Como impedir o Claude Code de editar arquivos que você não pediu

regra deny no settings.json impedindo o Claude Code de editar arquivos protegidos
Resposta rápida

Impedir o Claude Code de editar arquivos que você não pediu não é questão de caprichar na frase do prompt, é questão de regra de permissão. O Claude Code avalia as regras na ordem deny, ask, allow, e a primeira que casar decide, independente de quão específica ela seja. Regra deny bloqueia em todos os modos, inclusive no bypassPermissions. Na prática: você escreve deny sob a chave permissions no settings.json, no formato Ferramenta(padrão), com padrões estilo gitignore. O prompt orienta, o CLAUDE.md documenta, o deny é o que trava mesmo.

Fala aí, beleza? Você pediu ajuste em UM arquivo e o agente voltou com outros três mexidos, um deles bem longe do que você tinha em mente

Acontece

E o reflexo costuma ser o mesmo: escrever "não mexe em mais nada" no prompt e torcer pro melhor

Só que o prompt é a camada mais fraca dessa história

Antes do modelo decidir qualquer coisa, o pedido passa pelas regras de permissão do Claude Code, e é ali que a porta fecha, não no texto do prompt

A ordem de avaliação é deny, depois ask, depois allow, e a primeira regra que casar decide, não importa se ela é genérica ou ultra específica

Melhor ainda: pela documentação oficial, regra deny bloqueia em todos os modos de permissão, inclusive no bypassPermissions

(guarde esse "pela documentação oficial", porque mais pra frente eu mostro por que ainda assim vale testar a SUA regra)

Ou seja, o que você quer não é uma frase mais firme no prompt, é uma regra 😀

O que você precisa saber antes de delimitar o escopo

Existem três escopos principais de settings, e saber quem é quem já evita boa parte da confusão depois:

  • usuário: ~/.claude/settings.json
  • projeto: .claude/settings.json
  • local: .claude/settings.local.json

Tá no Windows? ~/.claude resolve pra %USERPROFILE%\.claude, mesmo lugar, outro nome

A precedência vai de usuário (menor peso) pra projeto, depois local, depois a flag --settings, e por último os managed settings da organização (maior peso)

Domine o Claude Code do básico ao avançado
Pré-inscrição Formação Claude Code

Domine o Claude Code do básico ao avançado

Você vai aprender a criar sistemas completos com Claude Code, sem precisar ser programador. Inscreva-se para ter acesso a um desconto de lançamento e bônus especiais!

Isso importa porque uma regra sua pode estar viva e ainda assim perder pra outra que veio de um arquivo mais forte

"E como eu vejo o que já está valendo agora?"

Dois comandos dentro da sessão:

  • /permissions lista todas as regras de permissão ativas E o settings.json de onde cada uma veio
  • /status mostra a linha de setting sources, ou seja, quais arquivos de configuração a sessão carregou

Rode os dois antes de escrever qualquer regra nova, beleza? Serve de linha de base

Se o seu incômodo com o agente também passa por desconfiar do que ele leu, vale olhar como saber se ele leu o projeto antes de responder

Passo a passo: marcando o alvo e o que fica fora do raio

A ideia aqui é simples: apontar o alvo, nomear o que fica fora e transformar a parte crítica disso em regra

  1. Aponte o alvo no prompt e nomeie o que fica fora

Em vez de "arruma o login", escreva qual pasta ou arquivo é o alvo, o que pode ser alterado e o que fica fora de escopo

Algo do tipo: "altere só src/auth/login.ts, não toque em nada dentro de migrations/ nem em arquivos de configuração, e se precisar mexer em outro arquivo, pare e me diga qual antes"

Isso orienta bem, principalmente quando você combina com um prompt que ele consegue verificar sozinho no fim da tarefa

O erro comum deste passo: achar que o texto do prompt virou uma trava técnica

Não virou

Prompt é instrução, e instrução pode ser mal interpretada. A trava mesmo mora no deny

  1. Rode /permissions e veja o terreno

Antes de adicionar regra, olhe o que já existe e de qual arquivo veio cada uma

O erro comum deste passo: escrever uma regra nova sem ver que já tinha uma antiga contradizendo ela em outro escopo

  1. Escreva o deny no settings.json

