Gestion des secrets avec Claude Code : de .env à la rotation en production
Guide pour sécuriser .env, secrets CI/CD, coffres cloud, logs masqués et limites Claude Code.
Les clés API, URL de base de données, OAuth client secrets et identifiants de déploiement cloud sont indispensables à une vraie application. Ce sont aussi les valeurs qui restent dans l’historique Git, les logs CI, les captures d’écran, les tickets, les README et les brouillons d’articles après un copier-coller imprudent. Quand vous utilisez Claude Code pour déboguer, migrer, déployer ou documenter, la règle doit être explicite : Claude Code peut aider à construire le système de sécurité, mais il ne doit pas voir, imprimer, stocker ni réutiliser les vrais secrets.
La gestion des secrets ne se limite pas à cacher des mots de passe. Elle consiste à séparer la configuration du code, distinguer local, développement, staging et production, appliquer le moindre privilège, valider la configuration au démarrage, masquer les logs et savoir faire une rotation avant qu’un incident n’oblige à improviser. Le principe Config de The Twelve-Factor App reste le bon point de départ : la configuration vient de l’environnement, pas du dépôt. En pratique, il faut aussi .gitignore, .env.example, un chargeur de configuration validé, des secrets CI/CD, un coffre cloud et une checklist de rotation.
flowchart LR
Dev["Local .env"] --> Loader["Validated config loader"]
CI["CI/CD secrets"] --> Deploy["Deployment runtime"]
Store["AWS / GCP / Azure secret store"] --> Deploy
Deploy --> App["Application process"]
App --> Logs["Redacted logs"]
1. Décider ce qui va où
L’erreur de débutant consiste à traiter toutes les variables d’environnement de la même façon. Le test est simple : si une fuite permet à quelqu’un de dépenser de l’argent, envoyer des emails, lire ou écrire des données, déployer du code ou usurper un utilisateur, c’est un secret. Une URL publique, un nom de feature flag ou un OAuth client ID sont généralement moins sensibles car ils ne donnent pas d’autorité seuls.
| Cas d’usage | Exemples | Développement local | Production |
|---|---|---|---|
| Email et API | SendGrid API key, Stripe secret key, GitHub token | Clés sandbox ou test dans .env | Injection depuis CI/CD secrets ou secret store |
| Base de données | DATABASE_URL, utilisateur, mot de passe | Utilisateur local ou dev uniquement | Droits lecture/écriture séparés et rotation |
| Déploiement cloud | Identifiants AWS/GCP/Azure | Éviter les clés longues en local | OIDC ou rôle dédié au déploiement |
| OAuth et webhooks | OAUTH_CLIENT_SECRET, webhook signing secret | App locale distincte | Secrets prod hors dépôt |
Le point important est la séparation des environnements. Ne réutilisez pas une clé Stripe de production en local. Ne mettez pas dans CI un token GitHub personnel avec accès large à l’organisation. Ne donnez pas de droits administrateur à une clé qui doit seulement déployer. C’est le moindre privilège : le bon périmètre, dans le bon environnement, pour une durée limitée si possible.
2. Committer la forme, jamais la valeur
.env est pratique en local, mais ne doit pas être committé. Le dépôt doit contenir .env.example, qui documente les noms, formats, sources et usages. Pour l’onboarding, associez-le au guide de gestion des variables d’environnement afin de réduire les questions répétitives.
# Local secrets
.env
.env.*
!.env.example
!.env.test.example
# Logs and generated output that may contain tokens
npm-debug.log*
yarn-debug.log*
coverage/
dist/
# .env.example - placeholders only, never real values
NODE_ENV=development
APP_BASE_URL=http://localhost:3000
# Use a local database user, not production credentials.
DATABASE_URL=postgres://app_user:replace-me@localhost:5432/app_dev
# Use test/sandbox keys for local development.
SENDGRID_API_KEY=SG.xxxxxx
STRIPE_SECRET_KEY=sk_test_xxxxxx
GITHUB_TOKEN=ghp_xxxxxx
# OAuth secrets must be separated by environment.
OAUTH_CLIENT_ID=local-client-id
OAUTH_CLIENT_SECRET=replace-me
# Deployment reads these from CI or a cloud secret store.
AWS_REGION=ap-northeast-1
DEPLOY_ROLE_ARN=arn:aws:iam::123456789012:role/app-deploy-dev
Quand Claude Code intervient, écrivez la limite : il peut lire .env.example, les manifests de déploiement, les scripts package et les noms de variables ; il ne peut pas ouvrir .env, copier des valeurs réelles dans le chat ni écrire des identifiants dans la documentation. Si une valeur réelle est nécessaire, vous la saisissez dans l’interface locale, CI ou secret store, et Claude Code ne connaît que le nom de variable.
3. Valider au démarrage et masquer les logs
Une application doit échouer vite si un secret manque ou n’a pas le bon format. Elle doit aussi éviter qu’un développeur imprime un token pendant le debug. Ce chargeur Node.js utilise dotenv et envalid pour valider l’environnement et fournit redactConfig pour les logs, health checks et sorties de support.
import { config as loadDotenv } from "dotenv";
import { cleanEnv, str, url } from "envalid";
const envFile = process.env.NODE_ENV === "test" ? ".env.test" : ".env";
loadDotenv({ path: envFile });
const secretKeyPattern = /(KEY|TOKEN|SECRET|PASSWORD|DATABASE_URL|PRIVATE)/i;
const env = cleanEnv(process.env, {
NODE_ENV: str({
choices: ["development", "test", "staging", "production"],
default: "development",
}),
APP_BASE_URL: url({ default: "http://localhost:3000" }),
DATABASE_URL: url(),
SENDGRID_API_KEY: str(),
STRIPE_SECRET_KEY: str(),
GITHUB_TOKEN: str(),
OAUTH_CLIENT_ID: str(),
OAUTH_CLIENT_SECRET: str(),
AWS_REGION: str({ default: "ap-northeast-1" }),
DEPLOY_ROLE_ARN: str(),
});
export function appConfig() {
return Object.freeze({
nodeEnv: env.NODE_ENV,
appBaseUrl: env.APP_BASE_URL,
databaseUrl: env.DATABASE_URL,
sendgridApiKey: env.SENDGRID_API_KEY,
stripeSecretKey: env.STRIPE_SECRET_KEY,
githubToken: env.GITHUB_TOKEN,
oauthClientId: env.OAUTH_CLIENT_ID,
oauthClientSecret: env.OAUTH_CLIENT_SECRET,
awsRegion: env.AWS_REGION,
deployRoleArn: env.DEPLOY_ROLE_ARN,
});
}
export function redactValue(key, value) {
if (!secretKeyPattern.test(key)) return value;
if (!value) return "<empty>";
const text = String(value);
if (text.length <= 8) return "<redacted>";
return `${text.slice(0, 4)}...${text.slice(-4)}`;
}
export function redactConfig(config) {
return Object.fromEntries(
Object.entries(config).map(([key, value]) => [key, redactValue(key, value)]),
);
}
if (process.argv[1] === new URL(import.meta.url).pathname) {
console.log(redactConfig(appConfig()));
}
Un échec fréquent consiste à ajouter console.log(process.env) pendant un incident, puis coller le log CI dans un ticket ou une conversation. Si vous demandez ensuite à Claude Code de résumer ces logs bruts, il peut réintroduire des secrets dans des tests, documents ou articles. Masquez d’abord, demandez de l’aide ensuite. Même règle pour les captures : recadrez ou floutez les tokens avant tout upload.
4. Donner à Claude Code des limites explicites
Claude Code a rarement besoin des valeurs réelles. Il a besoin des noms, formats, erreurs déjà masquées et objectifs de permissions. Collez ce bloc au début des tâches de sécurité, déploiement ou debug.
You may inspect .env.example, package.json, deployment manifests, and secret names.
Do not open, print, summarize, store, or copy .env, CI/CD secret values, cloud credentials, production dumps, or screenshots containing tokens.
When you need a value, ask me to set it outside chat and confirm only the variable name.
If a secret appears in command output, stop, redact it, and report which file or command exposed it.
Before changing permissions, explain the least-privilege scope and ask for approval.
Do not paste real secrets into prompts, logs, documentation, code comments, tests, tickets, or articles.
Limitez aussi les commandes. printenv, cat .env, les CLI cloud révélant des identifiants, les dumps complets de logs CI et les captures d’écran doivent demander confirmation. Avec .env.example, les types, des erreurs masquées et la documentation officielle, Claude Code peut corriger la majorité des problèmes sans voir les valeurs.
5. Utiliser CI/CD secrets et coffres cloud avec intention
Une séparation saine : .env pour le local, CI/CD secrets pour les pipelines, un coffre cloud pour le runtime de production. Sur AWS, utilisez AWS Secrets Manager. Sur Google Cloud, Secret Manager. Sur Azure, Key Vault. Dans GitHub, activez secret scanning pour détecter rapidement les tokens exposés.
name: deploy
on:
workflow_dispatch:
jobs:
deploy:
runs-on: ubuntu-latest
permissions:
contents: read
id-token: write
env:
NODE_ENV: production
AWS_REGION: ap-northeast-1
steps:
- uses: actions/checkout@v4
- name: Validate required secret names
run: test -n "${{ secrets.DEPLOY_ROLE_ARN }}" && test -n "${{ secrets.DATABASE_URL }}"
- name: Deploy without echoing secrets
env:
DATABASE_URL: ${{ secrets.DATABASE_URL }}
DEPLOY_ROLE_ARN: ${{ secrets.DEPLOY_ROLE_ARN }}
run: npm run deploy
Le piège CI classique est “on va juste faire un echo pour voir”. GitHub Actions masque beaucoup de secrets exacts, mais pas toujours les valeurs dérivées, URL encodées, JSON, captures ou valeurs non enregistrées comme secrets. Demandez à Claude Code d’afficher les noms de variables et étapes de validation, pas les valeurs. S’il propose des permissions larges, exigez une justification et réduisez le périmètre.
6. Prévoir la rotation avant l’urgence
La rotation doit être une maintenance normale, pas seulement une réponse à incident. Les clés SendGrid, Stripe, GitHub, mots de passe DB, OAuth client secrets, webhook signing secrets et politiques de confiance cloud doivent avoir un owner, un environnement, une liste de consommateurs, une date de dernière rotation et une prochaine revue.
## Secret rotation checklist
- [ ] Identify owner, environment, consumers, and business impact.
- [ ] Create a new secret with the smallest required scope.
- [ ] Store it in CI/CD secrets or the cloud secret store.
- [ ] Deploy one service or job with the new value.
- [ ] Confirm logs and metrics without printing the secret.
- [ ] Revoke the old secret.
- [ ] Scan Git history, tickets, docs, screenshots, and chat snippets.
- [ ] Record the rotation date and next review date.
Claude Code est utile pour transformer cette liste en issue template, runbook ou plan de migration. Ne lui donnez pas l’ancienne ou la nouvelle valeur. Demandez plutôt : “Trouve toutes les références à SENDGRID_API_KEY et prépare un plan sûr pour passer à la clé v2.”
7. Vérifier les échecs avant publication
Stoppez publication ou déploiement si l’un de ces points est vrai :
.envou.env.productiona été committé et la clé exposée n’a pas été révoquée.- Captures, logs CI, rapports d’erreur ou exemples d’article contiennent tokens, URL DB ou OAuth secrets.
- Une clé cloud a des droits administrateur alors qu’un rôle de déploiement suffit.
- Des identifiants production Stripe, SendGrid, DB ou GitHub sont réutilisés en local.
- Un OAuth client secret ou webhook signing secret n’a ni owner ni runbook de rotation.
- Une IA a reçu de vraies valeurs puis les a réutilisées dans README, tests, tickets ou brouillons.
Les incidents viennent souvent de trous de processus. Utilisez la checklist d’audit sécurité, relisez le guide des échecs sécurité, connectez cela au guide de développement API et, pour SendGrid ou l’email transactionnel, consultez l’article sur l’automatisation email.
8. Déployer la pratique en équipe
Ne commencez pas par migrer tous les services vers un coffre cloud. Choisissez une application et faites fonctionner toute la chaîne : .gitignore, .env.example, chargeur validé, logs masqués, CI/CD secrets, coffre de production et registre de rotation. Ensuite migrez les types récurrents : SendGrid, Stripe, GitHub token, DATABASE_URL, OAuth client secret et identifiants de déploiement.
Les formations et missions de conseil ClaudeCodeLab travaillent sur la forme réelle de votre dépôt, sans collecter les secrets réels. Nous définissons ce que Claude Code peut inspecter, dessinons les limites CI/CD secrets, activons GitHub secret scanning, planifions les coffres AWS/GCP/Azure et laissons des prompts et runbooks réutilisables. L’équipe peut ainsi les appliquer en revue de code dès le lendemain.
En résumé, gérer les secrets ne consiste pas seulement à cacher des chaînes. Il faut séparer valeurs et code, isoler les environnements, valider au démarrage, masquer les logs, réduire les permissions et pratiquer la rotation. Claude Code peut aider à bâtir et vérifier ce système, mais ne doit pas devenir un autre endroit où l’on copie des secrets.
Après test dans l’application Node.js d’exemple de Masa, le chargeur a détecté les valeurs manquantes, redactConfig a empêché l’URL de base de données et les clés API d’apparaître dans les logs CI, et le workflow de déploiement n’avait plus besoin de permissions write larges. La surprise venait d’une ancienne capture où une clé de test Stripe était visible ; elle a été réémise avant publication. La leçon : inspecter logs, images et brouillons avec la même méfiance que le code source.
PDF gratuit: cheatsheet Claude Code
Saisissez votre email et téléchargez une page avec commandes, habitudes de review et workflow sûr.
Nous protégeons vos données et n'envoyons pas de spam.
À propos de l'auteur
Masa
Ingénieur spécialisé dans les workflows pratiques avec Claude Code.
Articles liés
Claude Code Harness Smoke Test : boucle de preuve de 15 minutes avant de faire confiance à un agent
Un contrôle Claude Code pour cadrer portée, zones interdites, commandes de preuve, URL publique et CTA revenus.
Échelle de sécurité des permissions Claude Code
Passer du read-only aux éditions limitées, preuves et checks de déploiement sans perdre le contrôle.
Claude Code Small PR Proof Pack : rendre les petits changements reviewables
Un pack de preuve pour PR Claude Code : diff, vérifications, URL publique, CTA et rollback.