Le bouton « Don’t Ask Again » de Claude Code enregistre la commande exacte que vous avez approuvée sous forme de règle allow dans .claude/settings.local.json. Si cette commande contenait un mot de passe ou une clé API, le secret se retrouve désormais en clair dans votre dossier de projet, et si le fichier est commité, il devient public. La société de sécurité Apiiro a trouvé 1 122 fichiers de ce type sur GitHub public contenant 1 379 secrets réels. Voici comment vérifier vos propres dépôts en une seule commande, nettoyer le tout et éviter que cela ne se reproduise.
Ce qui s’est passé : les chiffres des découvertes d’Apiiro
Apiiro a fouillé GitHub public à la recherche de copies de .claude/settings.local.json, le fichier par projet dans lequel Claude Code enregistre vos approbations de permissions personnelles. L’entreprise en a trouvé 104 185 copies réparties sur 103 617 dépôts. Dans 1 122 d’entre eux se trouvait au moins un secret réel, soit 1 379 secrets distincts au total, selon le compte rendu de la recherche par iTnews.
| Type de secret | Nombre |
|---|---|
| Mots de passe de bases de données | 379 |
| Clés service-role Supabase | 122 |
| Connexions SSH de serveurs publics | 43 |
| Tokens GitHub, GitLab et npm | 42 |
| Clés AWS | 23 |
Lorsque Apiiro a élargi la recherche aux anciennes versions git du fichier, au .claude/settings.json partagé et aux transcriptions d’agents sauvegardées, le chiffre est monté à 2 539 secrets répartis sur 1 994 dépôts. Apiiro n’a pas testé si les identifiants fonctionnaient toujours, mais une organisation qu’elle a prévenue a confirmé qu’une clé était toujours active.
Ce sont les chiffres des scanners qui devraient vous inquiéter le plus. Sur les 1 122 fichiers contenant un secret réel, TruffleHog en a signalé 643 et gitleaks 564. 215 fichiers ont échappé aux deux. Ainsi, « nous utilisons un scanner de secrets » n’est pas la preuve que vous êtes à l’abri.
L’histoire a atteint la première place de Hacker News avec 582 points. Boris Cherny, qui dirige Claude Code chez Anthropic, a répondu dans le fil que Claude Code n’avait historiquement pas nettoyé les secrets et que l’équipe examine la question. Lisez la recherche originale d’Apiiro.
Comment « Don’t Ask Again » place les secrets dans un fichier
Lorsque Claude Code souhaite exécuter une commande Bash, il demande d’abord l’autorisation. Choisissez « Yes, and don’t ask again » et Claude Code écrit une approbation permanente dans .claude/settings.local.json sous forme de règle allow, comme le décrit la documentation des paramètres d’Anthropic. La règle enregistre le texte de la commande. Si la commande était celle-ci :
psql "postgresql://admin:Sup3rS3cret@db.example.com:5432/prod" -c "select count(*) from users"
alors votre fichier de paramètres contient désormais quelque chose comme ceci :
{
"permissions": {
"allow": [
"Bash(psql \"postgresql://admin:Sup3rS3cret@db.example.com:5432/prod\" -c \"select count(*) from users\")"
]
}
}
Le mot de passe se trouve dans la règle parce qu’il était dans la commande. Claude Code sauvegarde ce que vous avez approuvé, mot pour mot.

