O botão "Não perguntar novamente" do Claude Code salva o comando exato que você aprovou como uma regra de permissão no arquivo .claude/settings.local.json. Se esse comando continha uma senha ou chave de API, o segredo agora está em texto simples na pasta do seu projeto — e se o arquivo for commitado, ele se torna público. A empresa de segurança Apiiro encontrou 1.122 desses arquivos no GitHub público contendo 1.379 segredos reais. Veja como verificar seus repositórios com um único comando, fazer a limpeza e impedir que isso aconteça novamente.
O que aconteceu: as descobertas da Apiiro em números
A Apiiro pesquisou no GitHub público cópias do .claude/settings.local.json, o arquivo por projeto em que o Claude Code armazena suas aprovações pessoais de permissão. Encontrou 104.185 cópias em 103.617 repositórios. Em 1.122 delas havia pelo menos um segredo real — 1.379 segredos distintos no total, segundo o relato do iTnews sobre a pesquisa.
| Tipo de segredo | Quantidade |
|---|---|
| Senhas de banco de dados | 379 |
| Chaves de service-role do Supabase | 122 |
| Credenciais SSH de servidores públicos | 43 |
| Tokens do GitHub, GitLab e npm | 42 |
| Chaves da AWS | 23 |
Quando a Apiiro ampliou a busca para versões anteriores do arquivo no histórico do git, o .claude/settings.json compartilhado e transcripts de agentes salvos, o número subiu para 2.539 segredos em 1.994 repositórios. A Apiiro não testou se as credenciais ainda funcionavam, mas uma organização notificada confirmou que uma chave estava ativa.
Os números dos scanners são a parte que deve te preocupar mais. Dos 1.122 arquivos com um segredo real, o TruffleHog sinalizou 643 e o gitleaks sinalizou 564. 215 arquivos passaram despercebidos por ambos. Ou seja, "rodamos um scanner de segredos" não é prova de que você está limpo.
A história chegou ao topo do Hacker News com 582 pontos. Boris Cherny, que lidera o Claude Code na Anthropic, respondeu no tópico que o Claude Code historicamente não remove segredos e que a equipe está investigando o assunto. Leia a pesquisa original da Apiiro.
Como o "Não perguntar novamente" coloca segredos em um arquivo
Quando o Claude Code quer executar um comando Bash, ele pergunta antes. Ao escolher "Yes, and don't ask again", o Claude Code grava uma aprovação permanente no .claude/settings.local.json como uma regra allow, conforme descrito na documentação de configurações da Anthropic. A regra registra o texto do comando. Se o comando era este:
psql "postgresql://admin:Sup3rS3cret@db.example.com:5432/prod" -c "select count(*) from users"
então o seu arquivo de configurações agora contém algo assim:
{
"permissions": {
"allow": [
"Bash(psql \"postgresql://admin:Sup3rS3cret@db.example.com:5432/prod\" -c \"select count(*) from users\")"
]
}
}
A senha está na regra porque estava no comando. O Claude Code salva o que você aprovou, palavra por palavra.