As regras ficam sob a chave permissions, com listas allow e deny, no formato Ferramenta(padrão)

Esse é o exemplo oficial:

{
  "permissions": {
    "allow": [
      "Bash(npm run lint)",
      "Bash(npm run test *)"
    ],
    "deny": [
      "Read(./.env)",
      "Read(./.env.*)"
    ]
  }
}

Pra impedir escrita, a ferramenta é Edit, e se liga nisso: a regra Edit vale pra todas as ferramentas nativas que editam arquivo, não só pra uma

O erro comum deste passo: bloquear só a leitura achando que a edição foi junto. São ferramentas diferentes, regras diferentes

  1. Acerte o padrão (é sintaxe de gitignore)

As regras Read e Edit usam padrão estilo gitignore

Se você já mexeu em .gitignore na vida, é exatamente aquela pegada, o que ajuda muito

Padrão O que ele faz
* casa dentro de um único segmento do caminho e pode aparecer em qualquer posição
** atravessa diretórios
.env nome solto casa em qualquer profundidade, então Read(.env) equivale a Read(**/.env)
/caminho a barra inicial ancora na origem do arquivo de settings, não na raiz do sistema
//caminho duas barras pra caminho absoluto de verdade

O erro comum deste passo: escrever /Users/alice/file achando que apontou pro caminho absoluto

Não apontou: essa barra inicial ancora na origem do settings. Absoluto mesmo é //Users/alice/file

  1. Escolha o escopo do arquivo conforme a precedência

Regra que vale pra todo mundo do time vai no .claude/settings.json do projeto, que é versionado junto com o código

Regra que é manha sua daquela máquina vai no .claude/settings.local.json

Regra que você quer em qualquer projeto vai no ~/.claude/settings.json

O erro comum deste passo: colocar a proteção do time no escopo de usuário, aí ela existe na sua máquina e não existe na do colega

  1. Comece a sessão no modo certo

O Claude Code tem modos de permissão distintos: default (que aparece como Manual), acceptEdits, plan, auto, dontAsk e bypassPermissions

Quando a intenção é só explorar e entender, o modo plan é o seu amigo: ele lê arquivos e roda comandos de shell somente leitura pra explorar, mas não edita os fontes

A chave defaultMode nos settings define em qual modo as sessões começam

O erro comum deste passo: deixar o padrão em um modo que aceita edição e só perceber isso quando o diff já cresceu

  1. Feche a porta dos atalhos

Dá pra barrar o uso dos modos bypassPermissions e auto em qualquer arquivo de settings:

{
  "permissions": {
    "disableBypassPermissionsMode": "disable",
    "disableAutoMode": "disable"
  }
}

O erro comum deste passo: confiar só nisso

O deny continua sendo a trava principal, esse par aqui é o cinto de segurança em cima

  1. Registre a convenção onde o Claude lê

O CLAUDE.md fica na raiz do projeto e é lido no começo de toda sessão, então é o lugar certo pra escrever as regras do tipo "nunca edite X à mão"

Detalhe importante: no lançamento ele carrega o CLAUDE.md do diretório de trabalho e de todos os diretórios pais, e o CLAUDE.md de subdiretório entra sob demanda, quando ele lê arquivos dali

Quer ver onde esses arquivos moram? /memory lista os caminhos dos arquivos de memória por escopo, incluindo os que ainda nem existem

E quando a regra vale só pra certos arquivos, existe a pasta .claude/rules/, que aceita escopo de caminho via frontmatter YAML com o campo paths:

---
paths:
  - "**/*.ts"
  - "src/**/*"
---

Não altere arquivos gerados automaticamente nesta árvore.
Se for necessário, avise antes e explique o motivo.

Os .md dali são descobertos recursivamente e a pasta aceita symlinks

O erro comum deste passo: tratar o CLAUDE.md como se fosse bloqueio

Ele documenta e orienta, o que já é MUITO valioso, mas quem impede é a regra deny

Ele mexeu mesmo assim: o que checar quando o bloqueio falha

Escreveu a regra e ainda assim viu arquivo alterado fora do combinado? Vai por partes

A regra existe, mas outra venceu

Sintoma: você jura que escreveu o deny, e o agente editou do mesmo jeito

Causa provável: a regra está num escopo mais fraco, ou nem foi carregada nessa sessão

