L’interface est localisée ; les présentations et documents des Skills sont traduits automatiquement par IA dans votre langue. Le code, les commandes, chemins et termes techniques restent en version originale, et le document de l’auteur fait foi.
Explorer les Skills
Déploiement et opérations · SKILL.md

implementing-secrets-management-with-vault

implementing-secrets-management-with-vault

本技能涵盖在云环境中部署 HashiCorp Vault 进行集中式密钥管理,包括为数据库和云提供商生成动态密钥、传输加密(Transit Encryption)、PKI 证书管理以及 Kubernetes 集成。通过实现短生命周期、自动轮换的密钥,解决应用代码和 CI/CD 流水线中硬编码凭据的问题。

Independent GitHub snapshot · Automated classification · Original documentation governs

Documentation de la Skill

GitHub

name: implementing-secrets-management-with-vault description: > 本技能涵盖在云环境中部署 HashiCorp Vault 进行集中式密钥管理,包括为数据库和云提供商生成动态密钥、传输加密(Transit Encryption)、PKI 证书管理以及 Kubernetes 集成。通过实现短生命周期、自动轮换的密钥,解决应用代码和 CI/CD 流水线中硬编码凭据的问题。 domain: cybersecurity subdomain: cloud-security tags: [hashicorp-vault, secrets-management, dynamic-secrets, credential-rotation, zero-trust] version: 1.0.0 author: mahipal license: Apache-2.0

使用 Vault 实施密钥管理

适用场景

  • 应用程序将数据库密码、API 密钥或证书存储在环境变量或配置文件中时
  • 从静态长期凭据迁移到动态短期密钥时
  • Kubernetes 工作负载需要安全访问数据库凭据或云提供商 API 时
  • 合规要求强制进行集中凭据管理并具备审计日志时
  • CI/CD 流水线中包含代表供应链风险(Supply Chain Attack)的硬编码密钥时

不适用于:纯 AWS 环境(AWS Secrets Manager 已足够且无多云需求)、应用层加密逻辑(尽管 Vault Transit 可辅助实现),或身份联合(Identity Federation)场景(参见 managing-cloud-identity-with-okta)。

前置条件

  • 以高可用(HA)模式部署的 HashiCorp Vault 服务器(Consul 或 Raft 存储后端)
  • 用于 Vault 监听端点的 TLS 证书
  • Vault Enterprise 许可证(用于命名空间、Sentinel 策略和复制,可选)
  • 已集成 Vault Agent Injector 或 CSI 提供程序的 Kubernetes 集群(用于工作负载集成)

工作流程

步骤 1:以高可用模式部署 Vault

使用集成存储(Raft)部署 Vault,无需外部依赖即可实现 HA。配置 TLS、审计日志以及基于云 KMS 的自动解封(Auto-Unseal)。

# 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
}
# 初始化 Vault
vault operator init -key-shares=5 -key-threshold=3

# 启用审计日志
vault audit enable file file_path=/var/log/vault/audit.log

# 启用 syslog 审计以集成 SIEM
vault audit enable syslog tag="vault" facility="AUTH"

步骤 2:配置认证方法

为人工操作员、应用程序和 CI/CD 流水线启用认证后端。使用 AppRole 进行机器认证,使用 OIDC 进行人工访问。

# 通过 Okta 为人工用户启用 OIDC 认证
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"

# 为应用程序认证启用 AppRole
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"

# 为 Pod 访问启用 Kubernetes 认证
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,到期后自动撤销。

# 为 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"

# 轮换根凭据,使 Vault 独占管理
vault write -force database/rotate-root/production-db

# 创建 TTL 为 1 小时的只读角色
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"

# 启用 AWS 密钥引擎以动态生成 IAM 凭据
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 \
  policy_document=@deploy-policy.json \
  default_sts_ttl=3600

步骤 4:与 Kubernetes 工作负载集成

使用 Vault Agent Injector 或 CSI Provider,无需修改应用代码即可将密钥传递给 Pod。密钥以文件形式渲染到共享卷中。

# 带 Vault Agent Injector 注解的 Kubernetes Deployment
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:实施传输加密和 PKI

使用 Transit 密钥引擎实现应用层加密即服务,无需在应用代码中管理密钥。部署 PKI 引擎进行 TLS 证书自动管理。

# 启用 Transit 引擎实现加密即服务
vault secrets enable transit
vault write -f transit/keys/payment-data type=aes256-gcm96

# 加密敏感数据
vault write transit/encrypt/payment-data \
  plaintext=$(echo "card-number-4111-1111-1111-1111" | base64)

# 启用 PKI 进行内部证书管理
vault secrets enable pki
vault secrets tune -max-lease-ttl=87600h pki