Por que isso acaba no GitHub
O Claude Code tenta manter esse arquivo fora do git. Na primeira vez que ele grava o .claude/settings.local.json em um repositório que ainda não o ignora, ele adiciona **/.claude/settings.local.json ao arquivo global de exclusões do git. Essa proteção tem brechas:
- Você criou o arquivo manualmente. A documentação diz claramente: se você criou o arquivo por conta própria, precisa adicioná-lo ao
.gitignore. A leitura de Cherny no HN foi que as cópias expostas foram criadas manualmente e depois commitadas. - A regra de ignore vive em uma única máquina. Ela está nas suas exclusões globais, não no
.gitignoredo repositório. Um colega de equipe, um job de CI ou um notebook novo que copia a pasta não herda essa configuração. - O arquivo foi adicionado à força ou rastreado antes da regra existir. O
git add -fsobrepõe regras de ignore e, uma vez que um arquivo é rastreado, as regras de ignore deixam de se aplicar a ele. - O arquivo compartilhado. Na extensão do VS Code, o cartão de aprovação permite escolher o arquivo de destino, incluindo o
.claude/settings.jsoncommitado. Uma regra salva ali vai para todos.
Verifique seus repositórios com um único comando
Comece pelo repositório em que você está. Isto diz se o arquivo está rastreado agora e se ele já foi commitado alguma vez:
git ls-files | grep -E '(^|/)\.claude/settings(\.local)?\.json$'
git log --all --name-only --format= | grep -E '\.claude/settings(\.local)?\.json$' | sort -u
Se a primeira linha imprimir algo, o arquivo está na sua árvore atual. Se a segunda imprimir algo, ele está no seu histórico, mesmo que você o tenha excluído depois.
Para varrer todos os repositórios sob uma pasta de uma só vez:
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"' _ {} \;
Para uma organização no GitHub, a GitHub CLI pode buscar código por nome de arquivo:
gh search code permissions --owner your-org --filename settings.local.json
Depois, examine o conteúdo de qualquer arquivo que encontrar. Como os scanners perderam 19% dos arquivos vazados, leia as regras você mesmo em vez de confiar em uma varredura "verde":
grep -nE 'Bash\(' .claude/settings.local.json | grep -iE 'pass|token|key|secret|://[^/]*:[^@]*@'
Uma string de conexão com user:password@, um cabeçalho Authorization: Bearer, um -p seguido de uma senha literal, ou qualquer coisa que comece com sk-, ghp_, AKIA ou eyJ é uma credencial. Rode o gitleaks no repositório como uma segunda verificação, não como a única.
Como corrigir um arquivo de configurações vazado
A ordem importa. A rotação vem primeiro, porque apagar o arquivo não resolve nada quanto à cópia que já está em forks, clones e caches.
- Rotate todas as credenciais que o arquivo já conteve. Verifique o histórico completo do arquivo com
git log -p --all -- .claude/settings.local.json, liste todos os segredos nele e revogue cada um junto ao seu provedor. A orientação da Apiiro coloca esta etapa em primeiro lugar. - Remova o arquivo do rastreamento e ignore-o no próprio repositório:
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
O último comando deve imprimir a linha correspondente do .gitignore. Uma regra no repositório protege todos os clones.
- Limpe o histórico se o repositório for público ou amplamente compartilhado. O git-filter-repo remove o arquivo de todos os commits:
git filter-repo --invert-paths --path .claude/settings.local.json
git push --force --all
Isso reescreve o histórico para todos, então avise sua equipe antes. Também não alcança os forks, então é uma limpeza, não um substituto para a etapa 1.
- Limpe também o arquivo local. Abra o
.claude/settings.local.json, exclua qualquer regra que contenha um segredo literal e substitua-a por um padrão (seção seguinte). - Ative a proteção de push. A proteção de push do secret scanning do GitHub bloqueia pushes que contenham formatos de segredos reconhecidos. Ela não pegará tudo, como mostram os 215 arquivos perdidos, mas interrompe os formatos de token comuns.
Evite que aconteça novamente
A solução é simples de enunciar: nunca coloque um segredo literal em um comando que seu agente executa, e aprove padrões em vez de comandos exatos.

