HomeBrowseUpload
← Back to registry
// Skill profile

Secrets Management

Secure secrets management for CI/CD pipelines using Vault, AWS Secrets Manager, and native platform solutions.

by brandonwise · published 2026-03-22

开发工具图像生成加密货币
Total installs
0
Stars
★ 0
Last updated
2026-03
// Install command
$ claw add gh:brandonwise/brandonwise-secrets-management
View on GitHub
// Full documentation

# Secrets Management

Secure secrets management for CI/CD pipelines using Vault, AWS Secrets Manager, and native platform solutions.

Description

USE WHEN:

  • Storing API keys and credentials securely
  • Managing database passwords
  • Handling TLS certificates
  • Setting up automatic secret rotation
  • Implementing least-privilege access patterns
  • Integrating secrets into CI/CD pipelines (GitHub Actions, GitLab CI)
  • Deploying to Kubernetes with external secrets
  • DON'T USE WHEN:

  • Only need local dev values (use .env files not in git)
  • Cannot secure access to the secrets backend
  • Planning to hardcode secrets (don't do that)
  • ---

    Secrets Management Tools Comparison

    | Tool | Best For | Key Features |

    |------|----------|--------------|

    | **HashiCorp Vault** | Enterprise, multi-cloud | Dynamic secrets, rotation, audit logging |

    | **AWS Secrets Manager** | AWS-native workloads | RDS integration, auto-rotation |

    | **Azure Key Vault** | Azure workloads | HSM-backed, certificate management |

    | **Google Secret Manager** | GCP workloads | Versioning, IAM integration |

    | **GitHub Secrets** | GitHub Actions | Simple, per-repo/org/environment |

    | **GitLab CI Variables** | GitLab CI | Protected branches, masked variables |

    ---

    HashiCorp Vault

    Setup

    # Start Vault dev server
    vault server -dev
    
    # Set environment
    export VAULT_ADDR='http://127.0.0.1:8200'
    export VAULT_TOKEN='root'
    
    # Enable secrets engine
    vault secrets enable -path=secret kv-v2
    
    # Store secret
    vault kv put secret/database/config username=admin password=secret

    GitHub Actions with Vault

    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

    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..."

    ---

    AWS Secrets Manager

    Store Secret

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

    Retrieve in GitHub Actions

    - 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: ./deploy.sh  # $DB_PASSWORD available

    Terraform Integration

    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"]
    }

    ---

    Kubernetes: External Secrets Operator

    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 Rotation

    Automated (AWS Lambda)

    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}

    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

    ---

    Secret Scanning

    Pre-commit Hook

    #!/bin/bash
    # .git/hooks/pre-commit
    
    # Check for secrets with 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

    CI/CD Secret Scanning

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

    ---

    Best Practices

    1. **Never commit secrets** to Git

    2. **Use different secrets** per environment

    3. **Rotate secrets regularly** (90 days max)

    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**

    ---

    Related Skills

  • `vulnerability-scanner` - For detecting exposed secrets in code
  • `api-security` - For securing API credentials
  • // Comments
    Sign in with GitHub to leave a comment.
    // Related skills

    More tools from the same signal band