O que fazer: /permissions mostra as regras ativas e a origem de cada uma, /status mostra quais arquivos de settings a sessão carregou

Se a sua regra não aparece em nenhum dos dois, o problema não é o modelo, é o arquivo

O padrão está casando com outro caminho

Sintoma: o bloqueio funciona pra um arquivo e ignora o vizinho

Causa provável: * casa dentro de um único segmento e não atravessa diretório, quem atravessa é **

E lembre que nome solto casa em qualquer profundidade da árvore, o que às vezes bloqueia mais do que você queria

O que fazer: reescreva o padrão pensando em segmento de caminho, e confira se a barra inicial está ancorando onde você imagina

Você aprovou aquele caminho no passado

Sintoma: aparece uma regra que você não escreveu

Causa provável: em algum momento você aprovou um caminho marcando pra não perguntar de novo

Quando isso acontece, o Claude Code escapa os caracteres de padrão gitignore daquele caminho, justamente pra regra gerada casar só com o caminho literal aprovado (caracteres como [, ] e * entram escapados)

O que fazer: revisar a lista no /permissions de vez em quando, tipo faxina

Você apostou num .claudeignore

Sintoma: criou o arquivo, sentiu segurança, e nada mudou

Causa: existe pedido aberto de recurso pra um `.claudeignore` no repositório oficial, o que já indica que isso não é recurso nativo do produto

E combina com o relato aberto por lá de que um .claudeignore não impede o Claude de ler os arquivos listados nele: quem tentou usar o arquivo esbarrou justamente na ausência desse suporte

O que fazer: usar permissions.deny mesmo

Tem pasta extra aberta que ninguém lembrou

Sintoma: ele mexeu em coisa que nem deveria estar no raio do projeto

Causa provável: a chave permissions.additionalDirectories nos settings, a flag --add-dir na linha de comando ou o /add-dir na sessão deram acesso a pastas fora do diretório de trabalho

Detalhe que pega gente desprevenida: isso concede acesso aos arquivos e NÃO carrega a configuração daquelas pastas

Ou seja, o CLAUDE.md e as regras que moram lá não vêm junto de brinde

Apareceu "Shell cwd was reset"

Sintoma: no resultado da ferramenta vem anexada a mensagem Shell cwd was reset to <dir>

Causa: um cd caiu fora do diretório do projeto ou dos diretórios adicionais autorizados, e o Claude Code resetou pro diretório do projeto

O que fazer: tratar isso como aviso útil e olhar o que ele estava tentando alcançar ali fora

E vale conferir em vez de confiar cego

Aqui entra a ressalva que eu pedi pra você guardar lá em cima

A documentação diz que deny bloqueia em todos os modos, e é essa a regra do jogo que você deve seguir

Só que já foram abertas issues no repositório oficial relatando que regras deny do settings.json não estavam sendo aplicadas na leitura e na edição de arquivos: uma delas é o deny de Read pra .env não aplicado, aberta em 11/02/2026, e outra é o deny em .claude/settings.json ignorado, aberta em 20/02/2026

Não vou afirmar aqui que isso segue quebrado nem que já foi resolvido, porque não dá pra cravar

O recado prático é outro: comportamento documentado é o esperado, não é uma garantia que dispensa checagem

Então, depois de escrever a regra, teste ela

Peça uma leitura ou uma edição no caminho bloqueado e veja o que acontece

Prevenir é isso: regra escrita, regra testada, /permissions conferido de tempos em tempos

Três recortes que valem a pena travar no seu projeto

Segredos e variáveis de ambiente

Esse é tão comum que o próprio exemplo oficial já vem com Read(./.env) e Read(./.env.*) no deny

Faz sentido: são os arquivos que você menos quer ver entrando em contexto e sendo repetidos em algum lugar

Como nome solto casa em qualquer profundidade, Read(.env) equivale a Read(**/.env), o que ajuda em monorepo com vários .env espalhados

Código gerado ou de terceiros

Aquela pasta de build, de saída de gerador, de biblioteca que ninguém edita à mão

O agente às vezes acha um jeito "esperto" de resolver o problema editando o artefato em vez da fonte, e aí você tem um fix que some no próximo build

Aqui a ferramenta é Edit, com ** atravessando os diretórios da árvore:

