密钥与配置安全管理:Vault / AWS Secrets Manager / .env 工程化使用|杜绝硬编码、运行时动态注入、多环境配置隔离全套落地

本文完整拆解三层密钥管理方案:本地开发轻量化.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}

日志匹配内容统一替换为 ******