Checklist de auditoria de permissões Claude Code: revisar allow/deny em 5 minutos
Audite allow/deny, comandos arriscados, variáveis de ambiente e logs do Claude Code toda manhã em 5 minutos.
A auditoria define o que Claude Code pode fazer hoje
O maior risco nem sempre é dizer “faça tudo”. Na prática, o problema costuma ser mais discreto: ontem você permitiu Bash(git push *) ou um WebFetch amplo demais; hoje abre um repositório de produção e esquece que a regra continua ativa.
Este artigo traz uma rotina matinal de cinco minutos. allow significa executar sem nova confirmação, ask significa pedir aprovação, e deny significa bloquear. Para iniciantes, essas regras são as bordas da mesa de trabalho que você entrega ao agente.
Em 3 de junho de 2026, a documentação oficial diz que /permissions mostra permissões de ferramentas e o arquivo de configuração de origem. As regras são avaliadas em deny -> ask -> allow, então deny prevalece. Antes de transformar isso em política, confira Claude Code Permissions, Settings e Environment variables.
Use depois do checklist dos primeiros 30 minutos e antes do setup de equipe com o template CLAUDE.md. A meta não é burocracia, mas trabalho pequeno o bastante para ser revisado.
O fluxo de cinco minutos
Comece pelo risco da tarefa de hoje, não pelo JSON. Documentação, dependências, formulários e deploys precisam de limites diferentes.
flowchart TD
A[Start session] --> B[Check git status]
B --> C[Open /permissions]
C --> D[Review allow / ask / deny]
D --> E[Inspect env and logs policy]
E --> F[Run local audit script]
F --> G[Write handoff note]
| Onde olhar | O que confirmar | Sinal de risco |
|---|---|---|
git status --short | Se já existem mudanças | Há diff e ninguém sabe a origem |
/permissions | Qual arquivo fornece cada regra | Bash, WebFetch ou Edit inteiros em allow |
.claude/settings.json | Regras compartilhadas | Deploy, cobrança ou links de pagamento autoaprovados |
.claude/settings.local.json | Exceções pessoais | Regra temporária de ontem ainda ativa |
env | Histórico e subprocessos | A equipe quer logs, mas CLAUDE_CODE_SKIP_PROMPT_HISTORY=1 |
Um detalhe oficial importa: Bash sozinho em deny remove a ferramenta Bash do contexto do Claude, enquanto Bash(rm *) mantém a ferramenta disponível e bloqueia só chamadas correspondentes. Instruções no CLAUDE.md orientam, mas não impõem uma fronteira técnica.
Exemplo mínimo de settings para o repo
Configuração compartilhada funciona melhor quando ações perigosas são bloqueadas cedo e decisões ficam em ask. Este bloco é uma base prática para .claude/settings.json.
{
"$schema": "https://json.schemastore.org/claude-code-settings.json",
"permissions": {
"allow": [
"Bash(npm run lint)",
"Bash(npm run test *)",
"Bash(git status *)",
"Bash(git diff *)",
"Read(./src/**)",
"Read(./docs/**)"
],
"ask": [
"Bash(npm install *)",
"Bash(pnpm add *)",
"Bash(git push *)",
"Bash(npm run deploy *)",
"Edit(./.github/**)"
],
"deny": [
"Bash(curl *)",
"Bash(wget *)",
"Bash(rm -rf *)",
"Read(./.env)",
"Read(./.env.*)",
"Read(./secrets/**)",
"WebFetch(domain:pastebin.com)"
],
"defaultMode": "default",
"disableBypassPermissionsMode": "disable"
},
"env": {
"CLAUDE_CODE_SUBPROCESS_ENV_SCRUB": "1"
}
}
Aqui, “harness” é a estrutura de apoio do agente: Claude Code, settings, hooks, sandbox e política de logs funcionando juntos. Não é confiar mais; é dar um espaço de trabalho menor e mais claro.
Bash(npm run test *) usa curinga. A documentação atual também reconhece :* no final, como Bash(ls:*), mas apenas no fim do padrão. Em equipe, Bash(git push *) é mais fácil de revisar.
Checklist copiável para o repositório
A auditoria deve continuar curta. Cole este bloco em PR, issue ou nota de passagem.
claude_code_permission_audit:
date: "2026-06-03"
repository:
name: "your-repo"
branch: "feature/your-task"
dirty_before_start: "yes/no"
allowed_today:
- "Read project files"
- "Edit MDX and test files"
- "Run npm run lint"
- "Run npm run test -- --runInBand"
ask_before:
- "Install or update packages"
- "Change auth, billing, analytics, or deploy config"
- "Push commits or create releases"
never_allow:
- "Print .env, tokens, cookies, or private keys"
- "Run curl/wget for arbitrary URLs"
- "Delete git history or force-push"
proof_required:
- "git diff reviewed"
- "test or build command captured"
- "rollback note written"
owner_handoff:
reviewer: "name"
open_questions:
- "Which production URL should be checked?"
O ponto central é allowed_today. Não é uma licença permanente; é o menor conjunto de permissões para concluir a tarefa do dia com evidência.
Detectar padrões perigosos com Node
Revisão manual perde facilmente um Bash completo ou um Bash(npx *) esquecido. Salve como scripts/audit-claude-permissions.mjs e rode na raiz do repositório.
#!/usr/bin/env node
import fs from "node:fs";
import os from "node:os";
import path from "node:path";
const repo = process.cwd();
const settingsFiles = [
path.join(os.homedir(), ".claude", "settings.json"),
path.join(repo, ".claude", "settings.json"),
path.join(repo, ".claude", "settings.local.json"),
].filter((file) => fs.existsSync(file));
const riskyAllowRules = [
{ pattern: /^Bash$/i, severity: "high", reason: "all Bash commands are auto-allowed" },
{ pattern: /^PowerShell$/i, severity: "high", reason: "all PowerShell commands are auto-allowed" },
{ pattern: /^(Edit|Write)$/i, severity: "high", reason: "all file edits are auto-allowed" },
{ pattern: /^WebFetch$/i, severity: "medium", reason: "all web fetches are auto-allowed" },
{
pattern: /^Bash\((curl|wget|nc|ncat|ssh|scp|rsync)\b.*\)$/i,
severity: "high",
reason: "network or transfer command is auto-allowed",
},
{
pattern: /^Bash\(.*\b(rm\s+-[^\)]*r|git\s+push|npm\s+install|pnpm\s+add|yarn\s+add|npx|docker\s+exec|devbox\s+run|mise\s+exec|terraform\s+apply|kubectl\s+apply)\b.*\)$/i,
severity: "high",
reason: "destructive or environment-changing command is auto-allowed",
},
{
pattern: /^PowerShell\(.*\b(Remove-Item|Invoke-WebRequest|Invoke-RestMethod|Start-Process)\b.*\)$/i,
severity: "high",
reason: "risky PowerShell command is auto-allowed",
},
];
const expectedDenyRules = [
"Read(./.env)",
"Read(./.env.*)",
"Read(./secrets/**)",
"Bash(curl *)",
"Bash(wget *)",
];
const findings = [];
function add(file, severity, rule, reason) {
findings.push({ file: path.relative(repo, file) || file, severity, rule, reason });
}
function readJson(file) {
try {
return JSON.parse(fs.readFileSync(file, "utf8"));
} catch (error) {
add(file, "high", "JSON", `cannot parse settings: ${error.message}`);
return null;
}
}
for (const file of settingsFiles) {
const settings = readJson(file);
if (!settings) continue;
const permissions = settings.permissions ?? {};
const allow = Array.isArray(permissions.allow) ? permissions.allow : [];
const ask = Array.isArray(permissions.ask) ? permissions.ask : [];
const deny = Array.isArray(permissions.deny) ? permissions.deny : [];
if (permissions.defaultMode === "bypassPermissions") {
add(file, "high", "permissions.defaultMode", "session starts in bypassPermissions");
}
if (permissions.disableBypassPermissionsMode !== "disable") {
add(file, "medium", "permissions.disableBypassPermissionsMode", "bypass mode is not disabled here");
}
if (settings.env?.CLAUDE_CODE_SKIP_PROMPT_HISTORY === "1") {
add(file, "low", "CLAUDE_CODE_SKIP_PROMPT_HISTORY", "prompt history and transcripts are not written");
}
if (settings.env?.CLAUDE_CODE_SUBPROCESS_ENV_SCRUB !== "1") {
add(file, "low", "CLAUDE_CODE_SUBPROCESS_ENV_SCRUB", "subprocess credential scrubbing is not enabled here");
}
for (const rule of allow) {
for (const risky of riskyAllowRules) {
if (risky.pattern.test(rule)) add(file, risky.severity, rule, risky.reason);
}
}
for (const required of expectedDenyRules) {
if (!deny.includes(required)) add(file, "low", required, "consider adding this deny rule");
}
if (ask.length === 0) {
add(file, "low", "permissions.ask", "no ask rules are defined");
}
for (const rule of [...allow, ...ask, ...deny]) {
if (/:\*[^)]/.test(rule)) {
add(file, "medium", rule, "the :* shorthand only behaves as a wildcard at the end of a pattern");
}
}
}
if (settingsFiles.length === 0) {
console.log("No Claude Code settings files found in user or repo scope.");
} else if (findings.length === 0) {
console.log("No risky Claude Code permission patterns found.");
} else {
console.table(findings);
}
if (findings.some((finding) => finding.severity === "high")) {
process.exitCode = 1;
}
No PowerShell:
New-Item -ItemType Directory -Force -Path .\scripts | Out-Null
node .\scripts\audit-claude-permissions.mjs
O script não é um motor completo de segurança. Ele cria uma porta de revisão. Mesmo com Bash(curl *) bloqueado, um Bash permitido pode chamar um script Node que acessa a rede. Para fronteiras mais fortes, combine permissões com sandbox ou contêineres.
Quatro usos concretos
1. Artigos e documentação
MDX, README, traduções e screenshots costumam ter risco menor. Muitas vezes dá para permitir Read(./src/**), Edit(./site/src/content/**), Bash(npm run lint) e Bash(npm run test *), mantendo npm install e git push em ask.
A armadilha é o CTA. Links Gumroad, formulários e URLs de PDF gratuito afetam receita e leads, então a checagem de URL pública deve entrar na definição de pronto.
2. Atualizações de dependência
Dependências alteram package.json, lockfiles, build e às vezes a segurança. Deixe instalações em ask e peça motivo, comando de teste e rollback.
Prompt útil: “Limite a três candidatos de atualização e mostre risco de breaking change, comando de prova e rollback em uma tabela.”
3. Autenticação, cobrança e analytics
Login, Stripe, Gumroad, tags de anúncio, destinos de email e webhooks precisam de aprovação humana. Testes passando não bastam. Veja quais dados são enviados, se uma falha pode cobrar duas vezes e se logs guardam dados pessoais.
CLAUDE_CODE_SKIP_PROMPT_HISTORY=1 evita gravar histórico de prompts e transcrições em disco. Ajuda em sessões sensíveis e temporárias, mas prejudica auditoria de equipe.
4. Passagem de equipe
Ao passar o trabalho, deixe o rastro das decisões. A nota deve explicar o que foi permitido, bloqueado, provado e o que ainda precisa de pessoa.
Handoff note:
- Allowed today: Edit content files, run lint, run unit tests.
- Asked before: package changes, deploy, payment links, analytics tags.
- Denied: .env reads, arbitrary curl/wget, recursive delete.
- Evidence: npm run lint passed, git diff reviewed.
- Remaining risk: production URL has not been checked after deploy.
Armadilhas comuns
Primeiro, autoaprovação ampla demais. Bash, PowerShell, Edit ou WebFetch completos em allow parecem eficientes, mas deixam muito risco para memória e revisão manual.
Segundo, filtro de URL só com padrão Bash. Bash(curl https://github.com *) é frágil porque opções, redirects, variáveis e espaços mudam. Bloqueie curl e wget; use WebFetch(domain:example.com) ou hook.
Terceiro, wrappers. A documentação descreve tratamento integrado para timeout e time, mas runners como npx, docker exec, devbox run e mise exec exigem cautela.
Quarto, Read/Edit deny não é isolamento completo do sistema operacional. Vale para ferramentas integradas e comandos reconhecidos, não para qualquer script que abra arquivos internamente.
Prompt de equipe para o primeiro turno
Comece com auditoria, não implementação.
Before changing files, audit Claude Code permissions for this repository.
Return:
1. allow rules that are safe for today's task
2. ask rules that should stay behind human approval
3. deny rules that protect secrets, deploys, and destructive commands
4. environment variables that affect logs or subprocess secrets
5. the smallest task you can complete with proof and rollback notes
Do not edit files until the audit is summarized.
O prompt sozinho não impõe segurança. Settings e a UI de permissões fazem isso. O valor dele é tornar a fronteira visível antes da primeira edição.
Proteger o caminho de receita
Em um site que leva a PDF gratuito, produtos Gumroad ou consultoria, a auditoria protege receita além de segurança. Para firmar o fluxo básico, comece pela cheatsheet gratuita. Para organizar CLAUDE.md, permissões, hooks e MCP em equipe, o Setup Guide é o caminho mais rápido. Para adoção assistida, veja treinamento e consultoria.
Depois de testar na prática, a rotina de maior valor foi revisar git status, /permissions, .claude/settings.local.json e o script antes de pedir edições. Manter links Gumroad e deploys em ask deixa a sessão um pouco mais lenta, mas acelera a revisão porque toda mudança que afeta receita mantém uma razão de aprovação visível.
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
Checklist de auditoria inicial de repositório com Claude Code
Audite um repo em 20 minutos antes da primeira edição: escopo, riscos, provas e CTA de receita.
Claude Code Harness Lite: uma base pequena para mudanças seguras
Um fluxo iniciante que separa leitura, edição, prova, URL pública e CTA de receita no Claude Code.
Primeiro repo map com Claude Code: ler código existente sem gastar contexto
Fluxo seguro para ler um repositório com Claude Code antes de editar: mapa, tarefas pequenas, provas, PDF grátis, Gumroad e consultoria.