secrets-management

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

Secrets Management

密钥管理

Secure secrets management practices for CI/CD pipelines using Vault, AWS Secrets Manager, and other tools.
使用Vault、AWS Secrets Manager及其他工具为CI/CD流水线提供安全的密钥管理实践方案。

Purpose

目的

Implement secure secrets management in CI/CD pipelines without hardcoding sensitive information.
在CI/CD流水线中实现安全的密钥管理,避免硬编码敏感信息。

When to Use

适用场景

  • Store API keys and credentials
  • Manage database passwords
  • Handle TLS certificates
  • Rotate secrets automatically
  • Implement least-privilege access
  • 存储API密钥和凭证
  • 管理数据库密码
  • 处理TLS证书
  • 自动轮换密钥
  • 实现最小权限访问

Secrets Management Tools

密钥管理工具

HashiCorp Vault

HashiCorp Vault

  • Centralized secrets management
  • Dynamic secrets generation
  • Secret rotation
  • Audit logging
  • Fine-grained access control
  • 集中式密钥管理
  • 动态密钥生成
  • 密钥轮换
  • 审计日志
  • 细粒度访问控制

AWS Secrets Manager

AWS Secrets Manager

  • AWS-native solution
  • Automatic rotation
  • Integration with RDS
  • CloudFormation support
  • AWS原生解决方案
  • 自动轮换
  • 与RDS集成
  • 支持CloudFormation

Azure Key Vault

Azure Key Vault

  • Azure-native solution
  • HSM-backed keys
  • Certificate management
  • RBAC integration
  • Azure原生解决方案
  • HSM托管密钥
  • 证书管理
  • RBAC集成

Google Secret Manager

Google Secret Manager

  • GCP-native solution
  • Versioning
  • IAM integration
  • GCP原生解决方案
  • 版本控制
  • IAM集成

HashiCorp Vault Integration

HashiCorp Vault集成

Setup Vault

配置Vault

bash
undefined
bash
undefined

Start Vault dev server

启动Vault开发服务器

vault server -dev
vault server -dev

Set environment

设置环境变量

export VAULT_ADDR='http://127.0.0.1:8200' export VAULT_TOKEN='root'
export VAULT_ADDR='http://127.0.0.1:8200' export VAULT_TOKEN='root'

Enable secrets engine

启用密钥引擎

vault secrets enable -path=secret kv-v2
vault secrets enable -path=secret kv-v2

Store secret

存储密钥

vault kv put secret/database/config username=admin password=secret
undefined
vault kv put secret/database/config username=admin password=secret
undefined

GitHub Actions with Vault

GitHub Actions与Vault集成

yaml
name: Deploy with Vault Secrets

on: [push]

jobs:
  deploy:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4

      - name: Import Secrets from Vault
        uses: hashicorp/vault-action@v2
        with:
          url: https://vault.example.com:8200
          token: ${{ secrets.VAULT_TOKEN }}
          secrets: |
            secret/data/database username | DB_USERNAME ;
            secret/data/database password | DB_PASSWORD ;
            secret/data/api key | API_KEY

      - name: Use secrets
        run: |
          echo "Connecting to database as $DB_USERNAME"
          # Use $DB_PASSWORD, $API_KEY
yaml
name: Deploy with Vault Secrets

on: [push]

jobs:
  deploy:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4

      - name: Import Secrets from Vault
        uses: hashicorp/vault-action@v2
        with:
          url: https://vault.example.com:8200
          token: ${{ secrets.VAULT_TOKEN }}
          secrets: |
            secret/data/database username | DB_USERNAME ;
            secret/data/database password | DB_PASSWORD ;
            secret/data/api key | API_KEY

      - name: Use secrets
        run: |
          echo "Connecting to database as $DB_USERNAME"
          # Use $DB_PASSWORD, $API_KEY

GitLab CI with Vault

GitLab CI与Vault集成

yaml
deploy:
  image: vault:latest
  before_script:
    - export VAULT_ADDR=https://vault.example.com:8200
    - export VAULT_TOKEN=$VAULT_TOKEN
    - apk add curl jq
  script:
    - |
      DB_PASSWORD=$(vault kv get -field=password secret/database/config)
      API_KEY=$(vault kv get -field=key secret/api/credentials)
      echo "Deploying with secrets..."
      # Use $DB_PASSWORD, $API_KEY
Reference: See
references/vault-setup.md
yaml
deploy:
  image: vault:latest
  before_script:
    - export VAULT_ADDR=https://vault.example.com:8200
    - export VAULT_TOKEN=$VAULT_TOKEN
    - apk add curl jq
  script:
    - |
      DB_PASSWORD=$(vault kv get -field=password secret/database/config)
      API_KEY=$(vault kv get -field=key secret/api/credentials)
      echo "Deploying with secrets..."
      # Use $DB_PASSWORD, $API_KEY
参考文档: 详见
references/vault-setup.md

AWS Secrets Manager

