PreToolUse: proteggere file in Claude Code
Configura PreToolUse in Claude Code: deny, ask, percorsi protetti e limiti dei controlli. Una regola piccola da verificare prima dell’uso.
Tempo di lettura: 11 min

PreToolUse è l’evento di Claude Code da usare quando un controllo deve intervenire prima dell’esecuzione di una tool call. L’handler legge nome e input dello strumento e può restituire una decisione, fra cui ask o deny. È adatto a regole circoscritte, come impedire edit a una cartella protetta; la sua copertura dipende però dai tool intercettati e dalla regola effettivamente applicata. PreToolUse nella reference ufficiale.
Proteggere un file significa prima definire da quali operazioni e con quale confine. Uno stesso percorso può essere modificato con un editor, uno script shell o un tool esterno. Una regola che vede soltanto Edit e Write non controlla automaticamente gli altri canali. Per introdurre il meccanismo consulta la guida ai Claude Code Hooks; qui il focus è costruire un controllo preventivo piccolo e verificabile.
Documentazione verificata il 9 ottobre 2026. Il codice è un esempio didattico con percorsi sintetici, non eseguito in questa guida. Non va presentato come protezione completa di segreti o dati aziendali.
In sintesi
- PreToolUse controlla una tool call prima dell’azione.
- Il matcher seleziona il tool; lo script interpreta il suo input.
- Un percorso va normalizzato prima di confrontarlo con una regola.
- Shell e altri canali di scrittura richiedono controlli separati.
- Un errore del hook e un deny esplicito sono risultati diversi.
Quale regola sui file conviene definire per prima?
Una buona prima regola è stretta: “I tool Edit e Write non devono modificare file dentro la cartella config/protected di questo repository”. La cartella deve essere scelta perché il progetto ne conosce la responsabilità, non perché il suo nome sembra sensibile. La regola va documentata accanto allo script: chi può modificare quei file, quale percorso alternativo usare e quale operazione è esclusa dal controllo.
Evita un elenco infinito di nomi vaghi come “importante”, “produzione” o “privato”. Un criterio comprensibile è più facile da provare: percorso interno al progetto, directory specifica e azione di modifica. Se il sistema deve impedire lettura e scrittura di credenziali, serve anche lavorare su permessi del filesystem, disponibilità dei dati nell’ambiente e strumenti consentiti.
Una policy dovrebbe dichiarare la propria incompletezza operativa: il hook proposto in questa pagina controlla solo le chiamate selezionate. La discussione più ampia su AI e sicurezza dei dati aiuta a separare il controllo nel workflow dall’accesso effettivo alle informazioni. Una notazione onesta del perimetro è utile a chi mantiene il progetto.
Come arrivano nome del tool e percorso del file?
Per un handler command, Claude Code invia un oggetto JSON sullo standard input. Nel caso di una chiamata di modifica sono rilevanti tool_name e il percorso in tool_input. Lo script deve trattare questo oggetto come dati: non concatenarlo dentro un comando shell e non eseguire il contenuto del file per “capirlo”. Input e output dei hook.
Il primo passo è verificare che il JSON sia leggibile. Il secondo è controllare il tool previsto. Il terzo è estrarre un percorso valido. Non ha senso applicare silenziosamente la stessa regola quando il campo è assente: quella condizione merita una decisione esplicita e una prova dedicata. Per uno snippet dimostrativo può essere ragionevole chiedere attenzione invece di inventare un percorso predefinito.
Non stampare l’intero oggetto per il debug. Può contenere informazioni inutili alla diagnosi. Bastano nome dell’evento, categoria dell’esito e un identificatore non sensibile della prova. Per indagare un problema usa il percorso di debug dei Hooks, mantenendo separati log tecnici e output di decisione.
Un esempio di controllo su una cartella protetta
Il seguente script Python interpreta un input sintetico, normalizza il percorso e nega le modifiche dentro config/protected. Richiede Python 3 e CLAUDE_PROJECT_DIR. Usa una decisione ask quando l’input necessario manca. Non è stato eseguito in questa guida e non copre Bash, collegamenti modificati durante l’esecuzione o processi esterni. Il contratto della decisione è descritto nella reference. Decision control.
import json
import os
import sys
from pathlib import Path
def decide(value, reason):
print(json.dumps({
"hookSpecificOutput": {
"hookEventName": "PreToolUse",
"permissionDecision": value,
"permissionDecisionReason": reason
}
}))
try:
event = json.load(sys.stdin)
root = Path(os.environ["CLAUDE_PROJECT_DIR"]).resolve()
name = event.get("tool_name")
raw = event.get("tool_input", {}).get("file_path")
if name not in {"Edit", "Write"}:
sys.exit(0)
if not isinstance(raw, str) or not raw:
decide("ask", "Percorso assente: verifica la chiamata.")
sys.exit(0)
target = Path(raw)
if not target.is_absolute():
target = root / target
target = target.resolve()
protected = (root / "config" / "protected").resolve()
if target == protected or protected in target.parents:
decide("deny", "Cartella protetta: usa il percorso di review.")
except (ValueError, KeyError, OSError, TypeError, AttributeError):
decide("ask", "Controllo non disponibile: verifica prima di procedere.")
L’assenza di una decisione nel caso normale lascia proseguire il flusso ordinario dei permessi. Non significa che lo script stia autorizzando qualsiasi operazione nel repository. Mantieni questo comportamento intenzionale: un gate dedicato a una cartella non deve diventare un generatore indiscriminato di allow.
Come registrare lo script senza perdere altri settings?
Il file .claude/settings.json può contenere una registrazione come la seguente. Il comando invoca uno script locale al progetto; il percorso contiene virgolette perché un checkout può includere spazi. Integra il campo nel JSON esistente invece di sostituire l’intero file. Configurazione dei Hooks.
{
"hooks": {
"PreToolUse": [
{
"matcher": "Edit|Write",
"hooks": [
{
"type": "command",
"command": "python3 \"$CLAUDE_PROJECT_DIR/.claude/hooks/protect_files.py\""
}
]
}
]
}
}
Una regola di progetto deve essere leggibile anche dal collega che clona il repository domani. Conserva lo script, il requisito Python e la lista dei casi da provare. Non includere nel file condiviso percorsi della home dell’autore o informazioni estratte da un cliente. Apri /hooks nella sessione e controlla che la registrazione compaia sotto l’evento giusto.
Un plugin ha un percorso di distribuzione proprio. Se il team vuole confezionare la policy insieme ad altre personalizzazioni, consulta Mods per team e sicurezza. Il packaging non elimina la necessità di leggere il codice eseguito sul computer dello sviluppatore.
Ask, deny e allow: quale comportamento scegliere?
deny è appropriato quando una regola precisa rifiuta quella tool call. ask porta l’operazione a una decisione di permesso. allow esprime un’autorizzazione del controllo, ma nei settings hook non scavalca le permission rules deny e ask. Il rapporto fra hook e permessi va verificato nella documentazione corrente. Permission evaluation.
| Condizione osservata | Risposta proposta | Perché |
|---|---|---|
| Percorso dentro la cartella protetta | deny |
Viola la regola dichiarata |
| Percorso necessario assente | ask |
Il controllo non ha i dati per decidere |
| Tool diverso da Edit o Write | Nessuna decisione | Fuori dallo scope dello script |
| File ordinario esterno alla cartella | Nessuna decisione | Restano i permessi del workflow |
| Comando non avviabile | Esito tecnico da verificare | Non è un deny della policy |
La motivazione deve essere utilizzabile: “Cartella protetta, passa dalla review” permette di correggere il percorso del lavoro. “Operazione pericolosa” è più vaga e può indurre tentativi casuali. Quando chiedi una decisione non allegare il contenuto sensibile che stai cercando di proteggere; spiega la categoria di rischio e il riferimento alla policy.
Perché il confronto del percorso è una parte critica?
Un nome relativo può includere ..; un percorso assoluto può passare fuori dal repository; un collegamento simbolico può puntare altrove. Confrontare soltanto il testo iniziale produce falsi positivi e falsi negativi: config/protected-copy non è la stessa directory di config/protected. La normalizzazione rende il confronto più sensato, ma non converte lo script in una sandbox.
Il sistema reale può cambiare fra controllo e azione. Un file può essere rinominato da un altro processo; un collegamento può essere sostituito; un programma può interpretare il percorso in modo diverso. Per questo il confine del filesystem e i permessi dell’account contano quando il dato è critico. Lo snippet dimostra la logica di una regola, non una garanzia contro tutte le condizioni di concorrenza.
Prepara prove con una directory dal nome simile, un percorso relativo, un percorso assoluto e un collegamento sintetico. Registra l’esito atteso prima di eseguire. Se una prova fallisce, correggi la regola e ripeti anche le prove che prima passavano: una modifica al matching può cambiare la copertura in entrambe le direzioni.
Come controllare i comandi shell senza una falsa garanzia?
Una shell può combinare programmi, redirezioni e sottocomandi. Controllare che il comando inizi con una parola vietata non descrive ogni effetto possibile. Anche strumenti ordinari possono modificare file attraverso opzioni o script. Le permission rules hanno una propria interpretazione dei comandi; il matcher del hook, invece, seleziona prima il tool. Regole e sottocomandi Bash.
Per una PMI è preferibile ridurre gli strumenti autorizzati e dare al processo un ambiente di prova con soli dati necessari. Un hook può segnalare una categoria di comando o chiedere attenzione, ma non dovrebbe essere venduto come parser completo della shell. Se il requisito è prevenire scritture su un database, usa anche un account con privilegi appropriati.
Blast Radius può rendere visibile l’impatto di alcune chiamate attraverso un mod. Il suo valore di anteprima non dimostra la copertura di ogni grafia di comando. Quando la chiamata riguarda un tool di un server esterno, Hooks e MCP approfondisce nomi canonici e controllo dell’integrazione.
Che cosa succede se il controllo fallisce?
Un processo che termina con errore, un JSON non valido e una decisione deny sono tre esiti differenti. Non assumere che “il hook non ha risposto” significhi “la tool call non può procedere”. La release 2.1.295 dell’8 ottobre 2026 introduce onFailure: "block" per command e HTTP. Qui è verificata l’introduzione, non lo schema completo per ogni evento: non viene quindi proposto un campo di configurazione inventato. Release Anthropic.
Per un controllo vincolante prova l’assenza del runtime, un input malformato e un timeout in un ambiente sacrificabile. Osserva cosa accade alla chiamata oltre al messaggio mostrato. Se la regola deve impedire sempre una classe di operazioni, il progetto non può dipendere da un comportamento d’errore non verificato sulla versione effettivamente installata.
Quale prova documentare per un gate preventivo?
Descrivi una chiamata consentita, una chiamata rifiutata e un guasto del controllo. Per ognuna conserva input sintetico, versione del runtime, risultato del hook ed effetto osservato sul tool. Non riportare contenuti riservati dei file né variabili ambiente complete.
Due applicazioni italiane con confini espliciti
Esempio ipotetico, non testato: uno studio di consulenza a Milano sviluppa un generatore di documenti usando soltanto modelli fittizi. Vuole evitare edit involontari al template contrattuale approvato. Può spostare quel template in una directory riconoscibile e applicare un controllo sui tool di modifica. La review separata del template resta necessaria; il hook non certifica il contenuto legale e non impedisce qualsiasi programma di alterarlo.
Esempio ipotetico, non testato: un’officina di Verona prova un importatore di appuntamenti in un ambiente separato. I file di configurazione del gestionale sono esclusi dal compito. Il team definisce una cartella protetta e verifica che un edit sintetico venga rifiutato, mentre uno script nella cartella di lavoro resti disponibile. Prima di collegare dati reali controlla anche privilegi del processo e canali di scrittura alternativi.
In entrambi i casi la protezione produce un risultato più utile se indica il percorso autorizzato della modifica: una branch di review, una configurazione di prova o una responsabilità di manutenzione. Bloccare senza dare un’alternativa può generare tentativi ripetuti che rendono il lavoro meno comprensibile.
Come gestire una modifica intenzionale ai file protetti?
Una cartella protetta può richiedere manutenzione legittima. Definisci un percorso di review che identifichi chi propone il cambiamento, dove viene preparato e chi verifica il diff. Non aggiungere nello script un’eccezione generica basata su una frase del prompt: renderebbe il controllo dipendente da testo arbitrario invece che dalla policy dichiarata.
La regola deve spiegare come trattare un aggiornamento autorizzato senza trasformarsi in un ostacolo opaco. Il team può preparare la modifica in un ambiente separato e applicare il proprio processo di approvazione. Un rifiuto del hook rimane una decisione sulla chiamata osservata; non è un giudizio sulla legittimità generale del lavoro richiesto.
Conserva anche la motivazione della protezione. Se la directory non ha più quella responsabilità, la policy va aggiornata e provata, anziché aggirata a ogni modifica. Una regola mantenuta per inerzia crea eccezioni non documentate; una regola aggiornata conserva un confine verificabile e un percorso per i cambiamenti necessari.
Come mantenere la regola mentre il progetto cambia?
La directory può essere spostata; un nuovo tool può entrare nel workflow; un subagent può usare Bash dove l’autore usava Write. La revisione della policy deve accompagnare questi cambiamenti. In Hooks per subagent e team il punto centrale è applicare il controllo nel livello giusto e identificarne il ruolo.
Gli errori da evitare sono usare nomi di file vaghi, ignorare le normalizzazioni, stampare l’input completo nei log, restituire sempre allow e confondere un test successivo con il blocco preventivo. PostToolUse per formatter e test serve a un’altra responsabilità: segnala un problema dopo la modifica e non la annulla.
Per un’applicazione che gestisce informazioni aziendali, la progettazione del software su misura può includere confini di accesso, ambienti di prova e hook verificati insieme. Parti da una cartella e da una classe di operazioni, poi amplia soltanto dopo aver osservato un’esigenza reale e definito prove aggiornabili.
Metodo e fonti delle guide di Giallo Studio
Come lo applichiamo in azienda
Risorse correlate
Claude Code Hooks: guida pratica in italiano
PostToolUse: formatter e test in Claude Code
Notifiche Claude Code: hook locali e permessi
SessionStart: contesto dopo compaction
Stop hook: verifiche senza loop in Claude Code
Mods di Claude: cosa sono e quando servono in Claude Code
Claude AI per codice e sviluppoFAQ
PreToolUse quando viene eseguito?
Prima dell’esecuzione della tool call. Il controllo può leggere nome e input del tool e restituire una decisione supportata dall’evento.
Come si impediscono modifiche ai file protetti?
Si intercettano i tool di modifica e si verifica il percorso normalizzato rispetto alla regola scelta. È necessario coprire anche gli altri canali che possono scrivere sul filesystem.
Qual è la differenza fra ask e deny?
Ask richiede una decisione di permesso; deny rifiuta quella chiamata. La motivazione deve spiegare quale condizione ha causato la decisione.
Una regex può proteggere tutti i comandi shell?
No. Shell composte, redirezioni, sottocomandi e programmi differenti rendono insufficiente una verifica del solo prefisso. Servono permessi e confini del sistema coerenti.
Allow scavalca le permission rules?
Per i settings hook PreToolUse le regole deny e ask dei permessi continuano a essere valutate. Non usare allow come autorizzazione generale del progetto.
Un hook che va in timeout blocca sempre?
Non va presunto. La release 2.1.295 introduce onFailure block per command e HTTP; lo schema completo e le interazioni vanno verificati sulla versione installata.