secrets-env-manager

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

Secrets & Env Manager

密钥与环境变量管理器

Secure secrets handling and environment variable validation in CI/CD.
在CI/CD中安全处理密钥并验证环境变量。

Environment Variable Validation

环境变量验证

yaml
validate-env:
  runs-on: ubuntu-latest
  steps:
    - uses: actions/checkout@v4

    - name: Validate required environment variables
      run: |
        REQUIRED_VARS=(
          "DATABASE_URL"
          "API_KEY"
          "AWS_REGION"
          "STRIPE_SECRET_KEY"
        )

        MISSING=()
        for var in "${REQUIRED_VARS[@]}"; do
          if [ -z "${!var}" ]; then
            MISSING+=("$var")
          fi
        done

        if [ ${#MISSING[@]} -ne 0 ]; then
          echo "❌ Missing required environment variables:"
          printf '%s\n' "${MISSING[@]}"
          exit 1
        fi

        echo "✅ All required environment variables are set"
      env:
        DATABASE_URL: ${{ secrets.DATABASE_URL }}
        API_KEY: ${{ secrets.API_KEY }}
        AWS_REGION: ${{ secrets.AWS_REGION }}
        STRIPE_SECRET_KEY: ${{ secrets.STRIPE_SECRET_KEY }}
yaml
validate-env:
  runs-on: ubuntu-latest
  steps:
    - uses: actions/checkout@v4

    - name: Validate required environment variables
      run: |
        REQUIRED_VARS=(
          "DATABASE_URL"
          "API_KEY"
          "AWS_REGION"
          "STRIPE_SECRET_KEY"
        )

        MISSING=()
        for var in "${REQUIRED_VARS[@]}"; do
          if [ -z "${!var}" ]; then
            MISSING+=("$var")
          fi
        done

        if [ ${#MISSING[@]} -ne 0 ]; then
          echo "❌ Missing required environment variables:"
          printf '%s\n' "${MISSING[@]}"
          exit 1
        fi

        echo "✅ All required environment variables are set"
      env:
        DATABASE_URL: ${{ secrets.DATABASE_URL }}
        API_KEY: ${{ secrets.API_KEY }}
        AWS_REGION: ${{ secrets.AWS_REGION }}
        STRIPE_SECRET_KEY: ${{ secrets.STRIPE_SECRET_KEY }}

Secret Masking

密钥掩码

yaml
- name: Mask sensitive values
  run: |
    # Automatically masked in GitHub Actions
    echo "::add-mask::${{ secrets.API_KEY }}"
    echo "::add-mask::${{ secrets.DATABASE_PASSWORD }}"

    # Safe to use in commands
    curl -H "Authorization: Bearer ${{ secrets.API_KEY }}" https://api.example.com
yaml
- name: Mask sensitive values
  run: |
    # Automatically masked in GitHub Actions
    echo "::add-mask::${{ secrets.API_KEY }}"
    echo "::add-mask::${{ secrets.DATABASE_PASSWORD }}"

    # Safe to use in commands
    curl -H "Authorization: Bearer ${{ secrets.API_KEY }}" https://api.example.com

Leak Prevention

泄露防护

yaml
- name: Check for leaked secrets
  uses: trufflesecurity/trufflehog@main
  with:
    path: ./
    base: ${{ github.event.repository.default_branch }}
    head: HEAD

- name: Detect hardcoded secrets
  uses: reviewdog/action-detect-secrets@master
  with:
    github_token: ${{ secrets.GITHUB_TOKEN }}
    reporter: github-pr-review
yaml
- name: Check for leaked secrets
  uses: trufflesecurity/trufflehog@main
  with:
    path: ./
    base: ${{ github.event.repository.default_branch }}
    head: HEAD

- name: Detect hardcoded secrets
  uses: reviewdog/action-detect-secrets@master
  with:
    github_token: ${{ secrets.GITHUB_TOKEN }}
    reporter: github-pr-review

Environment-specific Secrets

环境专属密钥

yaml
deploy:
  runs-on: ubuntu-latest
  environment:
    name: ${{ github.event.inputs.environment }}
  steps:
    - name: Deploy
      run: |
        # Environment-specific secrets are automatically scoped
        echo "Deploying to ${{ github.event.inputs.environment }}"
      env:
        DATABASE_URL: ${{ secrets.DATABASE_URL }}
        API_KEY: ${{ secrets.API_KEY }}
yaml
deploy:
  runs-on: ubuntu-latest
  environment:
    name: ${{ github.event.inputs.environment }}
  steps:
    - name: Deploy
      run: |
        # Environment-specific secrets are automatically scoped
        echo "Deploying to ${{ github.event.inputs.environment }}"
      env:
        DATABASE_URL: ${{ secrets.DATABASE_URL }}
        API_KEY: ${{ secrets.API_KEY }}

Secret Validation Script

密钥验证脚本

typescript
// scripts/validate-env.ts
import * as fs from "fs";

interface EnvConfig {
  required: string[];
  optional: string[];
}

const config: EnvConfig = {
  required: ["DATABASE_URL", "JWT_SECRET", "STRIPE_SECRET_KEY"],
  optional: ["SENTRY_DSN", "LOG_LEVEL"],
};

function validateEnv(): boolean {
  const missing: string[] = [];

  config.required.forEach((key) => {
    if (!process.env[key]) {
      missing.push(key);
    }
  });

  if (missing.length > 0) {
    console.error("❌ Missing required environment variables:");
    missing.forEach((key) => console.error(`  - ${key}`));
    return false;
  }

  console.log("✅ All required environment variables are set");
  return true;
}

if (!validateEnv()) {
  process.exit(1);
}
typescript
// scripts/validate-env.ts
import * as fs from "fs";

interface EnvConfig {
  required: string[];
  optional: string[];
}

const config: EnvConfig = {
  required: ["DATABASE_URL", "JWT_SECRET", "STRIPE_SECRET_KEY"],
  optional: ["SENTRY_DSN", "LOG_LEVEL"],
};

function validateEnv(): boolean {
  const missing: string[] = [];

  config.required.forEach((key) => {
    if (!process.env[key]) {
      missing.push(key);
    }
  });

  if (missing.length > 0) {
    console.error("❌ Missing required environment variables:");
    missing.forEach((key) => console.error(`  - ${key}`));
    return false;
  }

  console.log("✅ All required environment variables are set");
  return true;
}

if (!validateEnv()) {
  process.exit(1);
}

.env.example Template

.env.example 模板

bash
undefined
bash
undefined

.env.example - Check into git

.env.example - Check into git

Copy to .env and fill in values

Copy to .env and fill in values

Database

Database

DATABASE_URL=postgresql://user:password@localhost:5432/mydb
DATABASE_URL=postgresql://user:password@localhost:5432/mydb

Authentication

Authentication

JWT_SECRET=your-secret-here JWT_EXPIRY=24h
JWT_SECRET=your-secret-here JWT_EXPIRY=24h

External APIs

External APIs

STRIPE_SECRET_KEY=sk_test_... SENDGRID_API_KEY=SG....
STRIPE_SECRET_KEY=sk_test_... SENDGRID_API_KEY=SG....

AWS

AWS

AWS_ACCESS_KEY_ID=AKIA... AWS_SECRET_ACCESS_KEY=... AWS_REGION=us-east-1
AWS_ACCESS_KEY_ID=AKIA... AWS_SECRET_ACCESS_KEY=... AWS_REGION=us-east-1

Optional

Optional

SENTRY_DSN=https://... LOG_LEVEL=info
undefined
SENTRY_DSN=https://... LOG_LEVEL=info
undefined

Documentation Template

文档模板

markdown
undefined
markdown
undefined

Environment Variables

Environment Variables

Required Variables

Required Variables

DATABASE_URL

DATABASE_URL

Description: PostgreSQL connection string Format:
postgresql://user:password@host:5432/database
Example:
postgresql://app:secret@localhost:5432/myapp
Where to get: Create database on Heroku/RDS
Description: PostgreSQL connection string Format:
postgresql://user:password@host:5432/database
Example:
postgresql://app:secret@localhost:5432/myapp
Where to get: Create database on Heroku/RDS

STRIPE_SECRET_KEY

STRIPE_SECRET_KEY

Description: Stripe API secret key Format:
sk_test_...
or
sk_live_...
Example:
sk_test_51abc123...
Where to get: Stripe Dashboard → Developers → API Keys ⚠️ Never commit to git
Description: Stripe API secret key Format:
sk_test_...
or
sk_live_...
Example:
sk_test_51abc123...
Where to get: Stripe Dashboard → Developers → API Keys ⚠️ Never commit to git

Optional Variables

Optional Variables

LOG_LEVEL

LOG_LEVEL

Description: Logging verbosity Format:
error | warn | info | debug
Default:
info
undefined
Description: Logging verbosity Format:
error | warn | info | debug
Default:
info
undefined

Fail-Fast Validation

快速失败验证

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

      - name: Validate secrets exist
        run: |
          if [ -z "${{ secrets.DATABASE_URL }}" ]; then
            echo "::error::DATABASE_URL secret not set"
            exit 1
          fi

          if [ -z "${{ secrets.API_KEY }}" ]; then
            echo "::error::API_KEY secret not set"
            exit 1
          fi

  deploy:
    needs: validate
    runs-on: ubuntu-latest
    steps:
      - name: Deploy
        run: echo "Deploying..."
yaml
jobs:
  validate:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4

      - name: Validate secrets exist
        run: |
          if [ -z "${{ secrets.DATABASE_URL }}" ]; then
            echo "::error::DATABASE_URL secret not set"
            exit 1
          fi

          if [ -z "${{ secrets.API_KEY }}" ]; then
            echo "::error::API_KEY secret not set"
            exit 1
          fi

  deploy:
    needs: validate
    runs-on: ubuntu-latest
    steps:
      - name: Deploy
        run: echo "Deploying..."

Best Practices

最佳实践

  1. Never log secrets: Always mask sensitive values
  2. Validate early: Check secrets before deployment
  3. Use GitHub Secrets: Never hardcode in workflows
  4. Environment separation: Dev/staging/prod secrets
  5. Rotate regularly: Update secrets periodically
  6. Principle of least privilege: Minimal permissions
  7. Document clearly: Where to get each secret
  8. Scan for leaks: Automated detection
  1. 切勿记录密钥:始终对敏感值进行掩码处理
  2. 提前验证:在部署前检查密钥
  3. 使用GitHub Secrets:切勿在工作流中硬编码
  4. 环境隔离:区分开发/预发布/生产环境的密钥
  5. 定期轮换:定期更新密钥
  6. 最小权限原则:使用最小必要权限
  7. 清晰文档:记录每个密钥的获取途径
  8. 扫描泄露:自动检测泄露情况

Output Checklist

输出检查清单

  • Required env vars validated
  • Secret masking configured
  • Leak detection enabled
  • .env.example template
  • Environment variables documented
  • Fail-fast validation
  • Environment-specific secrets
  • Rotation policy documented
  • 已验证必填环境变量
  • 已配置密钥掩码
  • 已启用泄露检测
  • 已准备.env.example模板
  • 已记录环境变量
  • 已配置快速失败验证
  • 已设置环境专属密钥
  • 已记录密钥轮换策略