{
  "permissions": {
    "deny": [
      "Edit(dist/**)",
      "Edit(build/**)",
      "Edit(node_modules/**)"
    ]
  }
}

O detalhe que resolve: a regra Edit vale pra todas as ferramentas nativas de edição de arquivo, então não fica um buraco aberto por outra ferramenta

A própria pasta .claude

Essa é a mais irônica e a mais esquecida

A configuração que define o que ele pode fazer também é um monte de arquivo no disco, e arquivo no disco é editável

{
  "permissions": {
    "deny": [
      "Edit(.claude/**)"
    ]
  }
}

Por que resolve: ** atravessa diretórios, então pega settings, rules e o resto da árvore de configuração de uma vez

Conclusão

A hierarquia é essa, e ela é bem clarinha quando você separa os papéis:

  • o prompt orienta ("mexa só aqui, isso fica fora")
  • o CLAUDE.md e a pasta .claude/rules/ documentam a convenção pra toda sessão
  • o permissions.deny bloqueia, avaliado antes de tudo e valendo, pela documentação, inclusive no bypassPermissions

Misturar esses três papéis é o que faz a galera achar que "pedi e ele ignorou"

Próximo passo, hoje mesmo, no projeto que você já tem aberto: rode /permissions, olhe o que aparece e de onde veio

Depois liste os dois ou três caminhos que ninguém deveria tocar naquele repositório

E escreva a primeira regra deny

Depois teste ela, que é o passo que quase todo mundo pula

Uma linha só já muda o jogo… e o resto você vai lapidando conforme o projeto pedir

Até o próximo post! 🙂

Perguntas frequentes

Escrever ‘não mexe em outros arquivos’ no prompt do Claude Code já resolve?

Orienta, mas não trava nada: prompt é instrução e pode ser mal interpretada pelo modelo. Quem decide de verdade é a regra deny nas permissions, avaliada antes de qualquer resposta, na ordem deny, depois ask, depois allow.

Um arquivo .claudeignore impede o Claude Code de ler ou editar arquivos?

Não é um recurso nativo do produto: existe pedido de recurso aberto no repositório oficial pedindo justamente isso (github.com/anthropics/claude-code/issues/29455). Por isso mesmo aparece por lá o relato de que um .claudeignore não impede a leitura dos arquivos listados nele (github.com/anthropics/claude-code/issues/36163): quem criou o arquivo esbarrou na ausência desse suporte. Pra bloquear de verdade, a regra é deny no settings.json.

A regra deny do Claude Code funciona mesmo no modo bypassPermissions?

Pela documentação oficial, sim: regra deny bloqueia em todos os modos de permissão, inclusive no bypassPermissions, que normalmente pula as confirmações. É por isso que ela é a trava principal, não o texto do prompt. Ainda assim, comportamento documentado não dispensa teste, então confirme a sua regra na prática (veja a próxima pergunta).

Como confirmar se a regra deny que eu escrevi está realmente valendo na sessão?

Rode /permissions: ele lista todas as regras ativas e de qual settings.json cada uma veio. Depois peça uma leitura ou edição no caminho bloqueado e veja o que acontece. Vale conferir mesmo, já que foram abertas issues no repositório oficial relatando deny não aplicado em leitura e em edição de arquivo (github.com/anthropics/claude-code/issues/24846), sem dar pra cravar se segue assim ou se já foi resolvido.

Qual arquivo usar pra bloquear edição só na minha máquina, sem mexer na regra do time?

O settings.local.json é o escopo local, pensado pra manha individual daquela máquina. Já o .claude/settings.json do projeto é o que fica versionado e vale pra todo mundo do time.

Dá pra criar uma regra deny que valha em qualquer projeto que eu abrir?

Dá, colocando a regra no ~/.claude/settings.json, que é o escopo de usuário. Só que esse escopo tem o menor peso na precedência (usuário < projeto < local < –settings < managed settings), então uma regra de projeto ou local pode se sobrepor a ela.



Subscribe
Notify of
guest

0 Comentários
Oldest
Newest Most Voted

Formações

Formação Vibe Coding

Formação Vibe Coding

Do Prompt ao Produto: Crie Software Real com IA

  • 474 aulas
  • 20 projetos
  • 39h 27min

Blog | Mais populares