Referencie segredos, não os digite. O shell expande uma variável em tempo de execução, mas a regra allow armazena o texto como foi escrito. Então psql "$DATABASE_URL" salva $DATABASE_URL na regra, não a senha:
{
"permissions": {
"allow": ["Bash(psql \"$DATABASE_URL\" *)", "Bash(npm run test *)"],
"deny": ["Read(./.env)", "Read(./.env.*)"]
}
}
As regras deny vêm diretamente da documentação de configurações da Anthropic; elas impedem que o Claude Code leia seus arquivos .env, assim uma chave também não pode ser colada de lá em um comando.
Mantenha as regras restritas. Comentadores do HN citando a pesquisa disseram que 5% dos arquivos permitiam qualquer comando de shell e 43% tinham regras de interpretador como Bash(python:*). Uma regra assim permite que o agente execute qualquer coisa via Python, ou seja, é uma regra de permitir tudo com etapas extras.
Considere o modo auto e um sandbox. Cherny recomendou o modo auto em vez de regras de permissão escritas à mão e disse que a Anthropic construiu um sandbox open-source. Vários comentadores apontaram que o modo auto é um classificador, não uma fronteira de segurança, então combine-o com os hábitos acima.
Mantenha os agentes longe dos segredos de produção. A chave mais segura é aquela que o agente nunca vê. Cobrimos os padrões para isso em como permitir que agentes de IA usem chaves de API sem vê-las, e o que invasores fazem com chaves de IA vazadas em chaves de API de IA roubadas e LLMjacking.
Deixe seu agente de programação chamar APIs sem digitar chaves, usando o Apidog CLI
Uma forma comum de uma chave parar em um comando aprovado é uma chamada rápida de API: curl -H "Authorization: Bearer sk-..." para verificar um endpoint. Em vez disso, você pode delegar essa tarefa ao Apidog CLI. A chave fica em uma variável de ambiente do Apidog, seu cenário de teste a referencia como {{API_KEY}}, e o comando que seu agente executa contém apenas IDs de projeto, cenário e ambiente. Não há nenhum segredo nele para ser salvo.
Configure uma única vez, no seu próprio terminal em vez de pelo agente, para que seu token de acesso nunca passe por uma aprovação:
npm install -g apidog-cli@latest
apidog auth login
npx -y skills add https://apidog.com # pick Claude Code when prompted
Depois, dê ao Claude Code um único prompt:
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.
O agente executa comandos como estes, que são seguros para aprovar com "Não perguntar novamente":
apidog environment list --project 123456
apidog run -t 7890 --project 123456 -e <envId> -r cli,json
Duas ressalvas honestas. Primeiro, o apidog run usa o valor compartilhado da variável, que é sincronizado com o Apidog e visível para os membros do projeto, então guarde ali uma chave de teste com escopo limitado, não uma chave root de produção. Se preferir manter os valores no disco, o apidog run também aceita --variables <path>; aponte para um arquivo fora do repositório. Segundo, a flag --env-var "key=value" existe para passar variáveis na linha de comando, e esse é exatamente o padrão que vaza, então diga ao seu agente para não usá-la para segredos.
Equipes no plano Enterprise também podem buscar segredos do HashiCorp Vault, Azure Key Vault ou AWS Secrets Manager com o Apidog Vault Secrets, e o Enterprise SaaS Secret Scanner sinaliza chaves salvas em requisições, scripts e variáveis do Apidog. Ele não faz varredura em repositórios do GitHub, então mantenha também as verificações acima. Para o passo a passo completo da configuração, veja como usar o Apidog CLI no Claude Code e como gerenciar ambientes e variáveis secretas no Apidog. O plano Free do Apidog cobre até 4 usuários.
FAQ
O settings.local.json do Claude Code é ignorado pelo git por padrão?
Parcialmente. Quando o Claude Code cria o arquivo em um repositório git, ele adiciona **/.claude/settings.local.json às suas exclusões globais do git. Isso protege apenas a sua máquina e não se aplica se você criou o arquivo manualmente ou o adicionou à força. Adicione a linha também ao .gitignore do próprio repositório.
Apagar o arquivo remove a chave vazada?
Não. A chave permanece no histórico do git, em forks e em todos os clones feitos enquanto ela estava pública. Faça a rotação da chave primeiro, depois remova o arquivo do rastreamento e limpe o histórico com o git-filter-repo.
O gitleaks ou o TruffleHog vão detectar esses vazamentos?
Não de forma confiável. Na amostra da Apiiro, 215 dos 1.122 arquivos com um segredo real passaram despercebidos por ambas as ferramentas. Rode um scanner e depois leia você mesmo as regras Bash(...) no arquivo.
Isso é um problema do modelo ou do Claude Code?
A Apiiro reproduziu o problema com o Opus 5.5 e o Fable 5.1 e o classificou como uma característica do Claude Code, não do modelo. A aprovação armazena o texto do comando, independentemente de qual modelo o escreveu.
Como aprovar comandos com segurança no Claude Code?
Aprove padrões como Bash(npm run test *) e referencie segredos como variáveis de ambiente, por exemplo $DATABASE_URL. Adicione regras deny para Read(./.env) e Read(./.env.*).
