本文完整拆解三层密钥管理方案:本地开发轻量化.env、AWS云原生托管密钥Secrets Manager、企业多云统一密钥平台Vault。围绕零硬编码敏感信息、运行时动态注入、开发/测试/生产环境强隔离三大核心目标,包含完整对比选型、工程规范、避坑指南,文末附带.env模板、Git钩子、AWS IAM策略、K8s CSI配置、Vault Policy/Agent全套可复制落地配置,适配初创单AWS云、中大型混合云/自建机房各类业务架构。

全套可直接复制落地配置模板(整合完整版,一次性复制)
一、本地开发 .env 安全全套配置
1. .env.example(允许提交Git)
# ==================== 数据库配置 ====================
DB_HOST=
DB_PORT=3306
DB_NAME=
DB_USER=
DB_PASSWORD=
# ==================== 第三方API密钥 ====================
WECHAT_APP_ID=
WECHAT_APP_SECRET=
ALIYUN_OSS_ACCESS_KEY=
ALIYUN_OSS_SECRET=
# ==================== 云厂商临时调试凭证 ====================
AWS_REGION=cn-north-1
AWS_ACCESS_KEY_ID=
AWS_SECRET_ACCESS_KEY=
# ==================== 通用非敏感业务配置 ====================
SERVER_PORT=8080
LOG_LEVEL=info
2. .env.dev 本地真实密钥(禁止提交Git)
DB_HOST=127.0.0.1
DB_PORT=3306
DB_NAME=dev_db
DB_USER=dev_user
DB_PASSWORD=Dev@Pass123456
WECHAT_APP_ID=wx_dev_123
WECHAT_APP_SECRET=sk-dev-wechat-xxxxxx
AWS_REGION=cn-north-1
AWS_ACCESS_KEY_ID=AKIADEVXXXXXX
AWS_SECRET_ACCESS_KEY=dev-secret-xxxxxx
3. .gitignore
# 真实密钥env文件
.env
.env.*
# 放行模板文件
!/.env.example
# IDE、日志、容器缓存
.idea/
.vscode/
logs/
*.log
docker-compose.override.yml
4. .githooks/pre-commit 防提交钩子
#!/bin/sh
if git diff --cached --name-only | grep -E '^\.env($|\.)'; then
echo "❌ 禁止提交 .env 密钥文件!仅允许提交 .env.example"
exit 1
fi
exit 0
启用命令:
git config core.hooksPath .githooks
chmod +x .githooks/pre-commit
5. Node.js 环境加载代码
if (process.env.NODE_ENV !== "prod") {
require("dotenv").config({ path: ".env.dev" });
}
const dbPwd = process.env.DB_PASSWORD;
6. .dockerignore
.env
.env.*
.git
.githooks
二、AWS Secrets Manager 生产全套配置
1. IAM Policy 环境隔离权限
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"secretsmanager:GetSecretValue",
"secretsmanager:DescribeSecret"
],
"Resource": [
"arn:aws:secretsmanager:cn-north-1:123456789012:secret:/prod/*",
"arn:aws:secretsmanager:cn-north-1:123456789012:secret:/test/*"
]
},
{
"Effect": "Deny",
"Action": "secretsmanager:GetSecretValue",
"Resource": "arn:aws:secretsmanager:cn-north-1:123456789012:secret:/dev/*"
}
]
}
2. SecretProviderClass CSI 内存挂载
apiVersion: secrets-store.csi.x-k8s.io/v1
kind: SecretProviderClass
metadata:
name: aws-secrets-prod
namespace: prod
spec:
provider: aws
parameters:
objects: |
- objectName: "/prod/mysql"
objectType: secretsmanager
jmesPath:
- path: DB_USER
objectAlias: db_user
- path: DB_PASSWORD
objectAlias: db_pwd
secretObjects:
- secretName: app-db-secret
type: Opaque
data:
- key: DB_USER
objectName: db_user
- key: DB_PASSWORD
objectName: db_pwd
3. Pod 挂载片段
volumes:
- name: secrets-store-inline
csi:
driver: secrets-store.csi.k8s.io
readOnly: true
volumeAttributes:
secretProviderClass: "aws-secrets-prod"
volumeMounts:
- name: secrets-store-inline
mountPath: "/mnt/secrets"
readOnly: true
三、HashiCorp Vault 企业级全套配置
1. prod-app-policy.hcl 权限策略
path "kv/prod/*" {
capabilities = ["read", "list"]
}
path "kv/dev/*" {
capabilities = ["deny"]
}
path "kv/test/*" {
capabilities = ["deny"]
}
path "database/creds/prod-mysql" {
capabilities = ["read"]
}
加载命令:
vault policy write prod-app prod-app-policy.hcl
2. K8s Auth 角色绑定命令
vault write auth/kubernetes/role/prod-app \
bound_service_account_names=app-sa \
bound_service_account_namespaces=prod \
policies=prod-app \
ttl=15m
3. agent-config.hcl Vault Agent 边车配置
auto_auth {
method "kubernetes" {
mount_path = "auth/kubernetes"
config = {
role = "prod-app"
}
}
sink "file" {
path = "/vault/.vault-token"
}
}
cache {
use_auto_auth_token = true
}
template {
source = "/vault/templates/db.tpl"
destination = "/mnt/secrets/db.json"
perms = 0440
command = "kill -SIGHUP $(pidof java || pidof node)"
}
4. templates/db.tpl 密钥模板
{
"DB_USER": {{ with secret "kv/prod/mysql" }}{{ .Data.data.DB_USER | toJSON }}{{ end }},
"DB_PASSWORD": {{ with secret "kv/prod/mysql" }}{{ .Data.data.DB_PASSWORD | toJSON }}{{ end }}
5. K8s Vault Agent Sidecar Pod 完整片段
spec:
containers:
- name: app
image: my-business:prod
volumeMounts:
- name: secret-mnt
mountPath: /mnt/secrets
- name: vault-agent
image: hashicorp/vault:1.16
volumeMounts:
- name: agent-config
mountPath: /vault/config
- name: agent-tpl
mountPath: /vault/templates
- name: secret-mnt
mountPath: /mnt/secrets
volumes:
- name: agent-config
configMap:
name: vault-agent-config
- name: agent-tpl
configMap:
name: vault-templates
- name: secret-mnt
emptyDir:
medium: Memory
6. MySQL动态短期凭证配置
# 配置数据库引擎
vault write database/config/prod-mysql \
plugin_name=mysql-database-plugin \
connection_url="{{username}}:{{password}}@tcp(mysql-prod:3306)/" \
allowed_roles="prod-app" \
username="root" \
password="Root@Pass123"
# 创建5分钟短期账号角色
vault write database/roles/prod-app \
db_name=prod-mysql \
creation_statements="CREATE USER '{{name}}'@'%' IDENTIFIED BY '{{password}}';GRANT SELECT,INSERT,UPDATE ON prod.* TO '{{name}}'@'%';" \
default_ttl=5m \
max_ttl=10m
# 应用获取临时账号
vault read database/creds/prod-app
四、CI/CD 安全配置 GitLab CI
build:
stage: build
script:
- rm -f .env .env.*
- vault kv get -format=json kv/prod/build > build-secret.json
- docker build -t app:$CI_COMMIT_SHA .
after_script:
- rm -rf build-secret.json
五、日志脱敏正则(全局拦截密钥打印)
DB_PASSWORD=.+
SECRET=.+
ACCESS_KEY=.+
APP_SECRET=.+
sk-[a-zA-Z0-9]+
AKIA[A-Z0-9]{16}
日志匹配内容统一替换为 ******