secrets-management

Secure secrets management for CI/CD pipelines using Vault, AWS Secrets Manager, and platform-native solutions. Supports multiple backends: HashiCorp Vault, AWS Secrets Manager, Azure Key Vault, Google Secret Manager, and GitHub/GitLab native secrets Includes integration examples for GitHub Actions, GitLab CI, Terraform, and Kubernetes with automatic secret rotation capabilities Covers best practices including secret masking in logs, least-privilege access, audit logging, and secret scanning with tools like TruffleHog Provides setup guides and code examples for storing, retrieving, and rotating credentials across different CI/CD platforms and infrastructure tools

INSTALLATION
npx skills add https://github.com/wshobson/agents --skill secrets-management
Run in your project or agent environment. Adjust flags if your CLI version differs.

SKILL.md

Secrets Management

Secure secrets management practices for CI/CD pipelines using Vault, AWS Secrets Manager, and other tools.

Purpose

Implement secure secrets management in CI/CD pipelines without hardcoding sensitive information.

When to Use

  • Store API keys and credentials
  • Manage database passwords
  • Handle TLS certificates
  • Rotate secrets automatically
  • Implement least-privilege access

Secrets Management Tools

HashiCorp Vault

  • Centralized secrets management
  • Dynamic secrets generation
  • Secret rotation
  • Audit logging
  • Fine-grained access control

AWS Secrets Manager

  • AWS-native solution
  • Automatic rotation
  • Integration with RDS
  • CloudFormation support

Azure Key Vault

  • Azure-native solution
  • HSM-backed keys
  • Certificate management
  • RBAC integration

Google Secret Manager

  • GCP-native solution
  • Versioning
  • IAM integration

HashiCorp Vault Integration

Setup Vault

# 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:1.17

  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

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

    # Use $DB_PASSWORD

    ./deploy.sh

Terraform with AWS Secrets Manager

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

Organization/Repository Secrets

- name: Use GitHub secret

  env:

    API_KEY: ${{ secrets.API_KEY }}

    DATABASE_URL: ${{ secrets.DATABASE_URL }}

  run: |

    # Secrets are injected as env vars — never print them to logs

    ./deploy.sh

Environment Secrets

deploy:

  runs-on: ubuntu-latest

  environment: production

  steps:

    - name: Deploy

      env:

        PROD_API_KEY: ${{ secrets.PROD_API_KEY }}

      run: |

        # Secret injected as env var — never print to logs

        ./deploy.sh

Reference: See references/github-secrets.md

GitLab CI/CD Variables

Project Variables

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

  • Never commit secrets to Git
  • Use different secrets per environment
  • Rotate secrets regularly
  • Implement least-privilege access
  • Enable audit logging
  • Use secret scanning (GitGuardian, TruffleHog)
  • Mask secrets in logs
  • Encrypt secrets at rest
  • Use short-lived tokens when possible
  • Document secret requirements

Secret Rotation

Automated Rotation with AWS

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

  • Generate new secret
  • Update secret in secret store
  • Update applications to use new secret
  • Verify functionality
  • Revoke old secret

External Secrets Operator

Kubernetes Integration

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

#!/bin/bash

# .git/hooks/pre-commit

# Check for secrets with TruffleHog

docker run --rm -v "$(pwd):/repo" \

  trufflesecurity/trufflehog:3.88 \

  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:3.88

  script:

    - trufflehog filesystem .

  allow_failure: false

Related Skills

  • github-actions-templates - For GitHub Actions integration
  • gitlab-ci-patterns - For GitLab CI integration
  • deployment-pipeline-design - For pipeline architecture
BrowserAct

Let your agent run on any real-world website

Bypass CAPTCHA & anti-bot for free. Start local, scale to cloud.

Explore BrowserAct Skills →

Stop writing automation&scrapers

Install the CLI. Run your first Skill in 30 seconds. Scale when you're ready.

Start free
free · no credit card