Update configuration files, templates, and internal documentation for the provisioning repository system. Configuration Updates: - KMS configuration modernization - Plugin system settings - Service port mappings - Test cluster topologies - Installation configuration examples - VM configuration defaults - Cedar authorization policies Documentation Updates: - Library module documentation - Extension API guides - AI system documentation - Service management guides - Test environment setup - Plugin usage guides - Validator configuration documentation All changes are backward compatible.
701 lines
31 KiB
HTML
701 lines
31 KiB
HTML
<!DOCTYPE HTML>
|
|
<html lang="en" class="ayu sidebar-visible" dir="ltr">
|
|
<head>
|
|
<!-- Book generated using mdBook -->
|
|
<meta charset="UTF-8">
|
|
<title>KMS Simplification - Provisioning Platform Documentation</title>
|
|
|
|
|
|
<!-- Custom HTML head -->
|
|
|
|
<meta name="description" content="Complete documentation for the Provisioning Platform - Infrastructure automation with Nushell, KCL, and Rust">
|
|
<meta name="viewport" content="width=device-width, initial-scale=1">
|
|
<meta name="theme-color" content="#ffffff">
|
|
|
|
<link rel="icon" href="../favicon.svg">
|
|
<link rel="shortcut icon" href="../favicon.png">
|
|
<link rel="stylesheet" href="../css/variables.css">
|
|
<link rel="stylesheet" href="../css/general.css">
|
|
<link rel="stylesheet" href="../css/chrome.css">
|
|
<link rel="stylesheet" href="../css/print.css" media="print">
|
|
|
|
<!-- Fonts -->
|
|
<link rel="stylesheet" href="../FontAwesome/css/font-awesome.css">
|
|
<link rel="stylesheet" href="../fonts/fonts.css">
|
|
|
|
<!-- Highlight.js Stylesheets -->
|
|
<link rel="stylesheet" id="highlight-css" href="../highlight.css">
|
|
<link rel="stylesheet" id="tomorrow-night-css" href="../tomorrow-night.css">
|
|
<link rel="stylesheet" id="ayu-highlight-css" href="../ayu-highlight.css">
|
|
|
|
<!-- Custom theme stylesheets -->
|
|
|
|
|
|
<!-- Provide site root and default themes to javascript -->
|
|
<script>
|
|
const path_to_root = "../";
|
|
const default_light_theme = "ayu";
|
|
const default_dark_theme = "navy";
|
|
</script>
|
|
<!-- Start loading toc.js asap -->
|
|
<script src="../toc.js"></script>
|
|
</head>
|
|
<body>
|
|
<div id="mdbook-help-container">
|
|
<div id="mdbook-help-popup">
|
|
<h2 class="mdbook-help-title">Keyboard shortcuts</h2>
|
|
<div>
|
|
<p>Press <kbd>←</kbd> or <kbd>→</kbd> to navigate between chapters</p>
|
|
<p>Press <kbd>S</kbd> or <kbd>/</kbd> to search in the book</p>
|
|
<p>Press <kbd>?</kbd> to show this help</p>
|
|
<p>Press <kbd>Esc</kbd> to hide this help</p>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div id="body-container">
|
|
<!-- Work around some values being stored in localStorage wrapped in quotes -->
|
|
<script>
|
|
try {
|
|
let theme = localStorage.getItem('mdbook-theme');
|
|
let sidebar = localStorage.getItem('mdbook-sidebar');
|
|
|
|
if (theme.startsWith('"') && theme.endsWith('"')) {
|
|
localStorage.setItem('mdbook-theme', theme.slice(1, theme.length - 1));
|
|
}
|
|
|
|
if (sidebar.startsWith('"') && sidebar.endsWith('"')) {
|
|
localStorage.setItem('mdbook-sidebar', sidebar.slice(1, sidebar.length - 1));
|
|
}
|
|
} catch (e) { }
|
|
</script>
|
|
|
|
<!-- Set the theme before any content is loaded, prevents flash -->
|
|
<script>
|
|
const default_theme = window.matchMedia("(prefers-color-scheme: dark)").matches ? default_dark_theme : default_light_theme;
|
|
let theme;
|
|
try { theme = localStorage.getItem('mdbook-theme'); } catch(e) { }
|
|
if (theme === null || theme === undefined) { theme = default_theme; }
|
|
const html = document.documentElement;
|
|
html.classList.remove('ayu')
|
|
html.classList.add(theme);
|
|
html.classList.add("js");
|
|
</script>
|
|
|
|
<input type="checkbox" id="sidebar-toggle-anchor" class="hidden">
|
|
|
|
<!-- Hide / unhide sidebar before it is displayed -->
|
|
<script>
|
|
let sidebar = null;
|
|
const sidebar_toggle = document.getElementById("sidebar-toggle-anchor");
|
|
if (document.body.clientWidth >= 1080) {
|
|
try { sidebar = localStorage.getItem('mdbook-sidebar'); } catch(e) { }
|
|
sidebar = sidebar || 'visible';
|
|
} else {
|
|
sidebar = 'hidden';
|
|
}
|
|
sidebar_toggle.checked = sidebar === 'visible';
|
|
html.classList.remove('sidebar-visible');
|
|
html.classList.add("sidebar-" + sidebar);
|
|
</script>
|
|
|
|
<nav id="sidebar" class="sidebar" aria-label="Table of contents">
|
|
<!-- populated by js -->
|
|
<mdbook-sidebar-scrollbox class="sidebar-scrollbox"></mdbook-sidebar-scrollbox>
|
|
<noscript>
|
|
<iframe class="sidebar-iframe-outer" src="../toc.html"></iframe>
|
|
</noscript>
|
|
<div id="sidebar-resize-handle" class="sidebar-resize-handle">
|
|
<div class="sidebar-resize-indicator"></div>
|
|
</div>
|
|
</nav>
|
|
|
|
<div id="page-wrapper" class="page-wrapper">
|
|
|
|
<div class="page">
|
|
<div id="menu-bar-hover-placeholder"></div>
|
|
<div id="menu-bar" class="menu-bar sticky">
|
|
<div class="left-buttons">
|
|
<label id="sidebar-toggle" class="icon-button" for="sidebar-toggle-anchor" title="Toggle Table of Contents" aria-label="Toggle Table of Contents" aria-controls="sidebar">
|
|
<i class="fa fa-bars"></i>
|
|
</label>
|
|
<button id="theme-toggle" class="icon-button" type="button" title="Change theme" aria-label="Change theme" aria-haspopup="true" aria-expanded="false" aria-controls="theme-list">
|
|
<i class="fa fa-paint-brush"></i>
|
|
</button>
|
|
<ul id="theme-list" class="theme-popup" aria-label="Themes" role="menu">
|
|
<li role="none"><button role="menuitem" class="theme" id="default_theme">Auto</button></li>
|
|
<li role="none"><button role="menuitem" class="theme" id="light">Light</button></li>
|
|
<li role="none"><button role="menuitem" class="theme" id="rust">Rust</button></li>
|
|
<li role="none"><button role="menuitem" class="theme" id="coal">Coal</button></li>
|
|
<li role="none"><button role="menuitem" class="theme" id="navy">Navy</button></li>
|
|
<li role="none"><button role="menuitem" class="theme" id="ayu">Ayu</button></li>
|
|
</ul>
|
|
<button id="search-toggle" class="icon-button" type="button" title="Search (`/`)" aria-label="Toggle Searchbar" aria-expanded="false" aria-keyshortcuts="/ s" aria-controls="searchbar">
|
|
<i class="fa fa-search"></i>
|
|
</button>
|
|
</div>
|
|
|
|
<h1 class="menu-title">Provisioning Platform Documentation</h1>
|
|
|
|
<div class="right-buttons">
|
|
<a href="../print.html" title="Print this book" aria-label="Print this book">
|
|
<i id="print-button" class="fa fa-print"></i>
|
|
</a>
|
|
<a href="https://github.com/provisioning/provisioning-platform" title="Git repository" aria-label="Git repository">
|
|
<i id="git-repository-button" class="fa fa-github"></i>
|
|
</a>
|
|
<a href="https://github.com/provisioning/provisioning-platform/edit/main/provisioning/docs/src/migration/KMS_SIMPLIFICATION.md" title="Suggest an edit" aria-label="Suggest an edit">
|
|
<i id="git-edit-button" class="fa fa-edit"></i>
|
|
</a>
|
|
|
|
</div>
|
|
</div>
|
|
|
|
<div id="search-wrapper" class="hidden">
|
|
<form id="searchbar-outer" class="searchbar-outer">
|
|
<input type="search" id="searchbar" name="searchbar" placeholder="Search this book ..." aria-controls="searchresults-outer" aria-describedby="searchresults-header">
|
|
</form>
|
|
<div id="searchresults-outer" class="searchresults-outer hidden">
|
|
<div id="searchresults-header" class="searchresults-header"></div>
|
|
<ul id="searchresults">
|
|
</ul>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Apply ARIA attributes after the sidebar and the sidebar toggle button are added to the DOM -->
|
|
<script>
|
|
document.getElementById('sidebar-toggle').setAttribute('aria-expanded', sidebar === 'visible');
|
|
document.getElementById('sidebar').setAttribute('aria-hidden', sidebar !== 'visible');
|
|
Array.from(document.querySelectorAll('#sidebar a')).forEach(function(link) {
|
|
link.setAttribute('tabIndex', sidebar === 'visible' ? 0 : -1);
|
|
});
|
|
</script>
|
|
|
|
<div id="content" class="content">
|
|
<main>
|
|
<h1 id="kms-simplification-migration-guide"><a class="header" href="#kms-simplification-migration-guide">KMS Simplification Migration Guide</a></h1>
|
|
<p><strong>Version</strong>: 0.2.0
|
|
<strong>Date</strong>: 2025-10-08
|
|
<strong>Status</strong>: Active</p>
|
|
<h2 id="overview"><a class="header" href="#overview">Overview</a></h2>
|
|
<p>The KMS service has been simplified from supporting 4 backends (Vault, AWS KMS, Age, Cosmian) to supporting only 2 backends:</p>
|
|
<ul>
|
|
<li><strong>Age</strong>: Development and local testing</li>
|
|
<li><strong>Cosmian KMS</strong>: Production deployments</li>
|
|
</ul>
|
|
<p>This simplification reduces complexity, removes unnecessary cloud provider dependencies, and provides a clearer separation between development and production use cases.</p>
|
|
<h2 id="what-changed"><a class="header" href="#what-changed">What Changed</a></h2>
|
|
<h3 id="removed"><a class="header" href="#removed">Removed</a></h3>
|
|
<ul>
|
|
<li>❌ HashiCorp Vault backend (<code>src/vault/</code>)</li>
|
|
<li>❌ AWS KMS backend (<code>src/aws/</code>)</li>
|
|
<li>❌ AWS SDK dependencies (<code>aws-sdk-kms</code>, <code>aws-config</code>, <code>aws-credential-types</code>)</li>
|
|
<li>❌ Envelope encryption helpers (AWS-specific)</li>
|
|
<li>❌ Complex multi-backend configuration</li>
|
|
</ul>
|
|
<h3 id="added"><a class="header" href="#added">Added</a></h3>
|
|
<ul>
|
|
<li>✅ Age backend for development (<code>src/age/</code>)</li>
|
|
<li>✅ Cosmian KMS backend for production (<code>src/cosmian/</code>)</li>
|
|
<li>✅ Simplified configuration (<code>provisioning/config/kms.toml</code>)</li>
|
|
<li>✅ Clear dev/prod separation</li>
|
|
<li>✅ Better error messages</li>
|
|
</ul>
|
|
<h3 id="modified"><a class="header" href="#modified">Modified</a></h3>
|
|
<ul>
|
|
<li>🔄 <code>KmsBackendConfig</code> enum (now only Age and Cosmian)</li>
|
|
<li>🔄 <code>KmsError</code> enum (removed Vault/AWS-specific errors)</li>
|
|
<li>🔄 Service initialization logic</li>
|
|
<li>🔄 README and documentation</li>
|
|
<li>🔄 Cargo.toml dependencies</li>
|
|
</ul>
|
|
<h2 id="why-this-change"><a class="header" href="#why-this-change">Why This Change?</a></h2>
|
|
<h3 id="problems-with-previous-approach"><a class="header" href="#problems-with-previous-approach">Problems with Previous Approach</a></h3>
|
|
<ol>
|
|
<li><strong>Unnecessary Complexity</strong>: 4 backends for simple use cases</li>
|
|
<li><strong>Cloud Lock-in</strong>: AWS KMS dependency limited flexibility</li>
|
|
<li><strong>Operational Overhead</strong>: Vault requires server setup even for dev</li>
|
|
<li><strong>Dependency Bloat</strong>: AWS SDK adds significant compile time</li>
|
|
<li><strong>Unclear Use Cases</strong>: When to use which backend?</li>
|
|
</ol>
|
|
<h3 id="benefits-of-simplified-approach"><a class="header" href="#benefits-of-simplified-approach">Benefits of Simplified Approach</a></h3>
|
|
<ol>
|
|
<li><strong>Clear Separation</strong>: Age = dev, Cosmian = prod</li>
|
|
<li><strong>Faster Compilation</strong>: Removed AWS SDK (saves ~30s)</li>
|
|
<li><strong>Offline Development</strong>: Age works without network</li>
|
|
<li><strong>Enterprise Security</strong>: Cosmian provides confidential computing</li>
|
|
<li><strong>Easier Maintenance</strong>: 2 backends instead of 4</li>
|
|
</ol>
|
|
<h2 id="migration-steps"><a class="header" href="#migration-steps">Migration Steps</a></h2>
|
|
<h3 id="for-development-environments"><a class="header" href="#for-development-environments">For Development Environments</a></h3>
|
|
<p>If you were using <strong>Vault</strong> or <strong>AWS KMS</strong> for development:</p>
|
|
<h4 id="step-1-install-age"><a class="header" href="#step-1-install-age">Step 1: Install Age</a></h4>
|
|
<pre><code class="language-bash"># macOS
|
|
brew install age
|
|
|
|
# Ubuntu/Debian
|
|
apt install age
|
|
|
|
# From source
|
|
go install filippo.io/age/cmd/...@latest
|
|
</code></pre>
|
|
<h4 id="step-2-generate-age-keys"><a class="header" href="#step-2-generate-age-keys">Step 2: Generate Age Keys</a></h4>
|
|
<pre><code class="language-bash">mkdir -p ~/.config/provisioning/age
|
|
age-keygen -o ~/.config/provisioning/age/private_key.txt
|
|
age-keygen -y ~/.config/provisioning/age/private_key.txt > ~/.config/provisioning/age/public_key.txt
|
|
</code></pre>
|
|
<h4 id="step-3-update-configuration"><a class="header" href="#step-3-update-configuration">Step 3: Update Configuration</a></h4>
|
|
<p>Replace your old Vault/AWS config:</p>
|
|
<p><strong>Old (Vault)</strong>:</p>
|
|
<pre><code class="language-toml">[kms]
|
|
type = "vault"
|
|
address = "http://localhost:8200"
|
|
token = "${VAULT_TOKEN}"
|
|
mount_point = "transit"
|
|
</code></pre>
|
|
<p><strong>New (Age)</strong>:</p>
|
|
<pre><code class="language-toml">[kms]
|
|
environment = "dev"
|
|
|
|
[kms.age]
|
|
public_key_path = "~/.config/provisioning/age/public_key.txt"
|
|
private_key_path = "~/.config/provisioning/age/private_key.txt"
|
|
</code></pre>
|
|
<h4 id="step-4-re-encrypt-development-secrets"><a class="header" href="#step-4-re-encrypt-development-secrets">Step 4: Re-encrypt Development Secrets</a></h4>
|
|
<pre><code class="language-bash"># Export old secrets (if using Vault)
|
|
vault kv get -format=json secret/dev > dev-secrets.json
|
|
|
|
# Encrypt with Age
|
|
cat dev-secrets.json | age -r $(cat ~/.config/provisioning/age/public_key.txt) > dev-secrets.age
|
|
|
|
# Test decryption
|
|
age -d -i ~/.config/provisioning/age/private_key.txt dev-secrets.age
|
|
</code></pre>
|
|
<h3 id="for-production-environments"><a class="header" href="#for-production-environments">For Production Environments</a></h3>
|
|
<p>If you were using <strong>Vault</strong> or <strong>AWS KMS</strong> for production:</p>
|
|
<h4 id="step-1-set-up-cosmian-kms"><a class="header" href="#step-1-set-up-cosmian-kms">Step 1: Set Up Cosmian KMS</a></h4>
|
|
<p>Choose one of these options:</p>
|
|
<p><strong>Option A: Cosmian Cloud (Managed)</strong></p>
|
|
<pre><code class="language-bash"># Sign up at https://cosmian.com
|
|
# Get API credentials
|
|
export COSMIAN_KMS_URL=https://kms.cosmian.cloud
|
|
export COSMIAN_API_KEY=your-api-key
|
|
</code></pre>
|
|
<p><strong>Option B: Self-Hosted Cosmian KMS</strong></p>
|
|
<pre><code class="language-bash"># Deploy Cosmian KMS server
|
|
# See: https://docs.cosmian.com/kms/deployment/
|
|
|
|
# Configure endpoint
|
|
export COSMIAN_KMS_URL=https://kms.example.com
|
|
export COSMIAN_API_KEY=your-api-key
|
|
</code></pre>
|
|
<h4 id="step-2-create-master-key-in-cosmian"><a class="header" href="#step-2-create-master-key-in-cosmian">Step 2: Create Master Key in Cosmian</a></h4>
|
|
<pre><code class="language-bash"># Using Cosmian CLI
|
|
cosmian-kms create-key \
|
|
--algorithm AES \
|
|
--key-length 256 \
|
|
--key-id provisioning-master-key
|
|
|
|
# Or via API
|
|
curl -X POST $COSMIAN_KMS_URL/api/v1/keys \
|
|
-H "X-API-Key: $COSMIAN_API_KEY" \
|
|
-H "Content-Type: application/json" \
|
|
-d '{
|
|
"algorithm": "AES",
|
|
"keyLength": 256,
|
|
"keyId": "provisioning-master-key"
|
|
}'
|
|
</code></pre>
|
|
<h4 id="step-3-migrate-production-secrets"><a class="header" href="#step-3-migrate-production-secrets">Step 3: Migrate Production Secrets</a></h4>
|
|
<p><strong>From Vault to Cosmian</strong>:</p>
|
|
<pre><code class="language-bash"># Export secrets from Vault
|
|
vault kv get -format=json secret/prod > prod-secrets.json
|
|
|
|
# Import to Cosmian
|
|
# (Use temporary Age encryption for transfer)
|
|
cat prod-secrets.json | \
|
|
age -r $(cat ~/.config/provisioning/age/public_key.txt) | \
|
|
base64 > prod-secrets.enc
|
|
|
|
# On production server with Cosmian
|
|
cat prod-secrets.enc | \
|
|
base64 -d | \
|
|
age -d -i ~/.config/provisioning/age/private_key.txt | \
|
|
# Re-encrypt with Cosmian
|
|
curl -X POST $COSMIAN_KMS_URL/api/v1/encrypt \
|
|
-H "X-API-Key: $COSMIAN_API_KEY" \
|
|
-d @-
|
|
</code></pre>
|
|
<p><strong>From AWS KMS to Cosmian</strong>:</p>
|
|
<pre><code class="language-bash"># Decrypt with AWS KMS
|
|
aws kms decrypt \
|
|
--ciphertext-blob fileb://encrypted-data \
|
|
--output text \
|
|
--query Plaintext | \
|
|
base64 -d > plaintext-data
|
|
|
|
# Encrypt with Cosmian
|
|
curl -X POST $COSMIAN_KMS_URL/api/v1/encrypt \
|
|
-H "X-API-Key: $COSMIAN_API_KEY" \
|
|
-H "Content-Type: application/json" \
|
|
-d "{\"keyId\":\"provisioning-master-key\",\"data\":\"$(base64 plaintext-data)\"}"
|
|
</code></pre>
|
|
<h4 id="step-4-update-production-configuration"><a class="header" href="#step-4-update-production-configuration">Step 4: Update Production Configuration</a></h4>
|
|
<p><strong>Old (AWS KMS)</strong>:</p>
|
|
<pre><code class="language-toml">[kms]
|
|
type = "aws-kms"
|
|
region = "us-east-1"
|
|
key_id = "arn:aws:kms:us-east-1:123456789012:key/..."
|
|
</code></pre>
|
|
<p><strong>New (Cosmian)</strong>:</p>
|
|
<pre><code class="language-toml">[kms]
|
|
environment = "prod"
|
|
|
|
[kms.cosmian]
|
|
server_url = "${COSMIAN_KMS_URL}"
|
|
api_key = "${COSMIAN_API_KEY}"
|
|
default_key_id = "provisioning-master-key"
|
|
tls_verify = true
|
|
use_confidential_computing = false # Enable if using SGX/SEV
|
|
</code></pre>
|
|
<h4 id="step-5-test-production-setup"><a class="header" href="#step-5-test-production-setup">Step 5: Test Production Setup</a></h4>
|
|
<pre><code class="language-bash"># Set environment
|
|
export PROVISIONING_ENV=prod
|
|
export COSMIAN_KMS_URL=https://kms.example.com
|
|
export COSMIAN_API_KEY=your-api-key
|
|
|
|
# Start KMS service
|
|
cargo run --bin kms-service
|
|
|
|
# Test encryption
|
|
curl -X POST http://localhost:8082/api/v1/kms/encrypt \
|
|
-H "Content-Type: application/json" \
|
|
-d '{"plaintext":"SGVsbG8=","context":"env=prod"}'
|
|
|
|
# Test decryption
|
|
curl -X POST http://localhost:8082/api/v1/kms/decrypt \
|
|
-H "Content-Type: application/json" \
|
|
-d '{"ciphertext":"...","context":"env=prod"}'
|
|
</code></pre>
|
|
<h2 id="configuration-comparison"><a class="header" href="#configuration-comparison">Configuration Comparison</a></h2>
|
|
<h3 id="before-4-backends"><a class="header" href="#before-4-backends">Before (4 Backends)</a></h3>
|
|
<pre><code class="language-toml"># Development could use any backend
|
|
[kms]
|
|
type = "vault" # or "aws-kms"
|
|
address = "http://localhost:8200"
|
|
token = "${VAULT_TOKEN}"
|
|
|
|
# Production used Vault or AWS
|
|
[kms]
|
|
type = "aws-kms"
|
|
region = "us-east-1"
|
|
key_id = "arn:aws:kms:..."
|
|
</code></pre>
|
|
<h3 id="after-2-backends"><a class="header" href="#after-2-backends">After (2 Backends)</a></h3>
|
|
<pre><code class="language-toml"># Clear environment-based selection
|
|
[kms]
|
|
dev_backend = "age"
|
|
prod_backend = "cosmian"
|
|
environment = "${PROVISIONING_ENV:-dev}"
|
|
|
|
# Age for development
|
|
[kms.age]
|
|
public_key_path = "~/.config/provisioning/age/public_key.txt"
|
|
private_key_path = "~/.config/provisioning/age/private_key.txt"
|
|
|
|
# Cosmian for production
|
|
[kms.cosmian]
|
|
server_url = "${COSMIAN_KMS_URL}"
|
|
api_key = "${COSMIAN_API_KEY}"
|
|
default_key_id = "provisioning-master-key"
|
|
tls_verify = true
|
|
</code></pre>
|
|
<h2 id="breaking-changes"><a class="header" href="#breaking-changes">Breaking Changes</a></h2>
|
|
<h3 id="api-changes"><a class="header" href="#api-changes">API Changes</a></h3>
|
|
<h4 id="removed-functions"><a class="header" href="#removed-functions">Removed Functions</a></h4>
|
|
<ul>
|
|
<li><code>generate_data_key()</code> - Now only available with Cosmian backend</li>
|
|
<li><code>envelope_encrypt()</code> - AWS-specific, removed</li>
|
|
<li><code>envelope_decrypt()</code> - AWS-specific, removed</li>
|
|
<li><code>rotate_key()</code> - Now handled server-side by Cosmian</li>
|
|
</ul>
|
|
<h4 id="changed-error-types"><a class="header" href="#changed-error-types">Changed Error Types</a></h4>
|
|
<p><strong>Before</strong>:</p>
|
|
<pre><code class="language-rust">KmsError::VaultError(String)
|
|
KmsError::AwsKmsError(String)</code></pre>
|
|
<p><strong>After</strong>:</p>
|
|
<pre><code class="language-rust">KmsError::AgeError(String)
|
|
KmsError::CosmianError(String)</code></pre>
|
|
<h4 id="updated-configuration-enum"><a class="header" href="#updated-configuration-enum">Updated Configuration Enum</a></h4>
|
|
<p><strong>Before</strong>:</p>
|
|
<pre><code class="language-rust">enum KmsBackendConfig {
|
|
Vault { address, token, mount_point, ... },
|
|
AwsKms { region, key_id, assume_role },
|
|
}</code></pre>
|
|
<p><strong>After</strong>:</p>
|
|
<pre><code class="language-rust">enum KmsBackendConfig {
|
|
Age { public_key_path, private_key_path },
|
|
Cosmian { server_url, api_key, default_key_id, tls_verify },
|
|
}</code></pre>
|
|
<h2 id="code-migration"><a class="header" href="#code-migration">Code Migration</a></h2>
|
|
<h3 id="rust-code"><a class="header" href="#rust-code">Rust Code</a></h3>
|
|
<p><strong>Before (AWS KMS)</strong>:</p>
|
|
<pre><code class="language-rust">use kms_service::{KmsService, KmsBackendConfig};
|
|
|
|
let config = KmsBackendConfig::AwsKms {
|
|
region: "us-east-1".to_string(),
|
|
key_id: "arn:aws:kms:...".to_string(),
|
|
assume_role: None,
|
|
};
|
|
|
|
let kms = KmsService::new(config).await?;</code></pre>
|
|
<p><strong>After (Cosmian)</strong>:</p>
|
|
<pre><code class="language-rust">use kms_service::{KmsService, KmsBackendConfig};
|
|
|
|
let config = KmsBackendConfig::Cosmian {
|
|
server_url: env::var("COSMIAN_KMS_URL")?,
|
|
api_key: env::var("COSMIAN_API_KEY")?,
|
|
default_key_id: "provisioning-master-key".to_string(),
|
|
tls_verify: true,
|
|
};
|
|
|
|
let kms = KmsService::new(config).await?;</code></pre>
|
|
<h3 id="nushell-code"><a class="header" href="#nushell-code">Nushell Code</a></h3>
|
|
<p><strong>Before (Vault)</strong>:</p>
|
|
<pre><code class="language-nushell"># Set Vault environment
|
|
$env.VAULT_ADDR = "http://localhost:8200"
|
|
$env.VAULT_TOKEN = "root"
|
|
|
|
# Use KMS
|
|
kms encrypt "secret-data"
|
|
</code></pre>
|
|
<p><strong>After (Age for dev)</strong>:</p>
|
|
<pre><code class="language-nushell"># Set environment
|
|
$env.PROVISIONING_ENV = "dev"
|
|
|
|
# Age keys automatically loaded from config
|
|
kms encrypt "secret-data"
|
|
</code></pre>
|
|
<h2 id="rollback-plan"><a class="header" href="#rollback-plan">Rollback Plan</a></h2>
|
|
<p>If you need to rollback to Vault/AWS KMS:</p>
|
|
<pre><code class="language-bash"># Checkout previous version
|
|
git checkout tags/v0.1.0
|
|
|
|
# Rebuild with old dependencies
|
|
cd provisioning/platform/kms-service
|
|
cargo clean
|
|
cargo build --release
|
|
|
|
# Restore old configuration
|
|
cp provisioning/config/kms.toml.backup provisioning/config/kms.toml
|
|
</code></pre>
|
|
<h2 id="testing-the-migration"><a class="header" href="#testing-the-migration">Testing the Migration</a></h2>
|
|
<h3 id="development-testing"><a class="header" href="#development-testing">Development Testing</a></h3>
|
|
<pre><code class="language-bash"># 1. Generate Age keys
|
|
age-keygen -o /tmp/test_private.txt
|
|
age-keygen -y /tmp/test_private.txt > /tmp/test_public.txt
|
|
|
|
# 2. Test encryption
|
|
echo "test-data" | age -r $(cat /tmp/test_public.txt) > /tmp/encrypted
|
|
|
|
# 3. Test decryption
|
|
age -d -i /tmp/test_private.txt /tmp/encrypted
|
|
|
|
# 4. Start KMS service with test keys
|
|
export PROVISIONING_ENV=dev
|
|
# Update config to point to /tmp keys
|
|
cargo run --bin kms-service
|
|
</code></pre>
|
|
<h3 id="production-testing"><a class="header" href="#production-testing">Production Testing</a></h3>
|
|
<pre><code class="language-bash"># 1. Set up test Cosmian instance
|
|
export COSMIAN_KMS_URL=https://kms-staging.example.com
|
|
export COSMIAN_API_KEY=test-api-key
|
|
|
|
# 2. Create test key
|
|
cosmian-kms create-key --key-id test-key --algorithm AES --key-length 256
|
|
|
|
# 3. Test encryption
|
|
curl -X POST $COSMIAN_KMS_URL/api/v1/encrypt \
|
|
-H "X-API-Key: $COSMIAN_API_KEY" \
|
|
-d '{"keyId":"test-key","data":"dGVzdA=="}'
|
|
|
|
# 4. Start KMS service
|
|
export PROVISIONING_ENV=prod
|
|
cargo run --bin kms-service
|
|
</code></pre>
|
|
<h2 id="troubleshooting"><a class="header" href="#troubleshooting">Troubleshooting</a></h2>
|
|
<h3 id="age-keys-not-found"><a class="header" href="#age-keys-not-found">Age Keys Not Found</a></h3>
|
|
<pre><code class="language-bash"># Check keys exist
|
|
ls -la ~/.config/provisioning/age/
|
|
|
|
# Regenerate if missing
|
|
age-keygen -o ~/.config/provisioning/age/private_key.txt
|
|
age-keygen -y ~/.config/provisioning/age/private_key.txt > ~/.config/provisioning/age/public_key.txt
|
|
</code></pre>
|
|
<h3 id="cosmian-connection-failed"><a class="header" href="#cosmian-connection-failed">Cosmian Connection Failed</a></h3>
|
|
<pre><code class="language-bash"># Check network connectivity
|
|
curl -v $COSMIAN_KMS_URL/api/v1/health
|
|
|
|
# Verify API key
|
|
curl $COSMIAN_KMS_URL/api/v1/version \
|
|
-H "X-API-Key: $COSMIAN_API_KEY"
|
|
|
|
# Check TLS certificate
|
|
openssl s_client -connect kms.example.com:443
|
|
</code></pre>
|
|
<h3 id="compilation-errors"><a class="header" href="#compilation-errors">Compilation Errors</a></h3>
|
|
<pre><code class="language-bash"># Clean and rebuild
|
|
cd provisioning/platform/kms-service
|
|
cargo clean
|
|
cargo update
|
|
cargo build --release
|
|
</code></pre>
|
|
<h2 id="support"><a class="header" href="#support">Support</a></h2>
|
|
<ul>
|
|
<li><strong>Documentation</strong>: See <a href="../../provisioning/platform/kms-service/README.html">README.md</a></li>
|
|
<li><strong>Issues</strong>: Report on project issue tracker</li>
|
|
<li><strong>Cosmian Support</strong>: https://docs.cosmian.com/support/</li>
|
|
</ul>
|
|
<h2 id="timeline"><a class="header" href="#timeline">Timeline</a></h2>
|
|
<ul>
|
|
<li><strong>2025-10-08</strong>: Migration guide published</li>
|
|
<li><strong>2025-10-15</strong>: Deprecation notices for Vault/AWS</li>
|
|
<li><strong>2025-11-01</strong>: Old backends removed from codebase</li>
|
|
<li><strong>2025-11-15</strong>: Migration complete, old configs unsupported</li>
|
|
</ul>
|
|
<h2 id="faqs"><a class="header" href="#faqs">FAQs</a></h2>
|
|
<p><strong>Q: Can I still use Vault if I really need to?</strong>
|
|
A: No, Vault support has been removed. Use Age for dev or Cosmian for prod.</p>
|
|
<p><strong>Q: What about AWS KMS for existing deployments?</strong>
|
|
A: Migrate to Cosmian KMS. The API is similar, and migration tools are provided.</p>
|
|
<p><strong>Q: Is Age secure enough for production?</strong>
|
|
A: No. Age is designed for development only. Use Cosmian KMS for production.</p>
|
|
<p><strong>Q: Does Cosmian support confidential computing?</strong>
|
|
A: Yes, Cosmian KMS supports SGX and SEV for confidential computing workloads.</p>
|
|
<p><strong>Q: How much does Cosmian cost?</strong>
|
|
A: Cosmian offers both cloud and self-hosted options. Contact Cosmian for pricing.</p>
|
|
<p><strong>Q: Can I use my own KMS backend?</strong>
|
|
A: Not currently supported. Only Age and Cosmian are available.</p>
|
|
<h2 id="checklist"><a class="header" href="#checklist">Checklist</a></h2>
|
|
<p>Use this checklist to track your migration:</p>
|
|
<h3 id="development-migration"><a class="header" href="#development-migration">Development Migration</a></h3>
|
|
<ul>
|
|
<li><input disabled="" type="checkbox"/>
|
|
Install Age (<code>brew install age</code> or equivalent)</li>
|
|
<li><input disabled="" type="checkbox"/>
|
|
Generate Age keys (<code>age-keygen</code>)</li>
|
|
<li><input disabled="" type="checkbox"/>
|
|
Update <code>provisioning/config/kms.toml</code> to use Age backend</li>
|
|
<li><input disabled="" type="checkbox"/>
|
|
Export secrets from Vault/AWS (if applicable)</li>
|
|
<li><input disabled="" type="checkbox"/>
|
|
Re-encrypt secrets with Age</li>
|
|
<li><input disabled="" type="checkbox"/>
|
|
Test KMS service startup</li>
|
|
<li><input disabled="" type="checkbox"/>
|
|
Test encrypt/decrypt operations</li>
|
|
<li><input disabled="" type="checkbox"/>
|
|
Update CI/CD pipelines (if applicable)</li>
|
|
<li><input disabled="" type="checkbox"/>
|
|
Update documentation</li>
|
|
</ul>
|
|
<h3 id="production-migration"><a class="header" href="#production-migration">Production Migration</a></h3>
|
|
<ul>
|
|
<li><input disabled="" type="checkbox"/>
|
|
Set up Cosmian KMS server (cloud or self-hosted)</li>
|
|
<li><input disabled="" type="checkbox"/>
|
|
Create master key in Cosmian</li>
|
|
<li><input disabled="" type="checkbox"/>
|
|
Export production secrets from Vault/AWS</li>
|
|
<li><input disabled="" type="checkbox"/>
|
|
Re-encrypt secrets with Cosmian</li>
|
|
<li><input disabled="" type="checkbox"/>
|
|
Update <code>provisioning/config/kms.toml</code> to use Cosmian backend</li>
|
|
<li><input disabled="" type="checkbox"/>
|
|
Set environment variables (<code>COSMIAN_KMS_URL</code>, <code>COSMIAN_API_KEY</code>)</li>
|
|
<li><input disabled="" type="checkbox"/>
|
|
Test KMS service startup in staging</li>
|
|
<li><input disabled="" type="checkbox"/>
|
|
Test encrypt/decrypt operations in staging</li>
|
|
<li><input disabled="" type="checkbox"/>
|
|
Load test Cosmian integration</li>
|
|
<li><input disabled="" type="checkbox"/>
|
|
Update production deployment configs</li>
|
|
<li><input disabled="" type="checkbox"/>
|
|
Deploy to production</li>
|
|
<li><input disabled="" type="checkbox"/>
|
|
Verify all secrets accessible</li>
|
|
<li><input disabled="" type="checkbox"/>
|
|
Decommission old KMS infrastructure</li>
|
|
</ul>
|
|
<h2 id="conclusion"><a class="header" href="#conclusion">Conclusion</a></h2>
|
|
<p>The KMS simplification reduces complexity while providing better separation between development and production use cases. Age offers a fast, offline solution for development, while Cosmian KMS provides enterprise-grade security for production deployments.</p>
|
|
<p>For questions or issues, please refer to the documentation or open an issue.</p>
|
|
|
|
</main>
|
|
|
|
<nav class="nav-wrapper" aria-label="Page navigation">
|
|
<!-- Mobile navigation buttons -->
|
|
<a rel="prev" href="../migration/index.html" class="mobile-nav-chapters previous" title="Previous chapter" aria-label="Previous chapter" aria-keyshortcuts="Left">
|
|
<i class="fa fa-angle-left"></i>
|
|
</a>
|
|
|
|
<a rel="next prefetch" href="../TRY_CATCH_MIGRATION.html" class="mobile-nav-chapters next" title="Next chapter" aria-label="Next chapter" aria-keyshortcuts="Right">
|
|
<i class="fa fa-angle-right"></i>
|
|
</a>
|
|
|
|
<div style="clear: both"></div>
|
|
</nav>
|
|
</div>
|
|
</div>
|
|
|
|
<nav class="nav-wide-wrapper" aria-label="Page navigation">
|
|
<a rel="prev" href="../migration/index.html" class="nav-chapters previous" title="Previous chapter" aria-label="Previous chapter" aria-keyshortcuts="Left">
|
|
<i class="fa fa-angle-left"></i>
|
|
</a>
|
|
|
|
<a rel="next prefetch" href="../TRY_CATCH_MIGRATION.html" class="nav-chapters next" title="Next chapter" aria-label="Next chapter" aria-keyshortcuts="Right">
|
|
<i class="fa fa-angle-right"></i>
|
|
</a>
|
|
</nav>
|
|
|
|
</div>
|
|
|
|
<!-- Livereload script (if served using the cli tool) -->
|
|
<script>
|
|
const wsProtocol = location.protocol === 'https:' ? 'wss:' : 'ws:';
|
|
const wsAddress = wsProtocol + "//" + location.host + "/" + "__livereload";
|
|
const socket = new WebSocket(wsAddress);
|
|
socket.onmessage = function (event) {
|
|
if (event.data === "reload") {
|
|
socket.close();
|
|
location.reload();
|
|
}
|
|
};
|
|
|
|
window.onbeforeunload = function() {
|
|
socket.close();
|
|
}
|
|
</script>
|
|
|
|
|
|
|
|
<script>
|
|
window.playground_copyable = true;
|
|
</script>
|
|
|
|
|
|
<script src="../elasticlunr.min.js"></script>
|
|
<script src="../mark.min.js"></script>
|
|
<script src="../searcher.js"></script>
|
|
|
|
<script src="../clipboard.min.js"></script>
|
|
<script src="../highlight.js"></script>
|
|
<script src="../book.js"></script>
|
|
|
|
<!-- Custom JS scripts -->
|
|
|
|
|
|
</div>
|
|
</body>
|
|
</html>
|