Aller au contenu

Gestion des secrets

API keys, tokens, certificats et mots de passe — stocker, rotater et détecter les fuites avant qu'il ne soit trop tard.


La règle absolue

Un secret commite dans un dépôt Git est compromis. Même supprimé dans un commit suivant, il reste dans l'historique. Même un dépôt prive peut devenir public. Revoquer immédiatement tout secret expose.

Types de secrets

Type Exemples Risque en cas de fuite
Credentials DB postgres://user:pass@host/db Accès complet aux données
API keys OpenAI, Stripe, Twilio, AWS Facturation, accès données, actions métier
Tokens OAuth Access token, refresh token Usurpation d'identité
Clés de chiffrement Fernet key, AES key, RSA private key Dechiffrement de toutes les données
Certificats TLS Clé privee .key Interception du trafic chiffre
Secrets CI/CD Deploy keys, registry credentials Accès à l'infrastructure

Détection de fuites : gitleaks et trufflehog

gitleaks

Analyse l'historique Git complet à la recherche de patterns de secrets.

# Installation
brew install gitleaks

# Scanner le depot courant (tous les commits)
gitleaks detect --source . --verbose

# Scanner uniquement les fichiers staged (pre-commit hook)
gitleaks protect --staged

# Integrer dans la CI (GitHub Actions)
# .github/workflows/security.yml
# .github/workflows/gitleaks.yml
name: Gitleaks
on: [push, pull_request]
jobs:
  scan:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
        with:
          fetch-depth: 0  # historique complet
      - uses: gitleaks/gitleaks-action@v2
        env:
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

trufflehog

Specialise dans la détection de secrets avec entropie et vérification live.

# Scanner un depot GitHub
trufflehog github --repo https://github.com/org/repo

# Scanner localement avec verification des secrets actifs
trufflehog git file://. --only-verified

# Scanner une image Docker
trufflehog docker --image python:3.11

Pre-commit hook

Installer gitleaks comme hook pre-commit empêche les commits accidentels :

# .pre-commit-config.yaml
repos:
  - repo: https://github.com/gitleaks/gitleaks
    rev: v8.18.0
    hooks:
      - id: gitleaks

Variables d'environnement : bonnes pratiques

Fichier .env en développement

# .env (jamais commite)
DATABASE_URL=postgres://user:pass@localhost/mydb
OPENAI_API_KEY=sk-proj-...
JWT_SECRET=un-secret-long-et-aleatoire

# .env.example (commite — template sans valeurs)
DATABASE_URL=postgres://user:pass@localhost/mydb
OPENAI_API_KEY=
JWT_SECRET=
# .gitignore — toujours exclure
.env
.env.local
.env.*.local
*.key
*.pem
secrets/

Charger les variables en Python

# VULNERABLE — hard-coded dans le code source
API_KEY = "sk-proj-abc123..."

# SECURISE — depuis l'environnement
import os
from dotenv import load_dotenv

load_dotenv()  # charge .env en dev, ignoré en prod si non present

API_KEY = os.environ["OPENAI_API_KEY"]  # leve une exception si absent
# ou avec valeur par defaut
DB_HOST = os.environ.get("DB_HOST", "localhost")

HashiCorp Vault

Solution de référence pour la gestion centralisee des secrets en production.

flowchart LR
    App["Application"] -->|"auth (AppRole/k8s)"| Vault["HashiCorp Vault"]
    Vault -->|"token temporaire"| App
    App -->|"lire secret"| Vault
    Vault -->|"secret + TTL"| App
    Vault --> Audit["Audit log"]
    Admin["Operateur"] -->|"ecrire/rotater secrets"| Vault

Exemple d'intégration Python

import hvac

def get_db_credentials():
    client = hvac.Client(url="https://vault.internal:8200")

    # Authentification via AppRole (recommande pour les applications)
    client.auth.approle.login(
        role_id=os.environ["VAULT_ROLE_ID"],
        secret_id=os.environ["VAULT_SECRET_ID"]
    )

    secret = client.secrets.kv.v2.read_secret_version(
        path="database/myapp",
        mount_point="secret"
    )
    return secret["data"]["data"]  # {"username": "...", "password": "..."}

Gestionnaires de secrets cloud

Service Provider Cas d'usage principal
AWS Secrets Manager AWS Rotation automatique RDS, rotation Lambda
GCP Secret Manager Google Intégration Cloud Run, GKE Workload Identity
Azure Key Vault Azure Certificats TLS, secrets app, clés de chiffrement
Doppler SaaS Sync multi-environnements, simple à intégrer

GCP Secret Manager — exemple

from google.cloud import secretmanager

def get_secret(project_id: str, secret_id: str, version: str = "latest") -> str:
    client = secretmanager.SecretManagerServiceClient()
    name = f"projects/{project_id}/secrets/{secret_id}/versions/{version}"
    response = client.access_secret_version(request={"name": name})
    return response.payload.data.decode("utf-8")

# Utilisation
db_password = get_secret("my-project", "db-password")

Stratégies de rotation

La rotation limite la fenêtre d'exposition en cas de fuite non détectée.

sequenceDiagram
    participant Scheduler
    participant SecretsManager
    participant Database
    participant App

    Scheduler->>SecretsManager: Declencher rotation
    SecretsManager->>Database: Creer nouveau mot de passe
    SecretsManager->>SecretsManager: Stocker nouveau secret (version N+1)
    App->>SecretsManager: Lire secret (version latest)
    SecretsManager-->>App: Retourner version N+1
    SecretsManager->>Database: Revoquer ancien mot de passe

Bonnes pratiques de rotation

  • Rotation automatique toutes les 30 a 90 jours pour les secrets long-terme
  • Tokens d'accès avec TTL court (1h a 24h) et renouvellement automatique
  • Rotation immédiate après chaque départ d'un membre de l'équipe
  • Alertes si un secret n'a pas été utilisé depuis sa rotation (potentiellement oublie)

Rotation sans downtime

Pour une rotation sans interruption : créer la nouvelle credential, mettre à jour les applications, valider, puis revoquer l'ancienne. Certains secrets managers (AWS) gèrent ce processus automatiquement.

Checklist secrets

  • .env dans .gitignore et jamais commite
  • .env.example avec toutes les variables (valeurs vides) commite
  • gitleaks ou trufflehog configuré en pre-commit hook
  • Scan de secrets dans la CI sur chaque PR
  • Secrets de production dans un gestionnaire de secrets (pas dans les variables CI en clair)
  • Rotation automatique activee pour les secrets critiques
  • Audit log des accès aux secrets active

Chapitre suivant : Supply chain — sécuriser vos dépendances et votre chaîne de build.