# 生成根 CA
vault write pki/root/generate/internal \
  common_name="Internal Root CA" \
  ttl=87600h

# 配置中间 CA 用于签发证书
vault secrets enable -path=pki_int pki
vault write pki_int/intermediate/generate/internal \
  common_name="Internal Intermediate CA" \
  ttl=43800h

# 创建证书签发角色
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"]
}

# 禁止访问管理路径
path "sys/*" {
  capabilities = ["deny"]
}
# 应用策略
vault policy write web-app-policy web-app-policy.hcl

# 验证审计日志捕获所有操作
vault audit list -detailed

核心概念

术语定义
动态密钥(Dynamic Secrets)按需生成并自动到期撤销的凭据,消除了长期静态凭据
密钥引擎(Secret Engine)存储、生成或加密数据的 Vault 组件;包括 KV、database、AWS、PKI 和 Transit 引擎
自动解封(Auto-Unseal)基于云 KMS 的机制,重启时自动解封 Vault 节点,无需手动输入密钥
AppRole面向机器的认证方法,使用 Role ID 和 Secret ID 供应用程序和 CI/CD 流水线访问
Transit 引擎(Transit Engine)加密即服务引擎,处理加密操作而不向应用程序暴露加密密钥
租约(Lease)带有 TTL 的时限凭据,到期后 Vault 自动撤销,除非续期
命名空间(Namespace)Vault Enterprise 功能,提供独立的认证、密钥和策略管理的租户隔离
响应封装(Response Wrapping)将密钥响应封装在一次性令牌中的技术,防止传输过程中的中间人攻击暴露

工具与系统

  • HashiCorp Vault:核心密钥管理平台,提供动态密钥、加密和基于身份的访问控制
  • Vault Agent Injector:Kubernetes 变更性 Webhook,通过边车容器自动将 Vault 密钥注入 Pod 卷
  • Vault CSI Provider:Kubernetes CSI 驱动程序,无需边车容器即可将 Vault 密钥直接挂载到 Pod 卷
  • consul-template:模板渲染守护进程,监视 Vault 密钥并在密钥变更时重新渲染配置文件
  • Vault Radar:密钥扫描工具,检测源代码、CI/CD 流水线和云配置中的硬编码凭据

常见场景

场景:消除 CI/CD 流水线中的硬编码数据库凭据

场景背景:DevOps 团队将 PostgreSQL 凭据存储在 GitHub Actions 密钥和 Jenkins 凭据存储中。同一组凭据在测试和生产环境中共用,18 个月未进行轮换。

方法:

  1. 部署 Vault 并为 CI/CD 系统启用 AppRole 认证
  2. 配置数据库密钥引擎,为测试(readwrite,TTL 2h)和生产(readonly,TTL 1h)分别设置角色
  3. 为每个流水线阶段创建独立的 Vault 策略,限制对相应数据库角色的访问
  4. 更新 GitHub Actions 工作流,在每个作业开始时通过 AppRole 认证并请求动态凭据
  5. 轮换静态 PostgreSQL 凭据,将根访问权限独占交给 Vault
  6. 启用审计日志,追踪每次凭据请求及流水线作业元数据

常见陷阱:Vault 迁移后未轮换原始静态凭据,导致旧凭据仍然有效。TTL 设置过短导致长时间运行的作业在部署过程中凭据过期。

输出格式

Vault 密钥管理审计报告
=======================================
Vault 集群: vault.internal.company.com
版本: 1.18.1 Enterprise
HA 模式: Raft (3 节点)
封印类型: AWS KMS 自动解封
报告日期: 2025-02-23

密钥引擎:
  database/         PostgreSQL 动态凭据   活跃租约: 47
  aws/              动态 IAM 凭据         活跃租约: 12
  transit/          加密即服务            密钥数: 8
  pki/              根 CA                已签发证书: 0
  pki_int/          中间 CA              已签发证书: 234
  secret/           KV v2 静态密钥        版本数: 1,892

认证方法:
  oidc/             Okta SSO(人工用户)  活跃令牌: 23
  approle/          CI/CD 流水线          活跃令牌: 156
  kubernetes/       基于 Pod 的认证       活跃令牌: 89

审计发现:
  [WARN] 3 个 AppRole 的 secret_id_num_uses 设为 0(无限制)
  [WARN] 12 个 KV 密钥超过 90 天未访问(潜在孤儿密钥)
  [PASS] 所有动态密钥 TTL 均低于 24 小时
  [PASS] 所有节点已启用审计日志
  [PASS] 初始设置后根令牌已撤销

凭据卫生:
  静态密钥 (KV): 234
  活跃动态密钥: 59
  平均租约 TTL: 2.3 小时
  本月已轮换密钥数: 12,456
Skills enregistrées