AWS Secrets Manager

Store Secret

存储密钥

bash
aws secretsmanager create-secret \
  --name production/database/password \
  --secret-string "super-secret-password"
bash
aws secretsmanager create-secret \
  --name production/database/password \
  --secret-string "super-secret-password"

Retrieve in GitHub Actions

在GitHub Actions中检索密钥

yaml
- name: Configure AWS credentials
  uses: aws-actions/configure-aws-credentials@v4
  with:
    aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }}
    aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
    aws-region: us-west-2

- name: Get secret from AWS
  run: |
    SECRET=$(aws secretsmanager get-secret-value \
      --secret-id production/database/password \
      --query SecretString \
      --output text)
    echo "::add-mask::$SECRET"
    echo "DB_PASSWORD=$SECRET" >> $GITHUB_ENV

- name: Use secret
  run: |
    # Use $DB_PASSWORD
    ./deploy.sh
yaml
- name: Configure AWS credentials
  uses: aws-actions/configure-aws-credentials@v4
  with:
    aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }}
    aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
    aws-region: us-west-2

- name: Get secret from AWS
  run: |
    SECRET=$(aws secretsmanager get-secret-value \
      --secret-id production/database/password \
      --query SecretString \
      --output text)
    echo "::add-mask::$SECRET"
    echo "DB_PASSWORD=$SECRET" >> $GITHUB_ENV

- name: Use secret
  run: |
    # Use $DB_PASSWORD
    ./deploy.sh

Terraform with AWS Secrets Manager

Terraform与AWS Secrets Manager集成

hcl
data "aws_secretsmanager_secret_version" "db_password" {
  secret_id = "production/database/password"
}

resource "aws_db_instance" "main" {
  allocated_storage    = 100
  engine              = "postgres"
  instance_class      = "db.t3.large"
  username            = "admin"
  password            = jsondecode(data.aws_secretsmanager_secret_version.db_password.secret_string)["password"]
}
hcl
data "aws_secretsmanager_secret_version" "db_password" {
  secret_id = "production/database/password"
}

resource "aws_db_instance" "main" {
  allocated_storage    = 100
  engine              = "postgres"
  instance_class      = "db.t3.large"
  username            = "admin"
  password            = jsondecode(data.aws_secretsmanager_secret_version.db_password.secret_string)["password"]
}

GitHub Secrets

GitHub Secrets

Organization/Repository Secrets

组织/仓库密钥

yaml
- name: Use GitHub secret
  run: |
    echo "API Key: ${{ secrets.API_KEY }}"
    echo "Database URL: ${{ secrets.DATABASE_URL }}"
yaml
- name: Use GitHub secret
  run: |
    echo "API Key: ${{ secrets.API_KEY }}"
    echo "Database URL: ${{ secrets.DATABASE_URL }}"

Environment Secrets

环境密钥

yaml
deploy:
  runs-on: ubuntu-latest
  environment: production
  steps:
    - name: Deploy
      run: |
        echo "Deploying with ${{ secrets.PROD_API_KEY }}"
Reference: See
references/github-secrets.md
yaml
deploy:
  runs-on: ubuntu-latest
  environment: production
  steps:
    - name: Deploy
      run: |
        echo "Deploying with ${{ secrets.PROD_API_KEY }}"
参考文档: 详见
references/github-secrets.md

GitLab CI/CD Variables

GitLab CI/CD变量

Project Variables

项目变量

yaml
deploy:
  script:
    - echo "Deploying with $API_KEY"
    - echo "Database: $DATABASE_URL"
yaml
deploy:
  script:
    - echo "Deploying with $API_KEY"
    - echo "Database: $DATABASE_URL"

Protected and Masked Variables

受保护和掩码变量

  • Protected: Only available in protected branches
  • Masked: Hidden in job logs
  • File type: Stored as file
  • 受保护:仅在受保护分支中可用
  • 掩码:在作业日志中隐藏
  • 文件类型:以文件形式存储

Best Practices

最佳实践

  1. Never commit secrets to Git
  2. Use different secrets per environment
  3. Rotate secrets regularly
  4. Implement least-privilege access
  5. Enable audit logging
  6. Use secret scanning (GitGuardian, TruffleHog)
  7. Mask secrets in logs
  8. Encrypt secrets at rest
  9. Use short-lived tokens when possible
  10. Document secret requirements
  1. 切勿将密钥提交至Git
  2. 为不同环境使用不同密钥
  3. 定期轮换密钥
  4. 实现最小权限访问
  5. 启用审计日志
  6. 使用密钥扫描工具(GitGuardian、TruffleHog)
  7. 在日志中掩码密钥
  8. 静态加密密钥
  9. 尽可能使用短期令牌
  10. 记录密钥要求

Secret Rotation

密钥轮换

Automated Rotation with AWS

使用AWS自动轮换

python
import boto3
import json

