secrets-vault-manager
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
ChineseSecrets Vault Manager
密钥管理器
Tier: POWERFUL
Category: Engineering
Domain: Security / Infrastructure / DevOps
层级:高级
类别:工程
领域:安全/基础设施/DevOps
Overview
概述
Production secret infrastructure management for teams running HashiCorp Vault, cloud-native secret stores, or hybrid architectures. This skill covers policy authoring, auth method configuration, automated rotation, dynamic secrets, audit logging, and incident response.
Distinct from env-secrets-manager which handles local file hygiene and leak detection. This skill operates at the infrastructure layer — Vault clusters, cloud KMS, certificate authorities, and CI/CD secret injection.
.env为运行HashiCorp Vault、云原生密钥存储或混合架构的团队提供生产级密钥基础设施管理。该技能涵盖策略编写、认证方法配置、自动轮换、动态密钥、审计日志和事件响应。
与env-secrets-manager不同,后者负责本地文件的合规性检查和泄漏检测。本技能作用于基础设施层——包括Vault集群、云KMS、证书颁发机构以及CI/CD密钥注入。
.envWhen to Use
使用场景
- Standing up a new Vault cluster or migrating to a managed secret store
- Designing auth methods for services, CI runners, and human operators
- Implementing automated credential rotation (database, API keys, certificates)
- Auditing secret access patterns for compliance (SOC 2, ISO 27001, HIPAA)
- Responding to a secret leak that requires mass revocation
- Integrating secrets into Kubernetes workloads or CI/CD pipelines
- 搭建新的Vault集群或迁移至托管密钥存储服务
- 为服务、CI运行器和操作人员设计认证方法
- 实现凭证自动轮换(数据库、API密钥、证书)
- 审计密钥访问模式以满足合规要求(SOC 2、ISO 27001、HIPAA)
- 应对需要批量吊销密钥的泄漏事件
- 将密钥集成到Kubernetes工作负载或CI/CD流水线中
HashiCorp Vault Patterns
HashiCorp Vault 实践模式
Architecture Decisions
架构决策
| Decision | Recommendation | Rationale |
|---|---|---|
| Deployment mode | HA with Raft storage | No external dependency, built-in leader election |
| Auto-unseal | Cloud KMS (AWS KMS / Azure Key Vault / GCP KMS) | Eliminates manual unseal, enables automated restarts |
| Namespaces | One per environment (dev/staging/prod) | Blast-radius isolation, independent policies |
| Audit devices | File + syslog (dual) | Vault refuses requests if all audit devices fail — dual prevents outages |
| 决策项 | 推荐方案 | 理由 |
|---|---|---|
| 部署模式 | 基于Raft存储的高可用架构 | 无外部依赖,内置主节点选举机制 |
| 自动解封 | 云KMS(AWS KMS / Azure Key Vault / GCP KMS) | 无需手动解封,支持自动重启 |
| 命名空间 | 每个环境(开发/预发布/生产)一个命名空间 | 隔离影响范围,策略独立管理 |
| 审计设备 | 文件+系统日志(双设备) | 若所有审计设备故障,Vault会拒绝请求——双设备可避免服务中断 |
Auth Methods
认证方法
AppRole — Machine-to-machine authentication for services and batch jobs.
hcl
undefinedAppRole — 用于服务和批处理作业的机器对机器认证。
hcl
undefinedEnable AppRole
Enable AppRole
path "auth/approle/*" {
capabilities = ["create", "read", "update", "delete", "list"]
}
path "auth/approle/*" {
capabilities = ["create", "read", "update", "delete", "list"]
}
Application-specific role
Application-specific role
vault write auth/approle/role/payment-service
token_ttl=1h
token_max_ttl=4h
secret_id_num_uses=1
secret_id_ttl=10m
token_policies="payment-service-read"
token_ttl=1h
token_max_ttl=4h
secret_id_num_uses=1
secret_id_ttl=10m
token_policies="payment-service-read"
**Kubernetes** — Pod-native authentication via service account tokens.
```hcl
vault write auth/kubernetes/role/api-server \
bound_service_account_names=api-server \
bound_service_account_namespaces=production \
policies=api-server-secrets \
ttl=1hOIDC — Human operator access via SSO provider (Okta, Azure AD, Google Workspace).
hcl
vault write auth/oidc/role/engineering \
bound_audiences="vault" \
allowed_redirect_uris="https://vault.example.com/ui/vault/auth/oidc/oidc/callback" \
user_claim="email" \
oidc_scopes="openid,profile,email" \
policies="engineering-read" \
ttl=8hvault write auth/approle/role/payment-service
token_ttl=1h
token_max_ttl=4h
secret_id_num_uses=1
secret_id_ttl=10m
token_policies="payment-service-read"
token_ttl=1h
token_max_ttl=4h
secret_id_num_uses=1
secret_id_ttl=10m
token_policies="payment-service-read"
**Kubernetes** — 通过服务账户令牌实现Pod原生认证。
```hcl
vault write auth/kubernetes/role/api-server \
bound_service_account_names=api-server \
bound_service_account_namespaces=production \
policies=api-server-secrets \
ttl=1hOIDC — 操作人员通过SSO提供商(Okta、Azure AD、Google Workspace)进行访问。
hcl
vault write auth/oidc/role/engineering \
bound_audiences="vault" \
allowed_redirect_uris="https://vault.example.com/ui/vault/auth/oidc/oidc/callback" \
user_claim="email" \
oidc_scopes="openid,profile,email" \
policies="engineering-read" \
ttl=8hSecret Engines
密钥引擎
| Engine | Use Case | TTL Strategy |
|---|---|---|
| KV v2 | Static secrets (API keys, config) | Versioned, manual rotation |
| Database | Dynamic DB credentials | 1h default, 24h max |
| PKI | TLS certificates | 90d leaf certs, 5y intermediate CA |
| Transit | Encryption-as-a-service | Key rotation every 90d |
| SSH | Signed SSH certificates | 30m for interactive, 8h for automation |
| 引擎 | 使用场景 | TTL策略 |
|---|---|---|
| KV v2 | 静态密钥(API密钥、配置) | 版本化,手动轮换 |
| Database | 动态数据库凭证 | 默认1小时,最长24小时 |
| PKI | TLS证书 | 叶子证书90天,中间CA证书5年 |
| Transit | 加密即服务 | 每90天轮换密钥 |
| SSH | 签名SSH证书 | 交互式会话30分钟,自动化任务8小时 |
Policy Design
策略设计
Follow least-privilege with path-based granularity:
hcl
undefined遵循最小权限原则,基于路径进行细粒度控制:
hcl
undefinedpayment-service-read policy
payment-service-read policy
path "secret/data/production/payment/*" {
capabilities = ["read"]
}
path "database/creds/payment-readonly" {
capabilities = ["read"]
}
path "secret/data/production/payment/*" {
capabilities = ["read"]
}
path "database/creds/payment-readonly" {
capabilities = ["read"]
}
Deny access to admin paths explicitly
Deny access to admin paths explicitly
path "sys/*" {
capabilities = ["deny"]
}
**Policy naming convention:** `{service}-{access-level}` (e.g., `payment-service-read`, `api-gateway-admin`).
---path "sys/*" {
capabilities = ["deny"]
}
**策略命名规范:** `{服务名}-{权限级别}`(例如:`payment-service-read`、`api-gateway-admin`)。
---Cloud Secret Store Integration
云密钥存储集成
Comparison Matrix
对比矩阵
| Feature | AWS Secrets Manager | Azure Key Vault | GCP Secret Manager |
|---|---|---|---|
| Rotation | Built-in Lambda | Custom logic via Functions | Cloud Functions |
| Versioning | Automatic | Manual or automatic | Automatic |
| Encryption | AWS KMS (default or CMK) | HSM-backed | Google-managed or CMEK |
| Access control | IAM policies + resource policy | RBAC + Access Policies | IAM bindings |
| Cross-region | Replication supported | Geo-redundant by default | Replication supported |
| Audit | CloudTrail | Azure Monitor + Diagnostic Logs | Cloud Audit Logs |
| Pricing model | Per-secret + per-API call | Per-operation + per-key | Per-secret version + per-access |
| 特性 | AWS Secrets Manager | Azure Key Vault | GCP Secret Manager |
|---|---|---|---|
| 轮换机制 | 内置Lambda | 通过Functions实现自定义逻辑 | Cloud Functions |
| 版本管理 | 自动 | 手动或自动 | 自动 |
| 加密方式 | AWS KMS(默认或自定义CMK) | HSM支持 | Google托管或CMEK |
| 访问控制 | IAM策略+资源策略 | RBAC+访问策略 | IAM绑定 |
| 跨区域支持 | 支持复制 | 默认地理冗余 | 支持复制 |
| 审计 | CloudTrail | Azure Monitor+诊断日志 | Cloud Audit Logs |
| 定价模式 | 按密钥数+API调用次数 | 按操作次数+密钥数 | 按密钥版本数+访问次数 |
When to Use Which
选型指南
- AWS Secrets Manager: RDS/Aurora credential rotation out of the box. Best when fully on AWS.
- Azure Key Vault: Certificate management strength. Required for Azure AD integrated workloads.
- GCP Secret Manager: Simplest API surface. Best for GKE-native workloads with Workload Identity.
- HashiCorp Vault: Multi-cloud, dynamic secrets, PKI, transit encryption. Best for complex or hybrid environments.
- AWS Secrets Manager:开箱即用的RDS/Aurora凭证轮换功能。适用于完全基于AWS的环境。
- Azure Key Vault:擅长证书管理。适用于集成Azure AD的工作负载。
- GCP Secret Manager:API接口最简洁。适用于使用Workload Identity的GKE原生工作负载。
- HashiCorp Vault:支持多云、动态密钥、PKI、传输加密。适用于复杂或混合环境。
SDK Access Patterns
SDK访问模式
Principle: Always fetch secrets at startup or via sidecar — never bake into images or config files.
python
undefined原则: 始终在启动时或通过sidecar获取密钥——绝不将密钥嵌入镜像或配置文件中。
python
undefinedAWS Secrets Manager pattern
AWS Secrets Manager pattern
import boto3, json
def get_secret(secret_name, region="us-east-1"):
client = boto3.client("secretsmanager", region_name=region)
response = client.get_secret_value(SecretId=secret_name)
return json.loads(response["SecretString"])
```pythonimport boto3, json
def get_secret(secret_name, region="us-east-1"):
client = boto3.client("secretsmanager", region_name=region)
response = client.get_secret_value(SecretId=secret_name)
return json.loads(response["SecretString"])
```pythonGCP Secret Manager pattern
GCP Secret Manager pattern
from google.cloud import secretmanager
def get_secret(project_id, secret_id, version="latest"):
client = secretmanager.SecretManagerServiceClient()
name = f"projects/{project_id}/secrets/{secret_id}/versions/{version}"
response = client.access_secret_version(request={"name": name})
return response.payload.data.decode("UTF-8")
```pythonfrom google.cloud import secretmanager
def get_secret(project_id, secret_id, version="latest"):
client = secretmanager.SecretManagerServiceClient()
name = f"projects/{project_id}/secrets/{secret_id}/versions/{version}"
response = client.access_secret_version(request={"name": name})
return response.payload.data.decode("UTF-8")
```pythonAzure Key Vault pattern
Azure Key Vault pattern
from azure.identity import DefaultAzureCredential
from azure.keyvault.secrets import SecretClient
def get_secret(vault_url, secret_name):
credential = DefaultAzureCredential()
client = SecretClient(vault_url=vault_url, credential=credential)
return client.get_secret(secret_name).value
---from azure.identity import DefaultAzureCredential
from azure.keyvault.secrets import SecretClient
def get_secret(vault_url, secret_name):
credential = DefaultAzureCredential()
client = SecretClient(vault_url=vault_url, credential=credential)
return client.get_secret(secret_name).value
---Secret Rotation Workflows
密钥轮换流程
Rotation Strategy by Secret Type
按密钥类型划分的轮换策略
| Secret Type | Rotation Frequency | Method | Downtime Risk |
|---|---|---|---|
| Database passwords | 30 days | Dual-account swap | Zero (A/B rotation) |
| API keys | 90 days | Generate new, deprecate old | Zero (overlap window) |
| TLS certificates | 60 days before expiry | ACME or Vault PKI | Zero (graceful reload) |
| SSH keys | 90 days | Vault-signed certificates | Zero (CA-based) |
| Service tokens | 24 hours | Dynamic generation | Zero (short-lived) |
| Encryption keys | 90 days | Key versioning (rewrap) | Zero (version coexistence) |
| 密钥类型 | 轮换频率 | 方法 | 停机风险 |
|---|---|---|---|
| 数据库密码 | 30天 | 双账户切换 | 零(A/B轮换) |
| API密钥 | 90天 | 生成新密钥,弃用旧密钥 | 零(重叠窗口期) |
| TLS证书 | 到期前60天 | ACME或Vault PKI | 零(平滑重载) |
| SSH密钥 | 90天 | Vault签名证书 | 零(基于CA) |
| 服务令牌 | 24小时 | 动态生成 | 零(短生命周期) |
| 加密密钥 | 90天 | 密钥版本化(重加密) | 零(版本共存) |
Database Credential Rotation (Dual-Account)
数据库凭证轮换(双账户模式)
- Two database accounts exist: and
app_user_aapp_user_b - Application currently uses
app_user_a - Rotation rotates password, updates secret store
app_user_b - Application switches to on next credential fetch
app_user_b - After grace period, password is rotated
app_user_a - Cycle repeats
- 存在两个数据库账户:和
app_user_aapp_user_b - 应用当前使用
app_user_a - 轮换操作更新的密码,并同步到密钥存储服务
app_user_b - 应用在下次获取凭证时切换为
app_user_b - 等待宽限期后,轮换的密码
app_user_a - 重复上述循环
API Key Rotation (Overlap Window)
API密钥轮换(重叠窗口期模式)
- Generate new API key with provider
- Store new key in secret store as , move old to
currentprevious - Deploy applications — they read
current - After all instances restarted (or TTL expired), revoke
previous - Monitoring confirms zero usage of old key before revocation
- 在服务商处生成新的API密钥
- 将新密钥存储到密钥服务中并标记为,旧密钥标记为
currentprevious - 部署应用,应用读取密钥
current - 待所有实例重启(或TTL过期)后,吊销密钥
previous - 监控确认旧密钥已无使用后再执行吊销操作
Dynamic Secrets
动态密钥
Dynamic secrets are generated on-demand with automatic expiration. Prefer dynamic secrets over static credentials wherever possible.
动态密钥是按需生成并自动过期的。只要可能,优先使用动态密钥而非静态凭证。
Database Dynamic Credentials (Vault)
数据库动态凭证(Vault)
hcl
undefinedhcl
undefinedConfigure database engine
Configure database engine
vault write database/config/postgres
plugin_name=postgresql-database-plugin
connection_url="postgresql://{{username}}:{{password}}@db.example.com:5432/app"
allowed_roles="app-readonly,app-readwrite"
username="vault_admin"
password="<admin-password>"
plugin_name=postgresql-database-plugin
connection_url="postgresql://{{username}}:{{password}}@db.example.com:5432/app"
allowed_roles="app-readonly,app-readwrite"
username="vault_admin"
password="<admin-password>"
vault write database/config/postgres
plugin_name=postgresql-database-plugin
connection_url="postgresql://{{username}}:{{password}}@db.example.com:5432/app"
allowed_roles="app-readonly,app-readwrite"
username="vault_admin"
password="<admin-password>"
plugin_name=postgresql-database-plugin
connection_url="postgresql://{{username}}:{{password}}@db.example.com:5432/app"
allowed_roles="app-readonly,app-readwrite"
username="vault_admin"
password="<admin-password>"
Create role with TTL
Create role with TTL
vault write database/roles/app-readonly
db_name=postgres
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
db_name=postgres
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
undefinedvault write database/roles/app-readonly
db_name=postgres
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
db_name=postgres
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
undefinedCloud IAM Dynamic Credentials
云IAM动态凭证
Vault can generate short-lived AWS IAM credentials, Azure service principal passwords, or GCP service account keys — eliminating long-lived cloud credentials entirely.
Vault可以生成短期的AWS IAM凭证、Azure服务主体密码或GCP服务账户密钥——彻底消除长期云凭证的风险。
SSH Certificate Authority
SSH证书颁发机构
Replace SSH key distribution with a Vault-signed certificate model:
- Vault acts as SSH CA
- Users/machines request signed certificates with short TTL (30 min)
- SSH servers trust the CA public key — no management
authorized_keys - Certificates expire automatically — no revocation needed for normal operations
使用Vault签名证书模型替代SSH密钥分发:
- Vault作为SSH CA
- 用户/机器请求短期TTL(30分钟)的签名证书
- SSH服务器信任CA公钥——无需管理
authorized_keys - 证书自动过期——正常操作下无需吊销
Audit Logging
审计日志
What to Log
日志记录内容
| Event | Priority | Retention |
|---|---|---|
| Secret read access | HIGH | 1 year minimum |
| Secret creation/update | HIGH | 1 year minimum |
| Auth method login | MEDIUM | 90 days |
| Policy changes | CRITICAL | 2 years (compliance) |
| Failed access attempts | CRITICAL | 1 year |
| Token creation/revocation | MEDIUM | 90 days |
| Seal/unseal operations | CRITICAL | Indefinite |
| 事件 | 优先级 | 保留期限 |
|---|---|---|
| 密钥读取访问 | 高 | 至少1年 |
| 密钥创建/更新 | 高 | 至少1年 |
| 认证方法登录 | 中 | 90天 |
| 策略变更 | 关键 | 2年(合规要求) |
| 访问尝试失败 | 关键 | 1年 |
| 令牌创建/吊销 | 中 | 90天 |
| 解封/密封操作 | 关键 | 永久 |
Anomaly Detection Signals
异常检测信号
- Secret accessed from new IP/CIDR range
- Access volume spike (>3x baseline for a path)
- Off-hours access for human auth methods
- Service accessing secrets outside its policy scope (denied requests)
- Multiple failed auth attempts from single source
- Token created with unusually long TTL
- 从新IP/CIDR范围访问密钥
- 访问量激增(超过某路径基线的3倍)
- 非工作时间使用人员认证方法访问
- 服务尝试访问其策略范围外的密钥(被拒绝的请求)
- 同一来源多次认证失败
- 创建了TTL异常长的令牌
Compliance Reporting
合规报告
Generate periodic reports covering:
- Access inventory — Which identities accessed which secrets, when
- Rotation compliance — Secrets overdue for rotation
- Policy drift — Policies modified since last review
- Orphaned secrets — Secrets with no recent access (>90 days)
Use to parse Vault or cloud audit logs for these signals.
audit_log_analyzer.py定期生成包含以下内容的报告:
- 访问清单 — 哪些身份在何时访问了哪些密钥
- 轮换合规性 — 逾期未轮换的密钥
- 策略漂移 — 自上次审核后修改的策略
- 孤立密钥 — 超过90天未被访问的密钥
使用解析Vault或云审计日志以识别这些信号。
audit_log_analyzer.pyEmergency Procedures
应急流程
Secret Leak Response (Immediate)
密钥泄漏应急响应(立即执行)
Time target: Contain within 15 minutes of detection.
- Identify scope — Which secret(s) leaked, where (repo, log, error message, third party)
- Revoke immediately — Rotate the compromised credential at the source (provider API, Vault, cloud SM)
- Invalidate tokens — Revoke all Vault tokens that accessed the leaked secret
- Audit blast radius — Query audit logs for usage of the compromised secret in the exposure window
- Notify stakeholders — Security team, affected service owners, compliance (if PII/regulated data)
- Post-mortem — Document root cause, update controls to prevent recurrence
时间目标: 检测到泄漏后15分钟内完成遏制。
- 确定范围 — 哪些密钥泄漏了,泄漏位置(代码库、日志、错误信息、第三方)
- 立即吊销 — 在源头轮换受损凭证(服务商API、Vault、云密钥存储)
- 失效令牌 — 吊销所有访问过泄漏密钥的Vault令牌
- 审计影响范围 — 查询审计日志,查看泄漏窗口内受损密钥的使用情况
- 通知相关方 — 安全团队、受影响服务的负责人、合规部门(若涉及PII或受监管数据)
- 事后复盘 — 记录根本原因,更新控制措施以防止再次发生
Vault Seal Operations
Vault密封操作
When to seal: Active security incident affecting Vault infrastructure, suspected key compromise.
Sealing stops all Vault operations. Use only as last resort.
Unseal procedure:
- Gather quorum of unseal key holders (Shamir threshold)
- Or confirm auto-unseal KMS key is accessible
- Unseal via or restart with auto-unseal
vault operator unseal - Verify audit devices reconnected
- Check active leases and token validity
See for complete playbooks.
references/emergency_procedures.md密封时机: Vault基础设施受到主动安全事件影响,或怀疑密钥被泄露。
密封会停止所有Vault操作。仅作为最后手段使用。
解封流程:
- 集齐足够数量的解封密钥持有者(Shamir阈值)
- 或确认自动解封KMS密钥可访问
- 通过命令解封,或启用自动解封重启
vault operator unseal - 验证审计设备已重新连接
- 检查活动租约和令牌有效性
完整的操作手册请查看。
references/emergency_procedures.mdCI/CD Integration
CI/CD集成
Vault Agent Sidecar (Kubernetes)
Vault Agent Sidecar(Kubernetes)
Vault Agent runs alongside application pods, handles authentication and secret rendering:
yaml
undefinedVault Agent与应用Pod并行运行,负责认证和密钥渲染:
yaml
undefinedPod annotation for Vault Agent Injector
Pod annotation for Vault Agent Injector
annotations:
vault.hashicorp.com/agent-inject: "true"
vault.hashicorp.com/role: "api-server"
vault.hashicorp.com/agent-inject-secret-db: "database/creds/app-readonly"
vault.hashicorp.com/agent-inject-template-db: |
{{- with secret "database/creds/app-readonly" -}}
postgresql://{{ .Data.username }}:{{ .Data.password }}@db:5432/app
{{- end }}
undefinedannotations:
vault.hashicorp.com/agent-inject: "true"
vault.hashicorp.com/role: "api-server"
vault.hashicorp.com/agent-inject-secret-db: "database/creds/app-readonly"
vault.hashicorp.com/agent-inject-template-db: |
{{- with secret "database/creds/app-readonly" -}}
postgresql://{{ .Data.username }}:{{ .Data.password }}@db:5432/app
{{- end }}
undefinedExternal Secrets Operator (Kubernetes)
External Secrets Operator(Kubernetes)
For teams preferring declarative GitOps over agent sidecars:
yaml
apiVersion: external-secrets.io/v1beta1
kind: ExternalSecret
metadata:
name: api-credentials
spec:
refreshInterval: 1h
secretStoreRef:
name: vault-backend
kind: ClusterSecretStore
target:
name: api-credentials
data:
- secretKey: api-key
remoteRef:
key: secret/data/production/api
property: key适用于偏好声明式GitOps而非Agent Sidecar的团队:
yaml
apiVersion: external-secrets.io/v1beta1
kind: ExternalSecret
metadata:
name: api-credentials
spec:
refreshInterval: 1h
secretStoreRef:
name: vault-backend
kind: ClusterSecretStore
target:
name: api-credentials
data:
- secretKey: api-key
remoteRef:
key: secret/data/production/api
property: keyGitHub Actions OIDC
GitHub Actions OIDC
Eliminate long-lived secrets in CI by using OIDC federation:
yaml
- name: Authenticate to Vault
uses: hashicorp/vault-action@v2
with:
url: https://vault.example.com
method: jwt
role: github-ci
jwtGithubAudience: https://vault.example.com
secrets: |
secret/data/ci/deploy api_key | DEPLOY_API_KEY ;
secret/data/ci/deploy db_password | DB_PASSWORD通过OIDC联合身份验证消除CI中的长期密钥:
yaml
- name: Authenticate to Vault
uses: hashicorp/vault-action@v2
with:
url: https://vault.example.com
method: jwt
role: github-ci
jwtGithubAudience: https://vault.example.com
secrets: |
secret/data/ci/deploy api_key | DEPLOY_API_KEY ;
secret/data/ci/deploy db_password | DB_PASSWORDAnti-Patterns
反模式
| Anti-Pattern | Risk | Correct Approach |
|---|---|---|
| Hardcoded secrets in source code | Leak via repo, logs, error output | Fetch from secret store at runtime |
| Long-lived static tokens (>30 days) | Stale credentials, no accountability | Dynamic secrets or short TTL + rotation |
| Shared service accounts | No audit trail per consumer | Per-service identity with unique credentials |
| No rotation policy | Compromised creds persist indefinitely | Automated rotation on schedule |
| Secrets in environment variables on CI | Visible in build logs, process table | Vault Agent or OIDC-based injection |
| Single unseal key holder | Bus factor of 1, recovery blocked | Shamir split (3-of-5) or auto-unseal |
| No audit device configured | Zero visibility into access | Dual audit devices (file + syslog) |
Wildcard policies ( | Over-permissioned, violates least privilege | Explicit path-based policies per service |
| 反模式 | 风险 | 正确做法 |
|---|---|---|
| 源代码中硬编码密钥 | 通过代码库、日志、错误输出泄漏 | 运行时从密钥存储服务获取 |
| 长期静态令牌(超过30天) | 凭证过期,无问责机制 | 使用动态密钥或短TTL+轮换 |
| 共享服务账户 | 无法追踪每个使用者的访问记录 | 为每个服务分配独立身份和唯一凭证 |
| 无轮换策略 | 受损凭证长期存在 | 按计划自动轮换 |
| CI环境变量中存储密钥 | 在构建日志、进程表中可见 | 使用Vault Agent或基于OIDC的注入 |
| 单个解封密钥持有者 | 单点故障,恢复受阻 | 使用Shamir拆分(3/5)或自动解封 |
| 未配置审计设备 | 完全无访问可见性 | 配置双审计设备(文件+系统日志) |
通配符策略( | 权限过度,违反最小权限原则 | 为每个服务配置基于路径的显式策略 |
Tools
工具
| Script | Purpose |
|---|---|
| Generate Vault policy and auth config from application requirements |
| Create rotation schedule from a secret inventory file |
| Analyze audit logs for anomalies and compliance gaps |
| 脚本 | 用途 |
|---|---|
| 根据应用需求生成Vault策略和认证配置 |
| 根据密钥清单文件创建轮换计划 |
| 分析审计日志以识别异常和合规缺口 |
Cross-References
交叉引用
- env-secrets-manager — Local file hygiene, leak detection, drift awareness
.env - senior-secops — Security operations, incident response, threat modeling
- ci-cd-pipeline-builder — Pipeline design where secrets are consumed
- docker-development — Container secret injection patterns
- helm-chart-builder — Kubernetes secret management in Helm charts
- env-secrets-manager — 本地文件合规性检查、泄漏检测、漂移感知
.env - senior-secops — 安全运维、事件响应、威胁建模
- ci-cd-pipeline-builder — 密钥消费场景下的流水线设计
- docker-development — 容器密钥注入模式
- helm-chart-builder — Helm图表中的Kubernetes密钥管理