Cos'è e perché conta
In modalità Manual, Claude Code ti chiede il permesso prima della maggior parte delle azioni. All'inizio leggi ogni domanda. Dopo un po' premi sì senza leggere, e a quel punto il permesso non ti protegge più.
Il bottone «fai tu» è il contrario: decidi una volta sola, a mente fredda, cosa Claude può fare da solo e cosa no. Libero dentro il progetto: modificare i file, lanciare i test, avviare il server. Bloccato su tre cose difficili da annullare: cancellare, pubblicare, toccare il database vero.
Servono due pezzi: una modalità di permesso, che decide quanto Claude ti chiede, e un file di regole nel progetto, che dice cosa passa sempre, cosa chiede sempre e cosa è vietato.
1. La modalità
Io lavoro in accept edits: Claude modifica i file del progetto senza chiedere, tutto il resto passa dalle regole qui sotto. Accetta da solo anche alcuni comandi base sui file, come mkdir, mv, cp e rm, ma solo dentro la cartella del progetto.
Per accenderla premi Shift+Tab finché sotto il prompt leggi «accept edits on». Nelle versioni recenti la sessione parte già in auto mode, dove un secondo modello controlla le azioni al posto tuo: il primo Shift+Tab ti porta in manuale, il secondo in accept edits. Oppure la scegli all'avvio, dal terminale:
claude --permission-mode acceptEdits
Prima di dare a Claude un lavoro, guarda sempre quella riga. Auto è comoda e blocca le azioni rischiose, ma la documentazione stessa dice che non garantisce la sicurezza. Con accept edits sai esattamente cosa passa da solo, e le regole valgono in tutte e due.
2. Le regole, una volta sola
Crea il file .claude/settings.json nella cartella del progetto. Se esiste già, non sovrascriverlo: aggiungi la parte «permissions» a quello che c'è. Il mio è così:
{
"permissions": {
"defaultMode": "acceptEdits",
"allow": [
"Bash(npm test *)",
"Bash(npm run test *)",
"Bash(npm run dev *)",
"Bash(npm run lint *)"
],
"ask": [
"Bash(git push *)"
],
"deny": [
"Bash(rm *)",
"Bash(git push --force *)",
"Bash(git push -f *)",
"Bash(npm publish *)",
"Bash(vercel *)",
"Bash(npx vercel *)",
"Bash(supabase db push *)",
"Bash(psql *)",
"Read(./.env.production)"
]
}
}Metti i tuoi comandi al posto dei miei (i test, il server, il deploy, il client del tuo database vero). Attenzione: in accept edits anche rm dentro il progetto passerebbe da solo, per questo è nei deny.
Cosa fa ogni parte
- defaultMode: la modalità con cui parte la sessione nel terminale. Parti in accept edits anche se il default sarebbe auto. Il flag --permission-mode vince sul file.
- allow: i comandi che Claude lancia senza chiedere: test, lint, server di sviluppo. Bash(npm test *) copre npm test da solo e con qualsiasi opzione dopo.
- ask: i comandi su cui vuoi una domanda ogni volta, in qualsiasi modalità, anche in auto. git push manda il codice online: lo voglio vedere prima.
- deny: quello che non deve succedere mai: cancellare file, il push forzato, pubblicare, il deploy, il database vero. vercel e npx vercel sono due righe perché la regola su vercel non vede il comando con npx davanti.
- Read(./.env.production): Claude non legge il file con le chiavi di produzione, né con i suoi strumenti né con cat, e non lo può modificare.
Il file non devi scriverlo a mano. Lo puoi far adattare a Claude:
Leggi il package.json e gli script di questo progetto. Poi adatta questo file .claude/settings.json: in allow metti i comandi veri dei test, del lint e del server di sviluppo; in deny i comandi che cancellano file, pubblicano l'app, fanno il deploy o toccano il database di produzione. Non mettere in allow niente che cancelli o mandi qualcosa online. Fammi vedere il file prima di salvarlo. [incolla qui il file]
Quando Claude salva il file ti chiede il permesso anche in accept edits: è normale, la cartella .claude è protetta.
3. Tre cose da sapere
Il deny vince sempre
Claude Code controlla le regole in quest'ordine: prima deny, poi ask, poi allow. Decide la prima che corrisponde. Un allow non apre un buco in un deny, nemmeno se è più preciso. E i deny valgono in ogni modalità.
Nel mio file: git push --force è sia nell'ask sia nel deny, e vince il deny. git push origin main --force invece il deny non lo vede, perché non comincia con «git push --force». Comincia però con «git push», e l'ask ti fa la domanda. Per questo tengo tutte e due le righe.
Le regole leggono il testo del comando
Le regole leggono il testo del comando: bash -c 'rm -rf build' o /bin/rm passano sotto «Bash(rm *)». La regola non li riconosce, e a quel punto decidono la modalità e le altre regole.
Per una guardia vera usa un hook PreToolUse (il guardiano del TIPS 05) o la sandbox (/sandbox). L'hook legge tutto il testo di ogni comando prima che parta, anche dentro bash -c. Con la sandbox è il sistema operativo a limitare cosa i comandi scrivono fuori dal progetto e a quali siti si collegano. Dentro il progetto però lascia scrivere: un rm lì lo ferma solo l'hook.
La modalità senza controlli
La modalità senza nessun controllo (--dangerously-skip-permissions) usala solo dentro un container o una macchina virtuale, mai sul computer con i tuoi file. Anche la documentazione la consiglia solo in ambienti isolati. Se sul tuo computer vuoi meno domande, la strada è accept edits con le regole, oppure auto.
4. Controlla
Scrivi /permissions dentro Claude Code: vedi tutte le regole attive e da quale file arriva ognuna. Se una regola non c'è, di solito il file è nel posto sbagliato o il JSON ha un errore, tipo una virgola mancante.
Poi fai una prova vera. Scrivi a Claude:
Crea un file vuoto chiamato prova-permessi.txt. Poi prova questi tre comandi, uno alla volta, e per ognuno dimmi cosa è successo: bloccato da una regola, mi hai chiesto il permesso, oppure è partito da solo. - npm test (o il comando dei test di questo progetto) - rm prova-permessi.txt - git push --dry-run Se un comando viene bloccato, non cercare altri modi per lanciarlo.
Ti aspetti questo: test partiti da soli, rm bloccato, git push con la domanda (con --dry-run non manda niente online). Il file di prova poi lo cancelli tu: Claude non può.
Gli errori più comuni
- Copiare il file senza cambiare i comandi: se i tuoi test non partono con npm test, l'allow non serve e Claude ti chiede ogni volta. Metti i comandi veri del tuo progetto.
- Lavorare in accept edits senza rm nei deny: dentro il progetto rm passa da solo. Tienilo nei deny e i file da buttare cancellali tu.
- Credere che il deny copra ogni forma del comando: bash -c o /bin/rm passano. Per una guardia vera aggiungi l'hook o la sandbox.
- Affidarsi alle istruzioni in chat, tipo «non cancellare niente»: orientano Claude ma non bloccano niente. Quello che non deve succedere mai va nei deny.
- Non guardare in che modalità sei: la sessione può partire in auto senza che tu l'abbia scelto. Prima di un lavoro lungo leggi la riga sotto il prompt.
Checklist
- Modalità scelta e letta sotto il prompt
- .claude/settings.json con i comandi del tuo progetto
- rm, deploy, publish e database vero nei deny
- git push nell'ask
- Regole controllate con /permissions
- Prova fatta: test liberi, rm bloccato, push con domanda
- Nessun --dangerously-skip-permissions sul tuo computer
Domande frequenti
Devo rifarlo in ogni progetto?
Il file nel progetto vale per quel progetto, e se lo salvi su git anche per chi ci lavora con te. Le regole che vuoi ovunque, tipo il deny su rm, mettile in ~/.claude/settings.json, nella tua cartella utente. Un deny blocca anche se un altro file ha un allow per lo stesso comando.
Uso Claude Code in VS Code: vale lo stesso?
Le regole sì. La modalità di partenza no: l'estensione non legge defaultMode dal file del progetto. La scegli dal selettore in basso nella casella del prompt, dove accept edits si chiama «Edit automatically».
Meglio accept edits o auto?
Accept edits se vuoi sapere esattamente cosa passa da solo. Auto per i lavori lunghi senza domande, sapendo che il secondo modello è un giudizio, non una garanzia. In tutte e due le regole restano attive e l'ask ti chiede comunque. Se con Shift+Tab auto non compare, il tuo account, il tuo modello o la tua organizzazione non la permettono.