Permission budget no Claude Code: permissões, custo e logs em 5 minutos
Um loop prático para regras allow/deny, limite de custo, logs de execução e handoff no Claude Code.
Por que revisar cinco minutos toda manhã
Com Claude Code, a pergunta operacional não é apenas “ele consegue programar?” A pergunta decisiva é “o que ele pode fazer sem parar para pedir aprovação?” Aprovar cada comando Bash parece cuidadoso no começo, mas logo surge fadiga de aprovação. Permitir tudo é pior: leitura de .env, instalação de pacotes, git push, deploy de produção, migrações e mudanças de billing podem cair na mesma faixa.
Um permission budget é uma tabela curta de operação. Ela define quais ações Claude Code pode executar sem aprovação, quais precisam perguntar a uma pessoa e quais ficam proibidas naquele repositório. O loop é o hábito de comparar essa tabela todas as manhãs com o log de execução e o uso do dia anterior. Em termos simples: contar as chaves e o dinheiro que você entregou ao agente.
Em 3 de junho de 2026, a documentação oficial descreve permissões com allow, ask e deny; deny tem prioridade sobre ask e allow. /permissions mostra as regras ativas e o arquivo de settings de origem. Para custos, /usage dá a visão local ou de sessão, enquanto Claude Console é a referência para billing e limites de workspace. Consulte Configure permissions, Claude Code settings, Manage costs effectively e a CLI reference.
Como leitura interna, conecte este loop ao Claude Code permissions guide, à permission audit checklist e ao permission receipt pattern.
O básico sem jargão de segurança
Permissions no Claude Code são aplicadas pela CLI, não pela intenção do modelo. Escrever em CLAUDE.md “não leia secrets” é uma orientação útil, mas não é uma barreira técnica. Uma regra deny como Read(./.env) ou Read(./secrets/**) é uma barreira que Claude Code pode aplicar.
Os modos também importam. default é o fluxo normal de aprovação. plan favorece leitura e investigação. acceptEdits facilita edições de arquivo. dontAsk nega ferramentas que não foram pré-aprovadas ou marcadas como ask. bypassPermissions, também disponível como --dangerously-skip-permissions, pula prompts e deve ficar restrito a containers ou VMs isoladas.
Custos seguem o mesmo raciocínio. /usage ajuda a identificar uma sessão local cara demais, mas billing de API deve ser confirmado no Claude Console. Em execuções com claude -p, --max-budget-usd e --max-turns são guardrails úteis; não substituem um orçamento de equipe.
O daily permission budget loop
A rotina precisa ser pequena o bastante para se repetir. O objetivo não é uma auditoria perfeita, e sim evitar começar o dia com uma permissão perigosa aberta.
| Passo | Verificar | Critério |
|---|---|---|
| 1 | /permissions | Sem Bash(*) ou regra ampla como Bash(npm *) |
| 2 | .claude/settings.json | secrets, deploy, banco de dados e billing estão em ask ou deny |
| 3 | /usage e Console | O gasto de ontem tem explicação |
| 4 | git diff e log | O trabalho aprovado bate com o diff |
| 5 | nota de handoff | Permissões abertas, ações bloqueadas e próximo reviewer estão escritos |
Prompt curto para começar:
Before starting today's Claude Code work, classify the task into:
1. safe to run without approval
2. requires human approval
3. should not run in this session
Then list up to five checks for /permissions, /usage, and git diff.
Starter compartilhado de settings.json
Este exemplo de .claude/settings.json é um bom ponto de partida. defaultMode: "dontAsk" é rígido: ferramentas fora de allow ou ask não rodam. Teste localmente antes de transformar em padrão do projeto.
{
"$schema": "https://json.schemastore.org/claude-code-settings.json",
"permissions": {
"defaultMode": "dontAsk",
"allow": [
"Bash(npm run lint)",
"Bash(npm run test)",
"Bash(npm run test *)",
"Bash(npm run build)",
"Bash(git status)",
"Bash(git diff)",
"Bash(git diff *)",
"WebFetch(domain:code.claude.com)"
],
"ask": [
"Bash(npm install *)",
"Bash(pnpm add *)",
"Bash(git push *)",
"Bash(wrangler deploy *)",
"Bash(vercel deploy *)",
"Bash(terraform apply *)",
"Bash(kubectl apply *)"
],
"deny": [
"Read(./.env)",
"Read(./.env.*)",
"Read(./secrets/**)",
"Bash(curl *)",
"Bash(wget *)",
"Bash(rm -rf *)"
]
}
}
O ponto principal é manter a faixa segura estreita. Bash(npm *) pode ir de test para install ou publish. Bash(git *) pode ir de diff para push. Leitura, lint, test e build entram em allow de forma específica; install, push, deploy e apply ficam atrás de aprovação humana.
Budget e log em JSON
Permission é só metade. A outra metade é custo. Investigações longas, testes falhando repetidamente, sessões em background e logs grandes podem aumentar o gasto sem chamar atenção. Um budget pequeno e um log diário tornam a revisão visível no pull request.
{
"date": "2026-06-03",
"dailyLimitUsd": 6,
"warnAtUsd": 4,
"usageSource": "/usage plus Claude Console",
"safeAllow": [
"Bash(npm run lint)",
"Bash(npm run test)",
"Bash(git diff *)"
],
"askFirst": [
"Bash(npm install *)",
"Bash(git push *)",
"Bash(wrangler deploy *)"
],
"mustDeny": [
"Read(./.env)",
"Read(./.env.*)",
"Read(./secrets/**)"
],
"handoffRequired": true
}
{
"date": "2026-06-03",
"spentUsd": 1.85,
"usageChecked": true,
"settingsChecked": true,
"permissionsReviewed": [
"/permissions",
".claude/settings.json"
],
"openAllowances": [
"Bash(npm run lint)",
"Bash(npm run test *)"
],
"handoff": [
"No deploy allowance left open",
"Claude stopped before production data work"
]
}
Salve como .claude/permission-budget.json e .claude/daily-claude-log.json. Planilhas servem para relatórios, mas JSON é melhor para code review e automação.
Script Node para auditoria
Salve como scripts/audit-claude-loop.mjs e rode node scripts/audit-claude-loop.mjs. Não há dependências externas. Ele detecta Bash amplo demais, deploy na faixa allow, falta de deny para .env, estouro de budget e handoff vazio.
#!/usr/bin/env node
import fs from "node:fs";
const readJson = (file) => JSON.parse(fs.readFileSync(file, "utf8"));
const budget = readJson(".claude/permission-budget.json");
const log = readJson(".claude/daily-claude-log.json");
const settings = readJson(".claude/settings.json");
const problems = [];
const permissions = settings.permissions ?? {};
const allow = new Set(permissions.allow ?? []);
const ask = new Set(permissions.ask ?? []);
const deny = new Set(permissions.deny ?? []);
const hasPattern = (items, pattern) => [...items].some((item) => pattern.test(item));
if (typeof budget.dailyLimitUsd !== "number" || budget.dailyLimitUsd <= 0) {
problems.push("dailyLimitUsd must be a positive number");
}
if (typeof budget.warnAtUsd !== "number" || budget.warnAtUsd >= budget.dailyLimitUsd) {
problems.push("warnAtUsd must be lower than dailyLimitUsd");
}
if (log.spentUsd > budget.dailyLimitUsd) {
problems.push(`spentUsd ${log.spentUsd} exceeds daily limit ${budget.dailyLimitUsd}`);
}
if (log.spentUsd >= budget.warnAtUsd) {
console.warn(`WARN: spentUsd ${log.spentUsd} has reached warnAtUsd ${budget.warnAtUsd}`);
}
if (!log.usageChecked) problems.push("Run /usage and mark usageChecked true");
if (!log.settingsChecked) problems.push("Review /permissions and mark settingsChecked true");
if (allow.has("Bash") || allow.has("Bash(*)") || hasPattern(allow, /^Bash\(\*.*\)$/)) {
problems.push("Do not allow every Bash command");
}
if (hasPattern(allow, /(deploy|terraform apply|kubectl apply|git push)/)) {
problems.push("Deploy, infrastructure, and push commands must be ask-first, not allow");
}
for (const rule of budget.askFirst ?? []) {
if (!ask.has(rule)) problems.push(`Missing ask rule: ${rule}`);
}
for (const rule of budget.mustDeny ?? []) {
if (!deny.has(rule)) problems.push(`Missing deny rule: ${rule}`);
}
if (!hasPattern(deny, /Read\(.*\.env/)) {
problems.push("Deny rules should block .env reads");
}
if (!Array.isArray(log.handoff) || log.handoff.length === 0) {
problems.push("Add at least one handoff note");
}
if (problems.length) {
console.error(problems.map((problem) => `- ${problem}`).join("\n"));
process.exit(1);
}
console.log("Claude Code daily permission budget check passed.");
Em CI, comece em modo warning ou manual. Uma policy muito dura no primeiro dia costuma gerar atalhos.
Quatro casos de uso concretos
Primeiro, artigos e documentação. Markdown, MDX, links internos, CTAs, correções e caminhos de imagem raramente tocam secrets ou produção. Permita de forma estreita leitura, git diff, lint, tests e build local para Claude Code produzir diffs pequenos sem interrupção desnecessária.
Segundo, mudanças de dependência. npm install e pnpm add afetam lockfiles, postinstall, licenças, vulnerabilidades e bundle size. Deixe em ask; antes de aprovar, peça motivo, alternativa considerada e plano de remoção.
Terceiro, deploys e migrações. wrangler deploy, vercel deploy, terraform apply, kubectl apply e migrations mudam estado externo. Claude Code pode preparar comando, impacto, rollback, URL de verificação e checklist de monitoramento, mas a execução deve esperar aprovação humana.
Quarto, handoff de equipe. Se outra pessoa continuar depois, escreva open allowances, proof commands, ações bloqueadas e budget restante. Sem isso, a próxima pessoa repete a investigação e reabre a mesma permissão arriscada.
Falhas a evitar
A falha mais comum é Bash amplo demais. Bash(npm *) e Bash(git *) são convenientes, mas misturam comandos de leitura com comandos que mudam estado. Prefira comandos exatos para a rotina diária.
Outra falha é esquecer uma permissão de deploy aberta. Durante incidente, wrangler deploy * pode sair de ask e virar allow. Se ficar assim na manhã seguinte, trabalho comum de feature passa a ter poder de produção.
A terceira falha é ignorar crescimento de tokens e custo. Uma investigação longa parece produtiva, mas pode queimar orçamento. Veja /usage, compare com Console quando billing importar e pare sessões sem valor claro.
Por fim, não confunda prompt com enforcement. “Não leia secrets” orienta. Read(./.env) em deny bloqueia. O harness, a estrutura de trabalho do agente, precisa de prompt, settings, logs e review juntos.
Produtos, treinamento e rollout
Para praticar sozinho, copie os JSON e o script para um repositório pequeno. Para checklists reutilizáveis, templates CLAUDE.md e prompts de review, use /products/. Para rollout de equipe com permissões, controle de custo, policy de CI, treinamento de reviewers e regras por repositório, use /training/.
Nota prática (resultado de testar na prática): a maior melhoria não veio de bloquear todos os comandos arriscados. Ela veio de verificar por cinco minutos, toda manhã, /permissions, /usage, git diff e a nota de handoff. Regras allow estreitas continuaram úteis, enquanto deploys, billing e secrets voltaram sempre para ask ou deny.
PDF grátis: cheatsheet do Claude Code
Informe seu e-mail e baixe uma página com comandos, hábitos de revisão e workflows seguros.
Cuidamos dos seus dados e não enviamos spam.
Sobre o autor
Masa
Engenheiro focado em workflows práticos com Claude Code.
Artigos relacionados
Como pedir ao Claude Code para mexer em um único arquivo
Do desastre em que um 'deixa melhor' alterou 40 linhas nasceu um template de prompt que limita o escopo, valida e permite reverter.
Recuperar de negações de permissão no Claude Code sem enfraquecer guardrails
Transforme um comando negado em plano seguro com motivo, alternativa, provas e critérios de nova tentativa.
Claude Code Harness Smoke Test: prova de 15 minutos antes de confiar em um agente
Um smoke test para escopo, áreas bloqueadas, comandos de prova, URL pública e CTAs de receita no Claude Code.