name: 秘密管理 description: 当设计秘密存储、轮换或凭证管理系统时使用。涵盖HashiCorp Vault模式、AWS Secrets Manager、Azure Key Vault、秘密轮换和零知识架构。 allowed-tools: Read, Glob, Grep
秘密管理
全面指南:管理秘密、凭证和敏感配置 - 从存储到轮换到访问控制。
何时使用此技能
- 设计秘密存储架构
- 实施秘密轮换
- 集成应用程序与秘密存储
- 管理API密钥、密码、证书
- 理解Vault、AWS Secrets Manager、Azure Key Vault
- 零知识和信封加密模式
秘密管理基础
什么是秘密?
秘密类型:
凭证:
├── 数据库密码
├── API密钥
├── OAuth客户端秘密
├── SSH私钥
└── 服务账户令牌
证书:
├── TLS证书和私钥
├── 代码签名证书
├── 客户端证书
└── CA证书
加密密钥:
├── 数据加密密钥 (DEK)
├── 密钥加密密钥 (KEK)
├── HMAC密钥
└── 签名密钥
敏感配置:
├── 连接字符串
├── 许可证密钥
├── 带有令牌的Webhook URL
└── 第三方凭证
秘密生命周期
秘密生命周期:
1. 生成
└── 使用足够熵创建
└── 使用加密随机性
└── 适当的密钥长度
2. 存储
└── 静态加密
└── 访问控制
└── 审计日志
3. 分发
└── 安全传输 (TLS)
└── 即时访问
└── 最小化副本
4. 使用
└── 内存保护
└── 最小化暴露窗口
└── 使用后清除
5. 轮换
└── 定期计划
└── 零停机轮换
└── 更新所有消费者
6. 撤销
└── 立即生效
└── 传播到所有系统
└── 审计跟踪
7. 销毁
└── 安全删除
└── 验证移除
└── 清除备份
架构模式
集中式秘密存储
集中式架构:
┌─────────────────────────────────────────────────┐
│ 秘密存储 │
│ ┌─────────────────────────────────────────┐ │
│ │ • 加密存储 │ │
│ │ • 访问控制 │ │
│ │ • 审计日志 │ │
│ │ • 轮换管理 │ │
│ │ • 高可用性 │ │
│ └─────────────────────────────────────────┘ │
└─────────────────────┬───────────────────────────┘
│
┌─────────────┼─────────────┐
│ │ │
┌────▼────┐ ┌────▼────┐ ┌────▼────┐
│ 应用 A │ │ 应用 B │ │ 应用 C │
│ │ │ │ │ │
│启动时获取│ │按需获取 │ │缓存获取 │
│秘密 │ │秘密 │ │秘密 │
└─────────┘ └─────────┘ └─────────┘
优点:
+ 单一真相源
+ 集中审计
+ 一致策略
+ 更容易轮换
挑战:
- 单点故障
- 网络依赖
- 秘密访问延迟
信封加密
信封加密:
┌─────────────────────────────────────────────────┐
│ 密钥层次结构 │
│ │
│ ┌─────────────┐ │
│ │ 主密钥 │ (永不离开KMS) │
│ │ (KEK) │ │
│ └──────┬──────┘ │
│ │ 加密 │
│ ▼ │
│ ┌─────────────┐ │
│ │ 数据密钥 │ (包装/加密) │
│ │ (DEK) │ │
│ └──────┬──────┘ │
│ │ 加密 │
│ ▼ │
│ ┌─────────────┐ │
│ │ 数据 │ (您的秘密/数据) │
│ │ │ │
│ └─────────────┘ │
└─────────────────────────────────────────────────┘
流程:
1. 本地生成DEK
2. 用DEK加密数据
3. 发送DEK到KMS用KEK包装
4. 存储:加密数据 + 包装的DEK
5. 解密:用KMS解包DEK,解密数据
优点:
- 主密钥永不暴露
- 可以轮换DEK而无需重新加密所有数据
- 分布式加密 (KMS不是瓶颈)
零知识架构
零知识秘密访问:
┌──────────────┐
│ 客户端 │
│ │
│ 拥有:从密码│
│ 衍生的秘密密钥│
└──────┬───────┘
│
┌──────────────────────▼───────────────────────┐
│ 服务器 │
│ │
│ 存储:加密的秘密 │
│ 无法解密 (没有密钥) │
│ │
│ 用户秘密 = 加密(数据, 用户衍生密钥) │
└───────────────────────────────────────────────┘
特性:
- 即使服务器被攻陷,也无法读取秘密
- 用户密码永不传输
- 客户端使用KDF衍生密钥
- 服务器只看到加密块
权衡:
+ 最大隐私
+ 服务器漏洞不会暴露秘密
- 如果用户忘记密码,无法恢复
- 无法审计存储内容
- 服务器无法验证秘密
HashiCorp Vault
Vault 架构
Vault 组件:
┌─────────────────────────────────────────────────────┐
│ Vault │
│ │
│ ┌──────────────────────────────────────────────┐ │
│ │ API 层 │ │
│ │ (所有操作的HTTP/HTTPS接口) │ │
│ └─────────────────────┬────────────────────────┘ │
│ │ │
│ ┌─────────────────────▼────────────────────────┐ │
│ │ 认证方法 │ │
│ │ 令牌 │ OIDC │ LDAP │ K8s │ AWS │ Azure │ │
│ └─────────────────────┬────────────────────────┘ │
│ │ │
│ ┌─────────────────────▼────────────────────────┐ │
│ │ 秘密引擎 │ │
│ │ KV │ 数据库 │ PKI │ 传输 │ AWS │ SSH │ │
│ └─────────────────────┬────────────────────────┘ │
│ │ │
│ ┌─────────────────────▼────────────────────────┐ │
│ │ 存储后端 │ │
│ │ Consul │ Raft │ S3 │ DynamoDB │ etcd │ │
│ └──────────────────────────────────────────────┘ │
└─────────────────────────────────────────────────────┘
Vault 秘密引擎
常见秘密引擎:
1. KV (键值)
- 静态秘密存储
- 版本支持
- 最简单引擎
2. 数据库
- 动态数据库凭证
- 自动轮换
- 短期凭证
vault write database/roles/my-role \
db_name=my-database \
creation_statements="CREATE USER..." \
default_ttl="1h" \
max_ttl="24h"
3. PKI
- 证书颁发机构
- 签发短期证书
- 自动续订
4. 传输
- 加密即服务
- 密钥管理
- 签名/验证操作
5. AWS/Azure/GCP
- 动态云凭证
- IAM 角色承担
- 临时访问
Vault 认证
认证方法选择:
Kubernetes:
- 最佳用于:Kubernetes中的Pod
- 身份:服务账户令牌
- 配置:绑定命名空间/SA
vault auth enable kubernetes
vault write auth/kubernetes/config \
kubernetes_host="https://kubernetes:443" \
kubernetes_ca_cert=@ca.crt
AppRole:
- 最佳用于:CI/CD,应用程序
- 身份:角色ID + 秘密ID
- 配置:绑定CIDR,元数据
vault auth enable approle
vault write auth/approle/role/my-app \
token_ttl=1h \
token_max_ttl=4h \
secret_id_num_uses=1
OIDC:
- 最佳用于:人类用户
- 身份:来自IdP的JWT
- 配置:OIDC提供者连接
云秘密管理器
AWS Secrets Manager
AWS Secrets Manager 功能:
能力:
├── 自动轮换 (基于Lambda)
├── 跨区域复制
├── IAM 集成
├── CloudTrail 审计
└── 资源策略
轮换流程:
┌─────────────────────────────────────────────────┐
│ 1. createSecret - 创建新秘密版本 │
│ 2. setSecret - 更新资源 (RDS等) │
│ 3. testSecret - 验证新秘密有效 │
│ 4. finishSecret - 标记轮换完成 │
└─────────────────────────────────────────────────┘
访问模式:
aws secretsmanager get-secret-value \
--secret-id my-secret \
--version-stage AWSCURRENT
SDK 集成:
client = boto3.client('secretsmanager')
response = client.get_secret_value(SecretId='my-secret')
secret = json.loads(response['SecretString'])
Azure Key Vault
Azure Key Vault 功能:
对象类型:
├── 秘密 - 通用键/值
├── 密钥 - 加密密钥 (HSM支持)
└── 证书 - X.509证书
访问控制:
- RBAC (推荐)
- 访问策略 (旧版)
- Azure资源的托管身份
软删除 + 清除保护:
- 删除的秘密在恢复期内保留
- 清除保护防止永久删除
- 适用于合规场景
集成:
// .NET 示例使用 DefaultAzureCredential
var client = new SecretClient(
new Uri("https://my-vault.vault.azure.net/"),
new DefaultAzureCredential());
KeyVaultSecret secret = await client.GetSecretAsync("my-secret");
GCP Secret Manager
GCP Secret Manager 功能:
能力:
├── 自动复制 (区域/全局)
├── IAM 集成
├── 审计日志
├── 秘密版本化
└── 过期支持
访问控制:
- roles/secretmanager.secretAccessor
- roles/secretmanager.admin
- IAM 条件用于细粒度访问
工作负载身份:
- GKE Pod使用服务账户
- 无需凭证文件
- 自动令牌刷新
访问模式:
gcloud secrets versions access latest --secret=my-secret
# Python
from google.cloud import secretmanager
client = secretmanager.SecretManagerServiceClient()
response = client.access_secret_version(name=secret_version_name)
secret = response.payload.data.decode('UTF-8')
秘密轮换
零停机轮换
双版本策略:
阶段 1: 创建新版本
┌─────────────────────────────────┐
│ 秘密存储 │
│ ├── 版本 1 (当前) ✓ │
│ └── 版本 2 (待定) 新建 │
└─────────────────────────────────┘
阶段 2: 更新消费者
┌─────────────────────────────────┐
│ 应用接受:版本 1 或 2 │
│ 资源更新到版本 2 │
└─────────────────────────────────┘
阶段 3: 验证新版本
┌─────────────────────────────────┐
│ 使用版本 2 测试连接 │
│ 监控错误 │
└─────────────────────────────────┘
阶段 4: 废弃旧版本
┌─────────────────────────────────┐
│ 秘密存储 │
│ ├── 版本 1 (已废弃) │
│ └── 版本 2 (当前) ✓ │
└─────────────────────────────────┘
阶段 5: 移除旧版本
┌─────────────────────────────────┐
│ 秘密存储 │
│ └── 版本 2 (当前) ✓ │
└─────────────────────────────────┘
数据库凭证轮换
数据库轮换模式:
方法 1: 双用户
┌─────────────────────────────────────────────────┐
│ 数据库有两个应用用户: │
│ - app_user_a (当前) │
│ - app_user_b (备用) │
│ │
│ 轮换: │
│ 1. 为 app_user_b 生成新密码 │
│ 2. 更新秘密指向 app_user_b │
│ 3. 应用获取新凭证 │
│ 4. 更改 app_user_a 密码 (现在备用) │
└─────────────────────────────────────────────────┘
方法 2: 动态凭证 (Vault)
┌─────────────────────────────────────────────────┐
│ 每个凭证请求创建新用户: │
│ - v-app-abc123-ttl-1h (1小时后过期) │
│ │
│ 优点: │
│ - 无需轮换 │
│ - 自动清理 │
│ - 按请求凭证 │
│ │
│ Vault 处理: │
│ - 创建用户 │
│ - 设置过期 │
│ - 撤销过期凭证 │
└─────────────────────────────────────────────────┘
应用程序集成
Sidecar 模式
Sidecar 秘密注入:
┌─────────────────────────────────────────────────┐
│ Pod │
│ ┌─────────────────┐ ┌─────────────────────┐ │
│ │ Vault 代理 │ │ 应用 │ │
│ │ (Sidecar) │ │ │ │
│ │ │ │ │ │
│ │ - 认证 │ │ 从 /vault/secrets/ │ │
│ │ - 获取 │──► 读取秘密 │ │
│ │ - 渲染 │ │ (共享卷) │ │
│ │ - 刷新 │ │ │ │
│ └─────────────────┘ └─────────────────────┘ │
│ │ │ │
│ ▼ │ │
│ [共享卷]◄────────────┘ │
│ /vault/secrets/ │
│ └── db-password │
│ └── api-key │
└─────────────────────────────────────────────────┘
CSI 驱动模式
Secrets Store CSI 驱动:
apiVersion: v1
kind: Pod
spec:
containers:
- name: app
volumeMounts:
- name: secrets
mountPath: "/mnt/secrets"
readOnly: true
volumes:
- name: secrets
csi:
driver: secrets-store.csi.k8s.io
readOnly: true
volumeAttributes:
secretProviderClass: "vault-database"
---
apiVersion: secrets-store.csi.x-k8s.io/v1
kind: SecretProviderClass
metadata:
name: vault-database
spec:
provider: vault
parameters:
vaultAddress: "https://vault:8200"
roleName: "db-role"
objects: |
- objectName: "db-password"
secretPath: "secret/data/db"
secretKey: "password"
最佳实践
安全最佳实践:
1. 永不存储秘密于:
❌ 源代码
❌ 环境变量 (日志中可见)
❌ 容器镜像
❌ Kubernetes ConfigMaps
❌ 纯文本文件
2. 访问控制:
□ 最小权限访问
□ 服务特定凭证
□ 尽可能时间限制访问
□ 定期访问审查
3. 审计和监控:
□ 记录所有秘密访问
□ 异常模式警报
□ 定期审计审查
□ 合规报告
4. 轮换:
□ 自动化所有轮换
□ 短期凭证生命周期
□ 测试轮换程序
□ 记录紧急轮换
5. 高可用性:
□ 秘密存储必须高可用
□ 缓存秘密以提高可用性
□ 优雅降级计划
□ 记录恢复程序
相关技能
zero-trust-architecture- 整体安全架构api-security- API 认证和授权mtls-service-mesh- 服务的证书管理container-orchestration- Kubernetes 秘密集成