Pourquoi cela finit sur GitHub
Claude Code tente de garder ce fichier hors de git. La première fois qu’il écrit .claude/settings.local.json dans un dépôt qui ne l’ignore pas déjà, il ajoute **/.claude/settings.local.json à votre fichier global d’exclusions git. Cette protection a des failles :
- Vous avez créé le fichier à la main. La documentation le dit clairement : si vous avez créé le fichier vous-même, vous devez l’ajouter au
.gitignore. Selon l’interprétation de Cherny sur HN, les copies exposées avaient été créées manuellement puis commitées. - La règle d’ignore ne vit que sur une seule machine. Elle se trouve dans vos exclusions globales, et non dans le
.gitignoredu dépôt. Un collègue, une tâche CI ou un ordinateur neuf qui copie le dossier ne l’hérite pas. - Le fichier a été ajouté de force ou suivi avant que la règle n’existe.
git add -foutrepasse les règles d’ignore, et une fois qu’un fichier est suivi, les règles d’ignore ne s’appliquent plus à lui. - Le fichier partagé. Dans l’extension VS Code, la carte d’approbation vous permet de choisir le fichier de destination, y compris le
.claude/settings.jsoncommité. Une règle enregistrée là s’applique à tout le monde.
Vérifier vos dépôts en une seule commande
Commencez par le dépôt dans lequel vous vous trouvez. Ceci vous indique si le fichier est actuellement suivi et s’il a déjà été commité :
git ls-files | grep -E '(^|/)\.claude/settings(\.local)?\.json$'
git log --all --name-only --format= | grep -E '\.claude/settings(\.local)?\.json$' | sort -u
Si la première ligne affiche quelque chose, le fichier est dans votre arborescence actuelle. Si la deuxième affiche quelque chose, il est dans votre historique, même si vous l’avez supprimé par la suite.
Pour baliser tous les dépôts sous un dossier d’un coup :
find ~/code -path '*/.claude/settings.local.json' -exec sh -c \
'cd "$(dirname "$1")/.." && git ls-files --error-unmatch .claude/settings.local.json >/dev/null 2>&1 && echo "TRACKED: $PWD"' _ {} \;
Pour une organisation GitHub, le CLI GitHub peut rechercher du code par nom de fichier :
gh search code permissions --owner your-org --filename settings.local.json
Ensuite, examinez le contenu de chaque fichier trouvé. Comme les scanners ont manqué 19 % des fichiers fuyés, lisez vous-même les règles plutôt que de vous fier à un scan au vert :
grep -nE 'Bash\(' .claude/settings.local.json | grep -iE 'pass|token|key|secret|://[^/]*:[^@]*@'
Une chaîne de connexion avec user:password@, un en-tête Authorization: Bearer, un -p suivi d’un mot de passe littéral, ou tout ce qui commence par sk-, ghp_, AKIA ou eyJ est un identifiant. Exécutez gitleaks sur le dépôt comme deuxième passe, et non comme la seule.
Comment corriger un fichier de paramètres fui
L’ordre compte. La rotation vient en premier, car supprimer le fichier ne fait rien pour la copie déjà présente dans les forks, les clones et les caches.
- Effectuez la rotation de chaque identifiant que le fichier a jamais contenu. Consultez l’historique complet du fichier avec
git log -p --all -- .claude/settings.local.json, listez chaque secret qu’il contient, et révoquez chacun auprès de son fournisseur. Les recommandations d’Apiiro placent cette étape en premier. - Cessez de suivre le fichier et ignorez-le dans le dépôt lui-même :
git rm --cached .claude/settings.local.json
echo '.claude/settings.local.json' >> .gitignore
git add .gitignore && git commit -m "Stop tracking Claude Code local settings"
git check-ignore -v .claude/settings.local.json
La dernière commande devrait afficher la ligne correspondante du .gitignore. Une règle dans le dépôt protège tous les clones.
- Nettoyez l’historique si le dépôt est public ou largement partagé. git-filter-repo supprime le fichier de chaque commit :
git filter-repo --invert-paths --path .claude/settings.local.json
git push --force --all
Ceci réécrit l’historique pour tout le monde, prévenez donc votre équipe au préalable. Cela n’atteint pas non plus les forks : c’est donc un nettoyage, pas un substitut à l’étape 1.
- Nettoyez aussi le fichier local. Ouvrez
.claude/settings.local.json, supprimez toute règle contenant un secret littéral, et remplacez-la par un motif (section suivante). - Activez la protection push. La protection push du secret scanning de GitHub bloque les pushs contenant des formats de secrets reconnus. Elle ne détectera pas tout, comme le montrent les 215 fichiers manqués, mais elle stoppe les formats de tokens courants.
Éviter que cela ne se reproduise
La solution est simple à énoncer : ne placez jamais un secret littéral dans une commande exécutée par votre agent, et approuvez des motifs plutôt que des commandes exactes.

