Module B04
Secrets & Variables d'env
Gérez les secrets correctement — aucun secret ne doit jamais se retrouver dans le code source.
01 Qu'est-ce qu'un secret ?
Un secret est toute donnée qui donnerait accès à des ressources protégées si elle était compromise. Les secrets doivent être traités comme des mots de passe.
| Type de secret | Exemples | Impact si exposé |
|---|---|---|
| Clés d'API tierces | Stripe, SendGrid, Twilio, Google Maps | Frais non autorisés, abus de service |
| Secrets JWT | JWT_SECRET, REFRESH_SECRET | Forge de tokens, usurpation d'identité |
| Mots de passe BDD | DB_PASSWORD, REDIS_URL | Accès complet aux données |
| Clés privées | Certificats TLS, SSH keys, PGP | Accès serveurs, déchiffrement |
| OAuth credentials | CLIENT_SECRET, GITHUB_SECRET | Usurpation d'application OAuth |
| Tokens Cloud | AWS_SECRET_ACCESS_KEY, GCP key | Accès infrastructure complète |
🚨 GitHub scanne automatiquement les commits pour certains patterns de secrets et notifie les fournisseurs (Stripe, AWS…). Votre clé peut être révoquée en quelques minutes.
02 Erreurs classiques d'exposition
// ❌ Hardcoded dans le code source const stripe = require('stripe')('sk_live_abc123...'); // Dans git pour toujours ! // ❌ Dans les logs console.log('Connecting with password: ' + process.env.DB_PASSWORD); // ❌ Dans les query params (historique navigateur, logs nginx) fetch(`/api/data?api_key=${apiKey}`); // ❌ Dans un fichier .env commité // git add .env → "oh j'ai oublié de le mettre dans .gitignore" // ❌ Dans les variables d'erreur retournées au client app.use((err, req, res, next) => { res.json({ error: err.message, stack: err.stack }); // Ne jamais exposer en prod ! });
03 .env avec dotenv — bonnes pratiques
# .env (JAMAIS commité) NODE_ENV=development PORT=3000 DATABASE_URL=postgresql://user:password@localhost/mydb JWT_SECRET=super-long-random-secret-at-least-32-chars STRIPE_SECRET_KEY=sk_test_... REDIS_URL=redis://localhost:6379 # .env.example (commité — documentation sans valeurs) NODE_ENV= PORT= DATABASE_URL=postgresql://user:password@host/dbname JWT_SECRET= # Générer avec: node -e "console.log(require('crypto').randomBytes(32).toString('hex'))" STRIPE_SECRET_KEY= # Depuis https://dashboard.stripe.com/apikeys REDIS_URL=
// Chargement dans l'application require('dotenv').config(); // À mettre en PREMIER, avant tous les imports // Valider que les secrets sont présents au démarrage const REQUIRED_ENV = ['DATABASE_URL', 'JWT_SECRET', 'STRIPE_SECRET_KEY']; for (const key of REQUIRED_ENV) { if (!process.env[key]) { console.error(`Variable d'env manquante: ${key}`); process.exit(1); } }
.gitignore obligatoire
# .gitignore
.env
.env.local
.env.*.local
*.pem
*.key
secrets/04 Variables d'env en production
En production, les secrets ne doivent jamais être dans des fichiers — ils sont injectés par la plateforme de déploiement.
| Plateforme | Méthode | Accès |
|---|---|---|
| Vercel | Settings → Environment Variables | Dashboard ou CLI |
| Railway | Project → Variables | Dashboard ou railway env |
| Heroku | Config Vars (Settings) | heroku config:set KEY=value |
| AWS EC2 | AWS Secrets Manager + IAM | SDK aws-sdk |
| Render | Environment → Secret Files | Dashboard |
| GitHub Actions | Settings → Secrets → Actions | ${{ secrets.KEY }} |
// Pas de dotenv en production — les env vars sont injectées directement if (process.env.NODE_ENV !== 'production') { require('dotenv').config(); }
05 Solutions avancées — Vault, Secrets Manager
| Solution | Cas d'usage | Avantages |
|---|---|---|
| HashiCorp Vault | Entreprises, multi-cloud | Rotation automatique, audit, dynamic secrets |
| AWS Secrets Manager | AWS natif | Rotation automatique RDS, intégration IAM |
| GCP Secret Manager | GCP natif | Versioning, IAM granulaire |
| Azure Key Vault | Azure natif | HSM, certificats TLS |
| Doppler / Infisical | Dev teams agiles | Interface simple, sync env vars multi-env |
Les 10 règles d'or
- 1.Jamais de secrets dans le code source (même dans les commentaires)
- 2..env dans .gitignore AVANT le premier commit
- 3.Toujours fournir un .env.example sans valeurs réelles
- 4.Valider la présence des secrets au démarrage (fail fast)
- 5.Ne jamais logger les secrets — même partiellement
- 6.Rotation régulière des secrets (surtout après un départ)
- 7.Secrets différents par environnement (dev ≠ staging ≠ prod)
- 8.Utiliser des variables d'env plateforme en production
- 9.Auditer régulièrement avec des outils comme git-secrets, truffleHog
- 10.Si exposé accidentellement : révoquer immédiatement, ne pas juste modifier le code