关于 implementing-secrets-management-with-vault
这是一份面向平台和 DevOps 团队的 HashiCorp Vault 密钥管理实施指南,介绍动态凭据、Kubernetes 工作负载接入、加密与审计策略的配置。
主要功能
- 01部署高可用 Vault
- 02配置人员与机器身份验证
- 03生成带过期时间的动态凭据
- 04向 Kubernetes 工作负载提供密钥
- 05使用 Transit 加密并管理 PKI
- 06设置最小权限策略与审计
适用场景
- 01替换 CI/CD 中的硬编码凭据
- 02为数据库生成短期访问凭据
- 03向 Kubernetes Pod 提供密钥文件
- 04集中审计密钥访问与管理操作
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ mukul975/ anthropic-cybersecurity-skills --skill implementing-secrets-management-with-vault安装后在 Claude Code 中输入/implementing-secrets-management-with-vault确认已加载。
包含的文件
除 SKILL.md 外,安装时一起下载的参考资料和脚本。
LICENSEreferences/api-reference.mdscripts/agent.py详细介绍
使用 Vault 实现密钥管理
适用场景
- 当应用将数据库密码、API 密钥或证书存储在环境变量或配置文件中时
- 当从静态长期凭证迁移到动态短期密钥时
- 当 Kubernetes 工作负载需要安全访问数据库凭证或云服务商 API 时
- 当合规要求强制实施带审计日志的集中式凭证管理时
- 当 CI/CD 流水线包含硬编码密钥,构成供应链风险时
不要使用于仅使用 AWS 且 AWS Secrets Manager 已足够、无需多云需求的场景,也不适用于应用层加密逻辑(尽管 Vault Transit 可提供帮助),或身份联合(参见 managing-cloud-identity-with-okta)。
前提条件
- 以 HA 模式部署 HashiCorp Vault 服务(Consul 或 Raft 存储后端)
- 用于 Vault 监听器端点的 TLS 证书
- 用于命名空间、Sentinel 策略和复制的 Vault Enterprise 许可(可选)
- 带有 Vault Agent Injector 或 CSI provider 的 Kubernetes 集群,用于工作负载集成
工作流
第 1 步:以高可用模式部署 Vault
使用 Integrated Storage(Raft)部署 Vault,实现无需外部依赖的 HA。配置 TLS、审计日志,并使用云 KMS 进行自动解封。
# vault-config.hcl
storage "raft" {
path = "/opt/vault/data"
node_id = "vault-node-1"
retry_join {
leader_api_addr = "https://vault-node-2.internal:8200"
}
retry_join {
leader_api_addr = "https://vault-node-3.internal:8200"
}
}
listener "tcp" {
address = "0.0.0.0:8200"
tls_cert_file = "/opt/vault/tls/vault.crt"
tls_key_file = "/opt/vault/tls/vault.key"
}
seal "awskms" {
region = "us-east-1"
kms_key_id = "alias/vault-unseal-key"
}
api_addr = "https://vault-node-1.internal:8200"
cluster_addr = "https://vault-node-1.internal:8201"
telemetry {
prometheus_retention_time = "30s"
disable_hostname = true
}
# Initialize Vault
vault operator init -key-shares=5 -key-threshold=3
# Enable audit logging
vault audit enable file file_path=/var/log/vault/audit.log
# Enable syslog audit for SIEM integration
vault audit enable syslog tag="vault" facility="AUTH"
第 2 步:配置认证方法
为人工操作员、应用和 CI/CD 流水线启用认证后端。使用 AppRole 进行机器认证,使用 OIDC 进行人工访问。
# Enable OIDC auth for human users via Okta
vault auth enable oidc
vault write auth/oidc/config \
oidc_discovery_url="https://company.okta.com/oauth2/default" \
oidc_client_id="vault-client-id" \
oidc_client_secret="vault-client-secret" \
default_role="default"
# Enable AppRole for application authentication
vault auth enable approle
vault write auth/approle/role/web-app \
secret_id_ttl=10m \
token_num_uses=10 \
token_ttl=20m \
token_max_ttl=30m \
secret_id_num_uses=1 \
token_policies="web-app-policy"
# Enable Kubernetes auth for pod-based access
vault auth enable kubernetes
vault write auth/kubernetes/config \
kubernetes_host="https://kubernetes.default.svc:443" \
token_reviewer_jwt=@/var/run/secrets/kubernetes.io/serviceaccount/token \
kubernetes_ca_cert=@/var/run/secrets/kubernetes.io/serviceaccount/ca.crt
第 3 步:启用动态密钥引擎
配置数据库密钥引擎以按需生成短期凭证。每组凭证都有 TTL,并在过期时自动撤销。
# Enable database secrets engine for PostgreSQL
vault secrets enable database
vault write database/config/production-db \
plugin_name=postgresql-database-plugin \
allowed_roles="readonly,readwrite" \
connection_url="postgresql://{{username}}:{{password}}@db.internal:5432/production?sslmode=require" \
username="vault_admin" \
password="initial-password"
# Rotate the root credentials so Vault manages them exclusively
vault write -force database/rotate-root/production-db
# Create a readonly role with 1-hour TTL
vault write database/roles/readonly \
db_name=production-db \
creation_statements="CREATE ROLE \"{{name}}\" WITH LOGIN PASSWORD '{{password}}' VALID UNTIL '{{expiration}}'; GRANT SELECT ON ALL TABLES IN SCHEMA public TO \"{{name}}\";" \
revocation_statements="REVOKE ALL ON ALL TABLES IN SCHEMA public FROM \"{{name}}\"; DROP ROLE IF EXISTS \"{{name}}\";" \
default_ttl="1h" \
max_ttl="24h"
# Enable AWS secrets engine for dynamic IAM credentials
vault secrets enable aws
vault write aws/config/root \
access_key=AKIAEXAMPLE \
secret_key=secretkey \
region=us-east-1
vault write aws/roles/deploy-role \
credential_type=iam_user \
[email protected] \
default_sts_ttl=3600
第 4 步:与 Kubernetes 工作负载集成
使用 Vault Agent Injector 或 CSI Provider 将密钥传递给 Pod,而无需更改应用代码。密钥会以文件形式呈现在共享卷中。
# Kubernetes deployment with Vault Agent Injector annotations
apiVersion: apps/v1
kind: Deployment
metadata:
name: web-app
spec:
template:
metadata:
annotations:
vault.hashicorp.com/agent-inject: "true"
vault.hashicorp.com/role: "web-app"
vault.hashicorp.com/agent-inject-secret-db-creds: "database/creds/readonly"
vault.hashicorp.com/agent-inject-template-db-creds: |
{{- with secret "database/creds/readonly" -}}
export DB_USERNAME="{{ .Data.username }}"
export DB_PASSWORD="{{ .Data.password }}"
{{- end }}
spec:
serviceAccountName: web-app
containers:
- name: web-app
image: company/web-app:v2.1
command: ["/bin/sh", "-c", "source /vault/secrets/db-creds && ./start.sh"]
第 5 步:实现 Transit 加密和 PKI
使用 Transit 密钥引擎进行应用层加密,而无需在应用代码中管理密钥。部署 PKI 引擎以实现自动 TLS 证书管理。
# Enable Transit engine for encryption as a service
vault secrets enable transit
vault write -f transit/keys/payment-data type=aes256-gcm96
# Encrypt sensitive data
vault write transit/encrypt/payment-data \
plaintext=$(echo "card-number-4111-1111-1111-1111" | base64)
# Enable PKI for internal certificate management
vault secrets enable pki
vault secrets tune -max-lease-ttl=87600h pki
# Generate root CA
vault write pki/root/generate/internal \
common_name="Internal Root CA" \
ttl=87600h
# Configure intermediate CA for issuing certificates
vault secrets enable -path=pki_int pki
vault write pki_int/intermediate/generate/internal \
common_name="Internal Intermediate CA" \
ttl=43800h
# Create a role for issuing certificates
vault write pki_int/roles/internal-services \
allowed_domains="internal.company.com" \
allow_subdomains=true \
max_ttl=720h
第 6 步:建立策略和审计追踪
按照最小权限原则定义细粒度 ACL 策略。为所有密钥访问和管理操作启用全面的审计日志。
# web-app-policy.hcl
path "database/creds/readonly" {
capabilities = ["read"]
}
path "transit/encrypt/payment-data" {
capabilities = ["update"]
}
path "transit/decrypt/payment-data" {
capabilities = ["update"]
}
path "secret/data/web-app/*" {
capabilities = ["read", "list"]
}
# Deny access to admin paths
path "sys/*" {
capabilities = ["deny"]
}
# Apply the policy
vault policy write web-app-policy web-app-policy.hcl
# Verify audit log captures all operations
vault audit list -detailed
关键概念
| 术语 | 定义 |
|---|---|
| 动态密钥 | 按需生成并自动过期和撤销的凭证,消除长期静态凭证 |
| 密钥引擎 | 用于存储、生成或加密数据的 Vault 组件;包括 KV、database、AWS、PKI 和 Transit 引擎 |
| 自动解封 | 基于云 KMS 的机制,可在重启时自动解封 Vault 节点,无需手动输入密钥 |
| AppRole | 面向机器的认证方法,使用 Role ID 和 Secret ID 进行应用和 CI/CD 流水线访问 |
| Transit 引擎 | 加密即服务引擎,处理加密操作而不向应用暴露加密密钥 |
| 租约 | 带 TTL 的限时凭证,除非续期,否则 Vault 会在到期时自动撤销 |
| 命名空间 | Vault Enterprise 功能,通过独立的认证、密钥和策略管理提供租户隔离 |
| 响应包装 | 将密钥响应包装在一次性令牌中的技术,以防止投递过程中的中间人暴露 |
工具与系统
- HashiCorp Vault:核心密钥管理平台,提供动态密钥、加密和基于身份访问
- Vault Agent Injector:Kubernetes 变更 webhook,通过 sidecar 容器自动将 Vault 密钥注入 pod 卷
- Vault CSI Provider:Kubernetes CSI 驱动,无需 sidecar 容器即可将 Vault 密钥直接挂载到 pod 卷
- consul-template:模板渲染守护进程,监视 Vault 密钥并在密钥更改时重新渲染配置文件
- Vault Radar:密钥扫描工具,检测源代码、CI/CD 流水线和云配置中的硬编码凭据
常见场景
场景:从 CI/CD 流水线中消除硬编码数据库凭据
背景:一个 DevOps 团队在 GitHub Actions secrets 和 Jenkins 凭据存储中存储 PostgreSQL 凭据。相同的凭据在暂存和生产环境中共享,18 个月未轮换。
方案:
- 部署 Vault 并为 CI/CD 系统启用 AppRole 认证
- 配置数据库密钥引擎,为暂存(readwrite,2 小时 TTL)和生产(readonly,1 小时 TTL)设置单独的角色
- 为每个流水线阶段创建单独的 Vault 策略,限制对相应数据库角色的访问
- 更新 GitHub Actions 工作流,通过 AppRole 进行身份验证,并在每个作业开始时请求动态凭据
- 轮换静态 PostgreSQL 凭据,并将 root 访问权限完全交给 Vault
- 启用审计日志记录,用流水线作业元数据跟踪每次凭据请求
陷阱:迁移到 Vault 后未轮换原始静态凭据会导致旧凭据仍然有效。将 TTL 设置得太短会导致长时间运行的作业在部署中途凭据过期。
输出格式
Vault Secrets Management Audit Report
=======================================
Vault Cluster: vault.internal.company.com
Version: 1.18.1 Enterprise
HA Mode: Raft (3 nodes)
Seal Type: AWS KMS Auto-Unseal
Report Date: 2025-02-23
SECRET ENGINES:
database/ PostgreSQL dynamic creds Leases Active: 47
aws/ Dynamic IAM credentials Leases Active: 12
transit/ Encryption as a service Keys: 8
pki/ Root CA Certs Issued: 0
pki_int/ Intermediate CA Certs Issued: 234
secret/ KV v2 static secrets Versions: 1,892
AUTH METHODS:
oidc/ Okta SSO for humans Active Tokens: 23
approle/ CI/CD pipelines Active Tokens: 156
kubernetes/ Pod-based auth Active Tokens: 89
AUDIT FINDINGS:
[WARN] 3 AppRole secret_id_num_uses set to 0 (unlimited)
[WARN] 12 KV secrets not accessed in 90+ days (potential orphans)
[PASS] All dynamic secret TTLs under 24 hours
[PASS] Audit logging enabled on all nodes
[PASS] Root token revoked after initial setup
CREDENTIAL HYGIENE:
Static Secrets (KV): 234
Dynamic Secrets Active: 59
Average Lease TTL: 2.3 hours
Secrets Rotated This Month: 12,456