密钥管理与Vault实践
目录
概述
密钥管理挑战
传统密钥管理问题
┌─────────────────────────────────────────────────────────────┐
│ ❌ 硬编码在代码中 │
│ const DB_PASSWORD = "admin123" │
│ │
│ ❌ 环境变量泄露 │
│ export DB_PASS=admin123 │
│ (在进程列表中可见) │
│ │
│ ❌ 配置文件明文存储 │
│ config.yaml: │
│ database: │
│ password: admin123 │
│ │
│ ❌ 共享密钥,难以追踪 │
│ 多个应用共用同一个数据库密码 │
│ │
│ ❌ 密钥轮转困难 │
│ 需要手动更新所有使用方 │
└─────────────────────────────────────────────────────────────┘
现代密钥管理方案
┌─────────────────────────────────────────────────────────────┐
│ ✓ 集中式密钥管理 │
│ ┌──────────────────────────────────────────┐ │
│ │ Vault / AWS Secrets Manager │ │
│ │ - 加密存储 │ │
│ │ - 访问控制 │ │
│ │ - 审计日志 │ │
│ └──────────────────────────────────────────┘ │
│ │
│ ✓ 动态密钥生成 │
│ 应用请求 -> Vault生成临时密钥 -> 自动过期 │
│ │
│ ✓ 加密即服务 │
│ 应用发送明文 -> Vault加密 -> 返回密文 │
│ │
│ ✓ 密钥版本管理 │
│ v1, v2, v3... 支持回滚 │
│ │
│ ✓ 自动轮转 │
│ 定期自动生成新密钥并通知应用 │
└─────────────────────────────────────────────────────────────┘Vault架构
┌──────────────────────────────────────────────────────────────┐
│ HashiCorp Vault Architecture │
├──────────────────────────────────────────────────────────────┤
│ │
│ 客户端 │
│ ┌──────────┬──────────┬──────────┬──────────┐ │
│ │ CLI │ API │ SDK │ Agent │ │
│ └────┬─────┴────┬─────┴────┬─────┴────┬─────┘ │
│ └──────────┴──────────┴──────────┘ │
│ │ HTTPS │
│ ┌─────────────────▼────────────────────────────────┐ │
│ │ Vault Server │ │
│ │ ┌────────────────────────────────────────────┐ │ │
│ │ │ HTTP/gRPC API Layer │ │ │
│ │ └──────────────────┬─────────────────────────┘ │ │
│ │ │ │ │
│ │ ┌──────────────────▼─────────────────────────┐ │ │
│ │ │ Core (核心引擎) │ │ │
│ │ │ ┌──────────────────────────────────────┐ │ │ │
│ │ │ │ 认证方法 (Auth Methods) │ │ │ │
│ │ │ │ ┌─────┬─────┬─────┬─────┬─────┐ │ │ │ │
│ │ │ │ │Token│LDAP │Kube │AWS │OIDC │ │ │ │ │
│ │ │ │ └─────┴─────┴─────┴─────┴─────┘ │ │ │ │
│ │ │ └──────────────────────────────────────┘ │ │ │
│ │ │ │ │ │
│ │ │ ┌──────────────────────────────────────┐ │ │ │
│ │ │ │ 密钥引擎 (Secrets Engines) │ │ │ │
│ │ │ │ ┌─────┬─────┬─────┬─────┬─────┐ │ │ │ │
│ │ │ │ │ KV │DB │AWS │PKI │SSH │ │ │ │ │
│ │ │ │ └─────┴─────┴─────┴─────┴─────┘ │ │ │ │
│ │ │ └──────────────────────────────────────┘ │ │ │
│ │ │ │ │ │
│ │ │ ┌──────────────────────────────────────┐ │ │ │
│ │ │ │ 策略引擎 (Policy Engine) │ │ │ │
│ │ │ │ - ACL策略 │ │ │ │
│ │ │ │ - 路径权限 │ │ │ │
│ │ │ │ - RBAC │ │ │ │
│ │ │ └──────────────────────────────────────┘ │ │ │
│ │ │ │ │ │
│ │ │ ┌──────────────────────────────────────┐ │ │ │
│ │ │ │ 审计设备 (Audit Devices) │ │ │ │
│ │ │ │ - File, Syslog, Socket │ │ │ │
│ │ │ └──────────────────────────────────────┘ │ │ │
│ │ └────────────────────────────────────────────┘ │ │
│ └───────────────────┬──────────────────────────────┘ │
│ │ │
│ ┌───────────────────▼──────────────────────────────┐ │
│ │ 存储后端 (Storage Backend) │ │
│ │ ┌────────┬────────┬────────┬────────┐ │ │
│ │ │Consul │etcd │S3 │File │ │ │
│ │ └────────┴────────┴────────┴────────┘ │ │
│ │ (加密存储) │ │
│ └───────────────────────────────────────────────────┘ │
└──────────────────────────────────────────────────────────────┘HashiCorp Vault完整教程
安装与初始化
bash
# 1. 安装Vault (Docker方式)
docker run -d \
--name vault \
--cap-add=IPC_LOCK \
-p 8200:8200 \
-e 'VAULT_DEV_ROOT_TOKEN_ID=myroot' \
-e 'VAULT_DEV_LISTEN_ADDRESS=0.0.0.0:8200' \
vault:latest
# 2. 安装Vault (二进制方式 - Linux)
wget https://releases.hashicorp.com/vault/1.15.0/vault_1.15.0_linux_amd64.zip
unzip vault_1.15.0_linux_amd64.zip
sudo mv vault /usr/local/bin/
vault --version
# 3. 生产环境配置文件
cat > /etc/vault/config.hcl <<EOF
ui = true
storage "consul" {
address = "127.0.0.1:8500"
path = "vault/"
}
listener "tcp" {
address = "0.0.0.0:8200"
tls_cert_file = "/etc/vault/tls/vault.crt"
tls_key_file = "/etc/vault/tls/vault.key"
}
api_addr = "https://vault.company.com:8200"
cluster_addr = "https://vault.company.com:8201"
# 启用审计
audit {
type = "file"
path = "/var/log/vault/audit.log"
}
# 启用遥测
telemetry {
prometheus_retention_time = "30s"
disable_hostname = true
}
EOF
# 4. 启动Vault服务器
vault server -config=/etc/vault/config.hcl
# 5. 初始化Vault (仅首次)
export VAULT_ADDR='http://127.0.0.1:8200'
vault operator init \
-key-shares=5 \
-key-threshold=3 \
-format=json > vault-init-output.json
# 保存输出:
# Unseal Key 1: xxx (保存到安全位置)
# Unseal Key 2: yyy
# Unseal Key 3: zzz
# Unseal Key 4: aaa
# Unseal Key 5: bbb
# Initial Root Token: root-token-here
# 6. 解封Vault (每次重启后需要)
vault operator unseal <unseal-key-1>
vault operator unseal <unseal-key-2>
vault operator unseal <unseal-key-3>
# 3次后解封成功
# 7. 登录
export VAULT_TOKEN='root-token-here'
vault login
# 8. 查看状态
vault statusKV密钥引擎配置
bash
# 1. 启用KV v2引擎
vault secrets enable -path=secret kv-v2
# 2. 写入密钥
vault kv put secret/database \
username="admin" \
password="super-secret-password" \
host="db.company.com" \
port="5432"
# 3. 读取密钥
vault kv get secret/database
vault kv get -field=password secret/database
# 4. 读取JSON格式
vault kv get -format=json secret/database | jq
# 5. 更新密钥 (创建新版本)
vault kv put secret/database \
username="admin" \
password="new-password" \
host="db.company.com" \
port="5432"
# 6. 查看历史版本
vault kv metadata get secret/database
# 7. 读取指定版本
vault kv get -version=1 secret/database
# 8. 删除最新版本 (软删除)
vault kv delete secret/database
# 9. 恢复删除的版本
vault kv undelete -versions=2 secret/database
# 10. 永久删除版本
vault kv destroy -versions=1 secret/database
# 11. 删除所有版本和元数据
vault kv metadata delete secret/database策略配置
bash
# 1. 创建策略文件
cat > app-policy.hcl <<EOF
# 读取数据库密钥
path "secret/data/database/*" {
capabilities = ["read"]
}
# 列出数据库密钥
path "secret/metadata/database/*" {
capabilities = ["list"]
}
# 读写应用配置
path "secret/data/app/config" {
capabilities = ["create", "read", "update"]
}
# 管理员完全权限
path "secret/*" {
capabilities = ["create", "read", "update", "delete", "list"]
}
# 生成数据库凭证
path "database/creds/readonly" {
capabilities = ["read"]
}
# 加密数据
path "transit/encrypt/orders" {
capabilities = ["update"]
}
# 解密数据
path "transit/decrypt/orders" {
capabilities = ["update"]
}
EOF
# 2. 写入策略
vault policy write app-policy app-policy.hcl
# 3. 查看策略
vault policy read app-policy
# 4. 列出所有策略
vault policy list
# 5. 删除策略
vault policy delete app-policy认证方法
AppRole认证
bash
# 1. 启用AppRole认证
vault auth enable approle
# 2. 创建角色
vault write auth/approle/role/web-app \
token_policies="app-policy" \
token_ttl=1h \
token_max_ttl=4h \
secret_id_ttl=24h
# 3. 获取RoleID
vault read auth/approle/role/web-app/role-id
# role_id: xxxxx
# 4. 生成SecretID
vault write -f auth/approle/role/web-app/secret-id
# secret_id: yyyyy
# 5. 使用AppRole登录
vault write auth/approle/login \
role_id="xxxxx" \
secret_id="yyyyy"
# 返回token
# 6. Python应用集成示例
cat > vault_client.py <<'EOF'
import hvac
import os
class VaultClient:
def __init__(self):
self.client = hvac.Client(url='http://localhost:8200')
self._authenticate()
def _authenticate(self):
"""使用AppRole认证"""
role_id = os.environ.get('VAULT_ROLE_ID')
secret_id = os.environ.get('VAULT_SECRET_ID')
response = self.client.auth.approle.login(
role_id=role_id,
secret_id=secret_id
)
self.client.token = response['auth']['client_token']
def get_secret(self, path):
"""读取密钥"""
secret = self.client.secrets.kv.v2.read_secret_version(
path=path
)
return secret['data']['data']
def put_secret(self, path, data):
"""写入密钥"""
self.client.secrets.kv.v2.create_or_update_secret(
path=path,
secret=data
)
# 使用示例
vault = VaultClient()
db_creds = vault.get_secret('database/prod')
print(f"Username: {db_creds['username']}")
print(f"Password: {db_creds['password']}")
EOFKubernetes认证
bash
# 1. 启用Kubernetes认证
vault auth enable kubernetes
# 2. 配置Kubernetes认证
vault write auth/kubernetes/config \
kubernetes_host="https://kubernetes.default.svc:443" \
kubernetes_ca_cert=@/var/run/secrets/kubernetes.io/serviceaccount/ca.crt \
token_reviewer_jwt=@/var/run/secrets/kubernetes.io/serviceaccount/token
# 3. 创建角色绑定
vault write auth/kubernetes/role/web-app \
bound_service_account_names=web-app \
bound_service_account_namespaces=production \
policies=app-policy \
ttl=1h
# 4. Kubernetes Pod中使用
cat > k8s-vault-example.yaml <<'EOF'
apiVersion: v1
kind: ServiceAccount
metadata:
name: web-app
namespace: production
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: web-app
namespace: production
spec:
replicas: 3
selector:
matchLabels:
app: web-app
template:
metadata:
labels:
app: web-app
annotations:
vault.hashicorp.com/agent-inject: "true"
vault.hashicorp.com/role: "web-app"
vault.hashicorp.com/agent-inject-secret-db: "secret/data/database/prod"
vault.hashicorp.com/agent-inject-template-db: |
{{- with secret "secret/data/database/prod" -}}
export DB_USER="{{ .Data.data.username }}"
export DB_PASS="{{ .Data.data.password }}"
export DB_HOST="{{ .Data.data.host }}"
{{- end }}
spec:
serviceAccountName: web-app
containers:
- name: app
image: myapp:latest
command: ["/bin/sh", "-c"]
args:
- source /vault/secrets/db && ./app
EOF动态密钥生成
数据库动态凭证
bash
# 1. 启用数据库密钥引擎
vault secrets enable database
# 2. 配置PostgreSQL连接
vault write database/config/postgresql \
plugin_name=postgresql-database-plugin \
allowed_roles="readonly,readwrite" \
connection_url="postgresql://{{username}}:{{password}}@postgres:5432/mydb?sslmode=disable" \
username="vaultadmin" \
password="vaultpass"
# 3. 创建只读角色
vault write database/roles/readonly \
db_name=postgresql \
creation_statements="
CREATE ROLE \"{{name}}\" WITH LOGIN PASSWORD '{{password}}' VALID UNTIL '{{expiration}}';
GRANT SELECT ON ALL TABLES IN SCHEMA public TO \"{{name}}\";
" \
default_ttl="1h" \
max_ttl="24h"
# 4. 创建读写角色
vault write database/roles/readwrite \
db_name=postgresql \
creation_statements="
CREATE ROLE \"{{name}}\" WITH LOGIN PASSWORD '{{password}}' VALID UNTIL '{{expiration}}';
GRANT SELECT, INSERT, UPDATE, DELETE ON ALL TABLES IN SCHEMA public TO \"{{name}}\";
" \
default_ttl="1h" \
max_ttl="24h"
# 5. 生成动态凭证
vault read database/creds/readonly
# Key Value
# --- -----
# lease_id database/creds/readonly/abc123
# lease_duration 1h
# username v-token-readonly-xyz
# password A1B2C3D4E5
# 6. 续租凭证
vault lease renew database/creds/readonly/abc123
# 7. 撤销凭证
vault lease revoke database/creds/readonly/abc123
# 8. 应用集成示例
cat > dynamic_db_client.py <<'EOF'
import hvac
import psycopg2
from contextlib import contextmanager
class DynamicDBClient:
def __init__(self, vault_client):
self.vault = vault_client
@contextmanager
def get_connection(self, role='readonly'):
"""获取数据库连接 (自动管理凭证生命周期)"""
# 生成动态凭证
creds = self.vault.client.read(f'database/creds/{role}')
username = creds['data']['username']
password = creds['data']['password']
lease_id = creds['lease_id']
# 创建连接
conn = psycopg2.connect(
host='postgres',
database='mydb',
user=username,
password=password
)
try:
yield conn
finally:
# 关闭连接
conn.close()
# 撤销凭证
self.vault.client.sys.revoke_lease(lease_id)
# 使用示例
vault = VaultClient()
db_client = DynamicDBClient(vault)
with db_client.get_connection('readonly') as conn:
cursor = conn.cursor()
cursor.execute("SELECT * FROM users LIMIT 10")
results = cursor.fetchall()
# 凭证自动撤销
EOFAWS动态凭证
bash
# 1. 启用AWS密钥引擎
vault secrets enable aws
# 2. 配置AWS根凭证
vault write aws/config/root \
access_key=AKIAIOSFODNN7EXAMPLE \
secret_key=wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY \
region=us-east-1
# 3. 创建角色 (IAM用户类型)
vault write aws/roles/s3-readonly \
credential_type=iam_user \
policy_document=-<<EOF
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": ["s3:GetObject", "s3:ListBucket"],
"Resource": ["arn:aws:s3:::mybucket/*"]
}
]
}
EOF
# 4. 创建角色 (STS AssumeRole类型)
vault write aws/roles/ec2-admin \
credential_type=assumed_role \
role_arns=arn:aws:iam::123456789012:role/EC2AdminRole \
default_sts_ttl=3600 \
max_sts_ttl=86400
# 5. 生成AWS凭证
vault read aws/creds/s3-readonly
# Key Value
# --- -----
# lease_id aws/creds/s3-readonly/abc123
# access_key AKIAIOSFODNN7EXAMPLE2
# secret_key secretkey123
# security_token <none>
# 6. 生成STS临时凭证
vault read aws/sts/ec2-admin
# 返回临时访问密钥和session token密钥轮转策略
自动密钥轮转
bash
# 1. 配置数据库根凭证轮转
vault write database/config/postgresql \
plugin_name=postgresql-database-plugin \
allowed_roles="*" \
connection_url="postgresql://{{username}}:{{password}}@postgres:5432/mydb" \
username="vaultadmin" \
password="initial-password" \
rotate=true
# 立即轮转根凭证
vault write -f database/rotate-root/postgresql
# 2. 配置自动轮转策略
cat > rotation-policy.hcl <<EOF
path "database/rotate-root/postgresql" {
schedule = "0 0 * * *" # 每天午夜轮转
}
EOF
# 3. KV密钥版本管理
vault kv put secret/api-key value="key-v1"
vault kv put secret/api-key value="key-v2" # 创建新版本
vault kv put secret/api-key value="key-v3"
# 配置最大版本数
vault kv metadata put -max-versions=5 secret/api-key
# 4. 密钥轮转通知
cat > rotate_notify.py <<'EOF'
"""
密钥轮转通知脚本
"""
import hvac
import smtplib
from email.mime.text import MIMEText
from datetime import datetime, timedelta
class SecretRotationMonitor:
def __init__(self, vault_client):
self.vault = vault_client
def check_expiring_secrets(self, days_threshold=7):
"""检查即将过期的密钥"""
expiring = []
# 检查所有动态密钥租约
leases = self.vault.client.sys.list_leases('database/creds')
for lease_id in leases['data']['keys']:
lease_info = self.vault.client.sys.read_lease(lease_id)
ttl = lease_info['data']['ttl']
if ttl < days_threshold * 86400: # 转换为秒
expiring.append({
'lease_id': lease_id,
'ttl_days': ttl / 86400,
'expires_at': datetime.now() + timedelta(seconds=ttl)
})
return expiring
def rotate_secret(self, path):
"""轮转密钥"""
# 读取当前密钥
current = self.vault.get_secret(path)
# 生成新密钥
new_value = self._generate_new_secret()
# 写入新版本
self.vault.put_secret(path, {'value': new_value})
# 记录轮转事件
self._log_rotation(path, current['value'], new_value)
return new_value
def _generate_new_secret(self):
"""生成新密钥"""
import secrets
return secrets.token_urlsafe(32)
def _log_rotation(self, path, old_value, new_value):
"""记录轮转日志"""
print(f"[{datetime.now()}] Rotated secret at {path}")
def send_notification(self, expiring_secrets):
"""发送通知"""
if not expiring_secrets:
return
message = "以下密钥即将过期:\n\n"
for secret in expiring_secrets:
message += f"- {secret['lease_id']}: {secret['ttl_days']:.1f} 天后过期\n"
self._send_email(
to='[email protected]',
subject='Vault密钥过期提醒',
body=message
)
def _send_email(self, to, subject, body):
"""发送邮件"""
msg = MIMEText(body)
msg['Subject'] = subject
msg['From'] = '[email protected]'
msg['To'] = to
# 发送邮件逻辑
pass
# 使用示例
vault = VaultClient()
monitor = SecretRotationMonitor(vault)
# 检查即将过期的密钥
expiring = monitor.check_expiring_secrets(days_threshold=7)
# 发送通知
if expiring:
monitor.send_notification(expiring)
# 轮转密钥
monitor.rotate_secret('secret/api-key')
EOFKMS集成
AWS KMS集成
bash
# 1. 配置Vault使用AWS KMS自动解封
cat > vault-kms.hcl <<EOF
seal "awskms" {
region = "us-east-1"
kms_key_id = "arn:aws:kms:us-east-1:123456789012:key/12345678-1234-1234-1234-123456789012"
}
storage "dynamodb" {
ha_enabled = "true"
region = "us-east-1"
table = "vault-storage"
}
listener "tcp" {
address = "0.0.0.0:8200"
tls_disable = 0
tls_cert_file = "/etc/vault/tls/vault.crt"
tls_key_file = "/etc/vault/tls/vault.key"
}
EOF
# 2. 启用Transit引擎 (加密即服务)
vault secrets enable transit
# 3. 创建加密密钥
vault write -f transit/keys/orders
# 4. 加密数据
vault write transit/encrypt/orders \
plaintext=$(echo "sensitive data" | base64)
# 返回: ciphertext: vault:v1:abc123...
# 5. 解密数据
vault write transit/decrypt/orders \
ciphertext="vault:v1:abc123..."
# 返回: plaintext (base64编码)
# 6. 轮转加密密钥
vault write -f transit/keys/orders/rotate
# 7. 重新包装数据 (使用新密钥)
vault write transit/rewrap/orders \
ciphertext="vault:v1:abc123..."
# 返回: ciphertext: vault:v2:xyz789...
# 8. Python应用集成
cat > transit_client.py <<'EOF'
import hvac
import base64
class TransitEncryption:
def __init__(self, vault_client, key_name='orders'):
self.vault = vault_client
self.key_name = key_name
def encrypt(self, plaintext):
"""加密数据"""
# Base64编码
plaintext_b64 = base64.b64encode(plaintext.encode()).decode()
# 加密
response = self.vault.client.secrets.transit.encrypt_data(
name=self.key_name,
plaintext=plaintext_b64
)
return response['data']['ciphertext']
def decrypt(self, ciphertext):
"""解密数据"""
# 解密
response = self.vault.client.secrets.transit.decrypt_data(
name=self.key_name,
ciphertext=ciphertext
)
# Base64解码
plaintext_b64 = response['data']['plaintext']
plaintext = base64.b64decode(plaintext_b64).decode()
return plaintext
def rotate_key(self):
"""轮转密钥"""
self.vault.client.secrets.transit.rotate_encryption_key(
name=self.key_name
)
def rewrap(self, ciphertext):
"""使用最新密钥重新加密"""
response = self.vault.client.secrets.transit.rewrap_data(
name=self.key_name,
ciphertext=ciphertext
)
return response['data']['ciphertext']
# 使用示例
vault = VaultClient()
transit = TransitEncryption(vault)
# 加密
ciphertext = transit.encrypt("credit card: 1234-5678-9012-3456")
print(f"Encrypted: {ciphertext}")
# 解密
plaintext = transit.decrypt(ciphertext)
print(f"Decrypted: {plaintext}")
# 轮转密钥
transit.rotate_key()
# 重新包装
new_ciphertext = transit.rewrap(ciphertext)
EOFGCP KMS集成
bash
# 1. 配置Vault使用GCP KMS
cat > vault-gcp-kms.hcl <<EOF
seal "gcpckms" {
project = "my-project"
region = "global"
key_ring = "vault-keyring"
crypto_key = "vault-key"
}
storage "gcs" {
bucket = "vault-storage-bucket"
ha_enabled = "true"
}
EOF
# 2. 设置GCP凭证
export GOOGLE_APPLICATION_CREDENTIALS="/path/to/credentials.json"
# 3. 启动Vault
vault server -config=vault-gcp-kms.hclAzure Key Vault集成
bash
# 1. 配置Vault使用Azure Key Vault
cat > vault-azure-kv.hcl <<EOF
seal "azurekeyvault" {
tenant_id = "00000000-0000-0000-0000-000000000000"
client_id = "00000000-0000-0000-0000-000000000000"
client_secret = "client-secret-here"
vault_name = "my-vault"
key_name = "vault-key"
}
storage "azure" {
accountName = "vaultstorageaccount"
accountKey = "storage-account-key"
container = "vault"
}
EOF实战案例
案例1: 微服务密钥管理
yaml
# Kubernetes部署with Vault Agent Injector
apiVersion: apps/v1
kind: Deployment
metadata:
name: order-service
spec:
replicas: 3
template:
metadata:
annotations:
# 启用Vault Agent注入
vault.hashicorp.com/agent-inject: "true"
vault.hashicorp.com/role: "order-service"
# 注入数据库凭证
vault.hashicorp.com/agent-inject-secret-db: "database/creds/order-db"
vault.hashicorp.com/agent-inject-template-db: |
{{- with secret "database/creds/order-db" -}}
DB_USER="{{ .Data.username }}"
DB_PASS="{{ .Data.password }}"
DB_HOST="postgres.production.svc.cluster.local"
{{- end }}
# 注入API密钥
vault.hashicorp.com/agent-inject-secret-api: "secret/data/order-service/api-keys"
vault.hashicorp.com/agent-inject-template-api: |
{{- with secret "secret/data/order-service/api-keys" -}}
STRIPE_API_KEY="{{ .Data.data.stripe_key }}"
SENDGRID_API_KEY="{{ .Data.data.sendgrid_key }}"
{{- end }}
# 注入加密密钥
vault.hashicorp.com/agent-inject-secret-encryption: "transit/keys/orders"
spec:
serviceAccountName: order-service
containers:
- name: app
image: order-service:v1.0.0
command: ["/bin/sh", "-c"]
args:
- |
# 加载Vault密钥
source /vault/secrets/db
source /vault/secrets/api
# 启动应用
exec ./order-service案例2: CI/CD密钥管理
yaml
# GitLab CI使用Vault
.vault_auth:
before_script:
- export VAULT_ADDR=https://vault.company.com
- export VAULT_TOKEN=$(vault write -field=token auth/jwt/login role=gitlab-ci jwt=$CI_JOB_JWT)
deploy:production:
extends: .vault_auth
script:
# 从Vault获取密钥
- vault kv get -field=aws_access_key secret/ci/aws > /tmp/aws_key
- vault kv get -field=aws_secret_key secret/ci/aws > /tmp/aws_secret
# 使用密钥部署
- aws configure set aws_access_key_id $(cat /tmp/aws_key)
- aws configure set aws_secret_access_key $(cat /tmp/aws_secret)
- aws eks update-kubeconfig --name production-cluster
# 部署应用
- kubectl apply -f k8s/
# 清理临时文件
- rm /tmp/aws_*
only:
- main总结
密钥管理最佳实践:
集中管理
- 使用Vault/KMS等专业工具
- 避免硬编码和明文存储
- 统一密钥访问入口
动态生成
- 数据库动态凭证
- 云平台临时凭证
- 自动过期和撤销
定期轮转
- 自动轮转策略
- 通知和监控
- 版本管理
最小权限
- 基于角色的访问控制
- 最小权限原则
- 定期审查权限
审计日志
- 记录所有访问
- 异常检测
- 合规报告
高可用
- 多节点集群
- 自动解封 (KMS)
- 备份恢复
核心工具:
- HashiCorp Vault: 最全面的密钥管理解决方案
- AWS Secrets Manager: AWS原生集成
- GCP Secret Manager: GCP原生集成
- Azure Key Vault: Azure原生集成
💬 讨论
使用 GitHub 账号登录后即可参与讨论