Skip to Content
SecurityGestion des secrets

Gestion des secrets

Bonnes pratiques pour stocker, rotationner et protéger les secrets (clés API, mots de passe, tokens) dans un projet de développement.

Principes fondamentaux

Ne jamais commiter de secret dans un dépôt Git. Un secret dans Git reste dans l’historique même après suppression du fichier.

Règle d’or : un secret ne doit exister que dans trois endroits :

  1. La machine du développeur (variable d’environnement ou gestionnaire de secrets local)
  2. Le serveur de production (variables d’environnement du déploiement)
  3. Un gestionnaire de secrets dédié (Vault, AWS Secrets Manager, etc.)

Fichiers .env

Structure recommandée

# .env (jamais commité !) DATABASE_URL=postgresql://user:***@localhost:5432/app JWT_SECRET=a1b2c3d4e5f6... API_KEY_SK=sk_liv...xxxx # .env.example (commité — modèle sans valeurs réelles) DATABASE_URL=postgresql://user:***@localhost:5432/app JWT_SECRET=<votre_secret_jwt> API_KEY_SK=<votre_clé_api>

.gitignore

# Secrets — jamais commités .env .env.local .env.production *.key *.pem secrets/

Validation d’un fichier .env

# Vérifier que les variables requises sont définies (script shell) required_vars=("DATABASE_URL" "JWT_SECRET" "API_KEY_SK") for var in "${required_vars[@]}"; do if [ -z "${!var}" ]; then echo "ERREUR: $var n'est pas défini" exit 1 fi done echo "Toutes les variables sont présentes."

Rotation des secrets

Stratégie de rotation

  1. Définir une politique de rotation : 90 jours pour les mots de passe, 180 jours pour les clés API
  2. Générer le nouveau secret (voir CLI Security)
  3. Déployer le nouveau secret avec la possibilité de cohabiter l’ancien et le nouveau pendant une fenêtre de bascule
  4. Révoquer l’ancien secret après la fenêtre de cohabitation

Rotation automatisée (exemple cron)

# Cron quotidien — génère un nouveau JWT_SECRET et redémarre l'appli 0 3 * * * /opt/scripts/rotate-secrets.sh >> /var/log/secret-rotation.log 2>&1
#!/bin/bash # /opt/scripts/rotate-secrets.sh NEW_SECRET=$(openssl rand -hex 32) echo "Nouveau JWT_SECRET généré à $(date)" >> /var/log/secret-rotation.log # Mettre à jour dans le fichier de config ou la variable d'environnement export JWT_SECRET="$NEW_SECRET" # Redémarrer l'application (systemd) systemctl restart mon-app

Git-secrets — Prévenir les fuites

Git-secrets scanne les commits pour détecter les patterns de secrets avant qu’ils ne soient envoyés à distance.

# Installation macOS brew install AWS/git-secrets/git-secrets # Installation Linux sudo apt-get install git-secrets # Initialiser dans le dépôt git secrets --install git secrets --register-aws # Ajouter des patterns personnalisés git secrets --add 'sk_live_[0-9a-zA-Z]+' git secrets --add '-----BEGIN (RSA |EC )?PRIVATE KEY-----' git secrets --add 'AWS_SECRET_ACCESS_KEY\s*=\s*["\047][0-9a-zA-Z/+=]{40}["\047]' # Scanner l'historique existant git secrets --scan --history

Hook pre-commit

#!/bin/bash # .git/hooks/pre-commit git secrets --scan if [ $? -ne 0 ]; then echo "ERREUR : des secrets potentiels ont été détectés dans les fichiers modifiés." echo "Annulation du commit." exit 1 fi

CI/CD — Secrets dans les pipelines

GitHub Actions

# .github/workflows/deploy.yml name: Déploiement on: push: branches: [main] jobs: deploy: runs-on: ubuntu-latest env: DATABASE_URL: ${{ secrets.DATABASE_URL }} JWT_SECRET: ${{ secrets.JWT_SECRET }} steps: - uses: actions/checkout@v4 - name: Déploiement run: ./scripts/deploy.sh

Ne jamais afficher les secrets dans les logs CI/CD. Utiliser echo "::add-mask::$SECRETS" dans GitHub Actions pour masquer automatiquement les valeurs sensibles.

Variable d’environnement masquée (GitHub Actions)

steps: - name: Masquer les secrets dans les logs run: | echo "::add-mask::${{ secrets.DATABASE_URL }}" echo "::add-mask::${{ secrets.JWT_SECRET }}"

Environnements protégés

Utiliser les environnements protégés GitHub Actions pour limiter l’accès aux secrets de production :

jobs: deploy-prod: environment: production # Nécessite une approbation manuelle runs-on: ubuntu-latest

Gestionnaires de secrets dédiés

HashiCorp Vault (aperçu)

Vault centralise les secrets avec rotation automatique, audit logging, et accès via API ou CLI.

# Installation # Voir https://developer.hashicorp.com/vault/install # Démarrer un serveur Vault en développement (usage local uniquement) vault server -dev # Authentification export VAULT_ADDR=http://127.0.0.1:8200 export VAULT_TOKEN=hvs.xxx # Lire un secret vault kv get secret/app-config # Écrire un secret vault kv put secret/app-config jwt_secret="nouveau_secret_ici" database_url="postgresql://..." # Rotation automatique (API) curl --request POST \ --header "X-Vault-Token: $VAULT_TOKEN" \ --data '{"type":"rotation","period":"720h"}' \ http://127.0.0.1:8200/v1/secret/data/rotate/jwt_secret

AWS Secrets Manager (aperçu)

# Récupérer un secret depuis AWS aws secretsmanager get-secret-value \ --secret-id production/JWT_SECRET \ --query SecretString --output text

Checklist de sécurisation des secrets

  • .env présent dans .gitignore
  • .env.example présent dans le dépôt (sans valeurs réelles)
  • Variables d’environnement requises validées au démarrage de l’application
  • Git-secrets ou hook pre-commit installé
  • Secrets dans la CI/CD via des variables protégées (pas de hardcodage)
  • Secrets d’origine masqués dans les logs (::add-mask::)
  • Politique de rotation définie (90 jours minimum)
  • Secret existant jamais compilé dans le code binaire ou les assets