def lambda_handler(event, context):
    client = boto3.client('secretsmanager')

    # Get current secret
    response = client.get_secret_value(SecretId='my-secret')
    current_secret = json.loads(response['SecretString'])

    # Generate new password
    new_password = generate_strong_password()

    # Update database password
    update_database_password(new_password)

    # Update secret
    client.put_secret_value(
        SecretId='my-secret',
        SecretString=json.dumps({
            'username': current_secret['username'],
            'password': new_password
        })
    )

    return {'statusCode': 200}
python
import boto3
import json

def lambda_handler(event, context):
    client = boto3.client('secretsmanager')

    # 获取当前密钥
    response = client.get_secret_value(SecretId='my-secret')
    current_secret = json.loads(response['SecretString'])

    # 生成新密码
    new_password = generate_strong_password()

    # 更新数据库密码
    update_database_password(new_password)

    # 更新密钥
    client.put_secret_value(
        SecretId='my-secret',
        SecretString=json.dumps({
            'username': current_secret['username'],
            'password': new_password
        })
    )

    return {'statusCode': 200}

Manual Rotation Process

手动轮换流程

  1. Generate new secret
  2. Update secret in secret store
  3. Update applications to use new secret
  4. Verify functionality
  5. Revoke old secret
  1. 生成新密钥
  2. 在密钥存储中更新密钥
  3. 更新应用以使用新密钥
  4. 验证功能正常
  5. 撤销旧密钥

External Secrets Operator

External Secrets Operator

Kubernetes Integration

Kubernetes集成

yaml
apiVersion: external-secrets.io/v1beta1
kind: SecretStore
metadata:
  name: vault-backend
  namespace: production
spec:
  provider:
    vault:
      server: "https://vault.example.com:8200"
      path: "secret"
      version: "v2"
      auth:
        kubernetes:
          mountPath: "kubernetes"
          role: "production"

---
apiVersion: external-secrets.io/v1beta1
kind: ExternalSecret
metadata:
  name: database-credentials
  namespace: production
spec:
  refreshInterval: 1h
  secretStoreRef:
    name: vault-backend
    kind: SecretStore
  target:
    name: database-credentials
    creationPolicy: Owner
  data:
    - secretKey: username
      remoteRef:
        key: database/config
        property: username
    - secretKey: password
      remoteRef:
        key: database/config
        property: password
yaml
apiVersion: external-secrets.io/v1beta1
kind: SecretStore
metadata:
  name: vault-backend
  namespace: production
spec:
  provider:
    vault:
      server: "https://vault.example.com:8200"
      path: "secret"
      version: "v2"
      auth:
        kubernetes:
          mountPath: "kubernetes"
          role: "production"

---
apiVersion: external-secrets.io/v1beta1
kind: ExternalSecret
metadata:
  name: database-credentials
  namespace: production
spec:
  refreshInterval: 1h
  secretStoreRef:
    name: vault-backend
    kind: SecretStore
  target:
    name: database-credentials
    creationPolicy: Owner
  data:
    - secretKey: username
      remoteRef:
        key: database/config
        property: username
    - secretKey: password
      remoteRef:
        key: database/config
        property: password

Secret Scanning

密钥扫描

Pre-commit Hook

提交前钩子

bash
#!/bin/bash
bash
#!/bin/bash

.git/hooks/pre-commit

.git/hooks/pre-commit

Check for secrets with TruffleHog

使用TruffleHog检查密钥

docker run --rm -v "$(pwd):/repo"
trufflesecurity/trufflehog:latest
filesystem --directory=/repo
if [ $? -ne 0 ]; then echo "❌ Secret detected! Commit blocked." exit 1 fi
undefined
docker run --rm -v "$(pwd):/repo"
trufflesecurity/trufflehog:latest
filesystem --directory=/repo
if [ $? -ne 0 ]; then echo "❌ 检测到密钥!提交已阻止。" exit 1 fi
undefined

CI/CD Secret Scanning

CI/CD密钥扫描

yaml
secret-scan:
  stage: security
  image: trufflesecurity/trufflehog:latest
  script:
    - trufflehog filesystem .
  allow_failure: false
yaml
secret-scan:
  stage: security
  image: trufflesecurity/trufflehog:latest
  script:
    - trufflehog filesystem .
  allow_failure: false

Reference Files

参考文件

  • references/vault-setup.md
    - HashiCorp Vault configuration
  • references/github-secrets.md
    - GitHub Secrets best practices
  • references/vault-setup.md
    - HashiCorp Vault配置文档
  • references/github-secrets.md
    - GitHub Secrets最佳实践

Related Skills

相关技能

  • github-actions-templates
    - For GitHub Actions integration
  • gitlab-ci-patterns
    - For GitLab CI integration
  • deployment-pipeline-design
    - For pipeline architecture
  • github-actions-templates
    - 用于GitHub Actions集成
  • gitlab-ci-patterns
    - 用于GitLab CI集成
  • deployment-pipeline-design
    - 用于流水线架构设计