provisioning/docs/src/security/secrets-management-guide.md

2 lines
12 KiB
Markdown
Raw Normal View History

# Secrets Management System - Configuration Guide\n\n**Status**: Production Ready\n**Date**: 2025-11-19\n**Version**: 1.0.0\n\n## Overview\n\nThe provisioning system supports secure SSH key retrieval from multiple secret sources, eliminating hardcoded filesystem dependencies and enabling\nenterprise-grade security. SSH keys are retrieved from configured secret sources (SOPS, KMS, RustyVault) with automatic fallback to local-dev mode for\ndevelopment environments.\n\n## Secret Sources\n\n### 1. SOPS (Secrets Operations)\n\nAge-based encrypted secrets file with YAML structure.\n\n**Pros**:\n\n- ✅ Age encryption (modern, performant)\n- ✅ Easy to version in Git (encrypted)\n- ✅ No external services required\n- ✅ Simple YAML structure\n\n**Cons**:\n\n- ❌ Requires Age key management\n- ❌ No key rotation automation\n\n**Environment Variables**:\n\n```\nPROVISIONING_SECRET_SOURCE=sops\nPROVISIONING_SOPS_ENABLED=true\nPROVISIONING_SOPS_SECRETS_FILE=/path/to/secrets.enc.yaml\nPROVISIONING_SOPS_AGE_KEY_FILE=$HOME/.age/provisioning\n```\n\n**Secrets File Structure** (provisioning/secrets.enc.yaml):\n\n```\n# Encrypted with sops\nssh:\n web-01:\n ubuntu: /path/to/id_rsa\n root: /path/to/root_id_rsa\n db-01:\n postgres: /path/to/postgres_id_rsa\n```\n\n**Setup Instructions**:\n\n```\n# 1. Install sops and age\nbrew install sops age\n\n# 2. Generate Age key (store securely!)\nage-keygen -o $HOME/.age/provisioning\n\n# 3. Create encrypted secrets file\ncat > secrets.yaml << 'EOF'\nssh:\n web-01:\n ubuntu: ~/.ssh/provisioning_web01\n db-01:\n postgres: ~/.ssh/provisioning_db01\nEOF\n\n# 4. Encrypt with sops\nsops -e -i secrets.yaml\n\n# 5. Rename to enc version\nmv secrets.yaml provisioning/secrets.enc.yaml\n\n# 6. Configure environment\nexport PROVISIONING_SECRET_SOURCE=sops\nexport PROVISIONING_SOPS_SECRETS_FILE=$(pwd)/provisioning/secrets.enc.yaml\nexport PROVISIONING_SOPS_AGE_KEY_FILE=$HOME/.age/provisioning\n```\n\n### 2. KMS (Key Management Service)\n\nAWS KMS or compatible key management service.\n\n**Pros**:\n\n- ✅ Cloud-native security\n- ✅ Automatic key rotation\n- ✅ Audit logging built-in\n- ✅ High availability\n\n**Cons**:\n\n- ❌ Requires AWS account/credentials\n- ❌ API calls add latency (~50 ms)\n- ❌ Cost per API call\n\n**Environment Variables**:\n\n```\nPROVISIONING_SECRET_SOURCE=kms\nPROVISIONING_KMS_ENABLED=true\nPROVISIONING_KMS_REGION=us-east-1\n```\n\n**Secret Storage Pattern**:\n\n```\nprovisioning/ssh-keys/{hostname}/{username}\n```\n\n**Setup Instructions**:\n\n```\n# 1. Create KMS key (one-time)\naws kms create-key \\n --description "Provisioning SSH Keys" \\n --region us-east-1\n\n# 2. Store SSH keys in Secrets Manager\naws secretsmanager create-secret \\n --name provisioning/ssh-keys/web-01/ubuntu \\n --secret-string "$(cat ~/.ssh/provisioning_web01)" \\n --region us-east-1\n\n# 3. Configure environment\nexport PROVISIONING_SECRET_SOURCE=kms\nexport PROVISIONING_KMS_REGION=us-east-1\n\n# 4. Ensure AWS credentials available\nexport AWS_PROFILE=provisioning\n# or\nexport AWS_ACCESS_KEY_ID=...\nexport AWS_SECRET_ACCESS_KEY=...\n```\n\n### 3. RustyVault (Hashicorp Vault-Compatible)\n\nSelf-hosted or managed Vault instance for secrets.\n\n**Pros**:\n\n- ✅ Self-hosted option\n- ✅ Fine-grained access control\n- ✅ Multiple authentication methods\n- ✅ Easy key rotation\n\n**Cons**:\n\n- ❌ Requires Vault instance\n- ❌ More operational overhead\n- ❌ Network latency\n\n**Environment Variables**:\n\n```\nPROVISIONING_SECRET_SOURCE=vault\nPROVISIONING_VAULT_ENABLED=true\nPROVISIONING_VAULT_ADDRESS=http://localhost:8200\nPROVISIONING_VAULT_TOKEN=hvs.CAESIAoICQ...\n```\n\n**Secret Storage Pattern**:\n\n```\nGET /v1/secret/ssh-keys/{hostname}/{username}\n# Returns: {"key_content": "-----BEGIN OPENSSH PRIVATE KEY-----..."}\n```\n\n**Setup Instructions**:\n\n```\n# 1. Start Vault (if not already running)\ndocker run -p 8200:8200 \\n -e VAULT_DEV_ROOT_TOKEN_ID=provisioning \\n vault server -dev\n\n# 2. Create KV v2 mount (if not exists)\nvault secrets