secrets-management

Par wshobson · agents

Implémentez une gestion sécurisée des secrets pour les pipelines CI/CD à l'aide de Vault, AWS Secrets Manager ou des solutions natives à la plateforme. À utiliser lors de la manipulation d'identifiants sensibles, de la rotation des secrets ou de la sécurisation des environnements CI/CD.

npx skills add https://github.com/wshobson/agents --skill secrets-management

Gestion des secrets

Bonnes pratiques de gestion sécurisée des secrets pour les pipelines CI/CD en utilisant Vault, AWS Secrets Manager et autres outils.

Objectif

Implémenter une gestion sécurisée des secrets dans les pipelines CI/CD sans hardcoder les informations sensibles.

Quand l'utiliser

  • Stocker les clés API et identifiants
  • Gérer les mots de passe de base de données
  • Gérer les certificats TLS
  • Rotation automatique des secrets
  • Implémenter l'accès au privilège minimal

Outils de gestion des secrets

HashiCorp Vault

  • Gestion centralisée des secrets
  • Génération de secrets dynamiques
  • Rotation des secrets
  • Audit logging
  • Contrôle d'accès granulaire

AWS Secrets Manager

  • Solution native AWS
  • Rotation automatique
  • Intégration avec RDS
  • Support CloudFormation

Azure Key Vault

  • Solution native Azure
  • Clés sauvegardées par HSM
  • Gestion des certificats
  • Intégration RBAC

Google Secret Manager

  • Solution native GCP
  • Versioning
  • Intégration IAM

Intégration HashiCorp Vault

Configuration de 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 avec 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 avec 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

Référence : Voir references/vault-setup.md

AWS Secrets Manager

Stocker un secret

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

Récupérer dans 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 avec 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"]
}

Secrets GitHub

Secrets d'organisation/dépôt

- 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

Secrets d'environnement

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

Référence : Voir references/github-secrets.md

Variables GitLab CI/CD

Variables de projet

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

Variables protégées et masquées

  • Protégées : Disponibles uniquement sur les branches protégées
  • Masquées : Cachées dans les logs de job
  • Type fichier : Stockées sous forme de fichier

Bonnes pratiques

  1. Ne jamais committer les secrets dans Git
  2. Utiliser des secrets différents par environnement
  3. Rotation régulière des secrets
  4. Implémenter l'accès au privilège minimal
  5. Activer l'audit logging
  6. Utiliser le scanning de secrets (GitGuardian, TruffleHog)
  7. Masquer les secrets dans les logs
  8. Chiffrer les secrets au repos
  9. Utiliser des tokens de courte durée quand possible
  10. Documenter les exigences en matière de secrets

Rotation des secrets

Rotation automatisée avec 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}

Processus de rotation manuelle

  1. Générer un nouveau secret
  2. Mettre à jour le secret dans le gestionnaire de secrets
  3. Mettre à jour les applications pour utiliser le nouveau secret
  4. Vérifier la fonctionnalité
  5. Révoquer l'ancien secret

External Secrets Operator

Intégration Kubernetes

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

Secret Scanning en CI/CD

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

Compétences associées

  • github-actions-templates - Pour l'intégration GitHub Actions
  • gitlab-ci-patterns - Pour l'intégration GitLab CI
  • deployment-pipeline-design - Pour l'architecture des pipelines

Skills similaires