Référencez les secrets, ne les tapez pas. Le shell développe une variable au moment de l’exécution, mais la règle allow stocke le texte tel qu’écrit. Ainsi, psql "$DATABASE_URL" enregistre $DATABASE_URL dans la règle, et non le mot de passe :
{
"permissions": {
"allow": ["Bash(psql \"$DATABASE_URL\" *)", "Bash(npm run test *)"],
"deny": ["Read(./.env)", "Read(./.env.*)"]
}
}
Les règles deny sont tirées directement de la documentation des paramètres d’Anthropic ; elles empêchent Claude Code de lire vos fichiers .env, de sorte qu’une clé ne puisse pas non plus être copiée de là vers une commande.
Gardez des règles étroites. Les commentateurs de HN citant la recherche ont indiqué que 5 % des fichiers autorisaient toute commande shell et que 43 % contenaient des règles d’interpréteur telles que Bash(python:*). Une règle de ce type permet à l’agent d’exécuter n’importe quoi via Python ; c’est donc une règle qui autorise tout, avec des étapes supplémentaires.
Envisagez le mode auto et un bac à sable. Cherny a recommandé le mode auto plutôt que des règles de permission écrites à la main et a déclaré qu’Anthropic avait construit un bac à sable open source. Plusieurs commentateurs ont souligné que le mode auto est un classifieur, et non une frontière de sécurité ; associez-le donc aux bonnes pratiques ci-dessus.
Tenez les agents à l’écart des secrets de production. La clé la plus sûre est celle que l’agent ne voit jamais. Nous avons couvert les patterns pour cela dans comment permettre aux agents IA d’utiliser des clés API sans les voir, et ce que font les attaquants avec les clés IA fuiées dans clés API IA volées et LLMjacking.
Permettez à votre agent de code d’appeler des API sans taper de clés, grâce à Apidog CLI
Une façon courante pour une clé de se retrouver dans une commande approuvée est un appel API rapide : curl -H "Authorization: Bearer sk-..." pour vérifier un endpoint. Vous pouvez plutôt confier cette tâche à Apidog CLI. La clé réside dans une variable d’environnement Apidog, votre scénario de test la référence sous la forme {{API_KEY}}, et la commande que votre agent exécute ne contient que des IDs de projet, de scénario et d’environnement. Il n’y a aucun secret à sauvegarder dedans.
Configurez-le une fois, dans votre propre terminal plutôt que via l’agent, afin que votre token d’accès ne passe jamais par une approbation :
npm install -g apidog-cli@latest
apidog auth login
npx -y skills add https://apidog.com # pick Claude Code when prompted
Donnez ensuite un prompt à Claude Code :
List the environments in Apidog project 123456, then run test scenario 7890
against the staging environment and summarise any failed assertions.
The API key is stored in that environment as {{API_KEY}}. Never pass a key,
token or password on the command line, and never use --env-var for secrets.
L’agent exécute des commandes comme celles-ci, sans danger à approuver avec « Don’t Ask Again » :
apidog environment list --project 123456
apidog run -t 7890 --project 123456 -e <envId> -r cli,json
Deux mises en garde honnêtes. Premièrement, apidog run utilise la valeur partagée de la variable, qui est synchronisée avec Apidog et visible par les membres du projet ; stockez-y donc une clé de test à périmètre limité, et non une clé root de production. Si vous préférez garder les valeurs sur le disque, apidog run accepte aussi --variables <path> ; pointez-le vers un fichier en dehors du dépôt. Deuxièmement, l’option --env-var "key=value" existe pour passer des variables en ligne de commande, et c’est exactement le pattern qui fuit ; dites donc à votre agent de ne pas l’utiliser pour des secrets.
Les équipes sur le plan Enterprise peuvent également extraire des secrets de HashiCorp Vault, Azure Key Vault ou AWS Secrets Manager avec Apidog Vault Secrets, et le Secret Scanner du SaaS Enterprise signale les clés enregistrées dans les requêtes, scripts et variables Apidog. Il ne scanne pas les dépôts GitHub, gardez donc aussi les vérifications ci-dessus. Pour la procédure complète de configuration, consultez comment utiliser Apidog CLI dans Claude Code et la gestion des environnements et variables secrètes dans Apidog. Le plan gratuit d’Apidog couvre jusqu’à 4 utilisateurs.
FAQ
Le settings.local.json de Claude Code est-il ignoré par git par défaut ?
En partie. Lorsque Claude Code crée le fichier dans un dépôt git, il ajoute **/.claude/settings.local.json à vos exclusions git globales. Cela ne protège que votre machine, et cela ne s’applique pas si vous avez créé le fichier à la main ou l’avez ajouté de force. Ajoutez aussi la ligne au .gitignore propre au dépôt.
Supprimer le fichier retire-t-il la clé fuiée ?
Non. La clé reste dans l’historique git, dans les forks et dans chaque clone réalisé pendant qu’elle était publique. Effectuez d’abord la rotation de la clé, puis cessez de suivre le fichier et nettoyez l’historique avec git-filter-repo.
gitleaks ou TruffleHog détecteront-ils ces fuites ?
Pas de manière fiable. Dans l’échantillon d’Apiiro, 215 des 1 122 fichiers contenant un secret réel ont échappé aux deux outils. Exécutez un scanner, puis lisez vous-même les règles Bash(...) du fichier.
Est-ce un problème de modèle ou un problème de Claude Code ?
Apiiro l’a reproduit avec Opus 5.5 et Fable 5.1 et l’a qualifié de propriété de Claude Code, et non du modèle. L’approbation stocke le texte de la commande, quel que soit le modèle qui l’a écrite.
Comment approuver des commandes en toute sécurité dans Claude Code ?
Approuvez des motifs tels que Bash(npm run test *) et référencez les secrets sous forme de variables d’environnement comme $DATABASE_URL. Ajoutez des règles deny pour Read(./.env) et Read(./.env.*).
