Claude Code veilig maken: zo blokkeer je gevaarlijke commando's automatisch
Tutorials

Claude Code veilig maken: zo blokkeer je gevaarlijke commando's automatisch

· 9 min leestijd

Duizenden developers zetten Claude Code in de stand waarin de AI-agent nooit meer om toestemming vraagt. Dat werkt heerlijk, tot het ene commando voorbijkomt dat een database leegtrekt of een server sloopt. Wat bijna niemand weet: Claude Code heeft twee ingebouwde mechanismes waarmee je zulke rampcommando's hard blokkeert, zonder de agent af te remmen. In deze tutorial bouw je dat vangnet stap voor stap, met code die je letterlijk kunt kopiëren en een testset die bewijst dat het werkt.

Kort antwoord

Je beveiligt Claude Code met twee lagen: deny-regels in ~/.claude/settings.json blokkeren commando's op patroon, en een PreToolUse-hook (een klein script) leest élk commando en blokkeert rampen met exit-code 2. Beide werken ook als Claude zonder toestemmingsvragen draait, kosten geen tokens en draaien in milliseconden.

Waarom zou je een AI-agent afremmen die je zelf vertrouwt?

Een AI-agent met volledige terminal-toegang kan alles wat jij kunt, inclusief de dingen die je nooit zou willen. Wie Claude Code serieus inzet, schakelt vroeg of laat de toestemmingsvragen uit: de agent draait dan met de vlag --dangerously-skip-permissions en voert elk commando direct uit. Voor geautomatiseerde workflows is dat de makkelijkste stand, maar niet de enige. Claude Code kent ook voorzichtiger opties: met allow-regels keur je vooraf precies de commando's goed die een workflow nodig heeft, en de dontAsk-modus weigert automatisch alles wat niet op die lijst staat, zonder te vragen. In de praktijk kiezen veel teams toch voor de volledige bypass, omdat een strakke allowlist bij breed agent-werk al snel knelt. Agents die 's nachts zelfstandig draaien kunnen immers niet wachten op een mens die op "toestaan" klikt. Juist in die stand heb je een eigen vangnet nodig.

Daar zit de spanning. Volgens de Newcom AI Monitor werken 4,6 miljoen Nederlanders inmiddels met AI op de werkvloer, en uit data van TheAIDaily blijkt dat 44 procent van de mkb-medewerkers al bedrijfsdata deelde met een gratis AI-tool. AI krijgt dus steeds meer toegang tot systemen die ertoe doen. Een agent die bij je productie-database en je servers kan, is geweldig zolang het goed gaat. Eén verkeerd geïnterpreteerde opdracht is genoeg voor een heel slechte dag.

Dit is geen theoretisch risico. Toen Claude Code zelfstandig pull requests begon te openen, was de eerste reactie van developers het eisen van een uitknop. De behoefte aan een noodrem groeit mee met de autonomie. Het goede nieuws: die noodrem kun je zelf bouwen, in een kwartier.

Wat is het verschil tussen deny-regels en hooks?

Deny-regels zijn patroonfilters die Claude Code zelf afdwingt, hooks zijn eigen scripts die de inhoud van elk commando lezen. Ze vullen elkaar aan en je wilt ze allebei. De verschillen op een rij:

EigenschapDeny-regelsPreToolUse-hookSterkste optie
Hoe het werktPatroonvergelijking op het begin van het commandoScript leest het volledige commandoHook
Ziet binnen ssh- en mysql-stringsNeeJaHook
InstallatieRegel toevoegen in settings.jsonScript schrijven en registrerenDeny-regels
Kan kapotNee, ingebouwdJa, als het script fouten bevatDeny-regels
Werkt zonder toestemmingsvragen (bypass)JaJaGelijk
Kosten per commandoGeenEnkele milliseconden, geen tokensGelijk

Even voor de beeldvorming: een deny-regel is een bordje "verboden toegang" bij de deur, een PreToolUse-hook is de portier die elke bezoeker aankijkt en zijn tas controleert. Het bordje houdt de argeloze bezoeker tegen. De portier ziet ook wat er in de tas zit.

Deny-regels: de snelste bescherming

Deny-regels zet je in het bestand ~/.claude/settings.json en ze gelden direct voor alle projecten. Elke regel is een prefix-match: Bash(sudo rm *) weigert elk commando dat begint met sudo rm. Het commando wordt dan niet uitgevoerd en de agent krijgt een foutmelding met de reden, zodat hij een veilig alternatief kiest.

Dit is een verstandige startset:

{
  "permissions": {
    "deny": [
      "Bash(sudo rm *)",
      "Bash(mkfs*)",
      "Bash(shutdown *)",
      "Bash(reboot*)",
      "Bash(crontab -r*)",
      "Bash(git push --force *)",
      "Bash(git clean -f*)",
      "Bash(chmod -R 777 *)"
    ]
  }
}

Elke regel hier voorkomt een specifiek soort ellende: crontab -r wist je complete takenplanning zonder bevestiging, git push --force kan de historie van een repository vernietigen en git clean -f gooit bestanden weg die niet in git staan, zoals je .env met wachtwoorden. De volledige syntax staat in de officiële documentatie van Anthropic over settings.

Er zit wel een gat in deze aanpak. Een prefix-match kijkt alleen naar het begin van het commando. Het commando ssh root@server "rm -rf /" begint met ssh, dus geen enkele rm-regel vangt het af. Wie servers beheert via een AI-agent heeft meer nodig.

Hoe werkt een PreToolUse-hook precies?

Een PreToolUse-hook is een script dat Claude Code aanroept vlak vóórdat een commando wordt uitgevoerd, met de macht om het tegen te houden. Het mechanisme is verrassend simpel. Claude Code stuurt de complete tool-aanroep als JSON naar je script. Het script leest het commando, beslist, en antwoordt met een exit-code: 0 betekent doorlaten, 2 betekent hard blokkeren. Bij een blokkade wordt het commando niet uitgevoerd en krijgt de agent jouw uitlegtekst te zien.

Terminal waarin de guard een rm -rf binnen een ssh-commando en een DROP DATABASE blokkeert, terwijl rm -rf node_modules gewoon doorgaat
De guard in actie: rampcommando's worden geblokkeerd met uitleg, ook verpakt in ssh. Gewoon opruimwerk gaat door.

Omdat je script de vólledige commandotekst ziet, vangt het ook af wat binnen een ssh-aanroep of een mysql -e zit verstopt. Dat is het grote verschil met deny-regels. En belangrijk om te weten: hooks draaien in élke stand van Claude Code, ook als alle toestemmingsvragen uitstaan. De bypass-vlag slaat alleen het vragen over, niet de hooks.

Stap voor stap: de catastrofe-guard bouwen

De guard hieronder blokkeert vier categorieën onherstelbare rampen en laat al het normale werk door. In drie stappen staat hij aan.

Stap 1. Zet dit script neer als ~/bin/claude-guard.sh en maak het uitvoerbaar met chmod +x ~/bin/claude-guard.sh:

#!/bin/bash
# Blokkeer catastrofale commando's, ook verpakt in ssh of mysql -e.
input=$(cat)
cmd=$(printf '%s' "$input" | jq -r '.tool_input.command // empty' 2>/dev/null)
[ -z "$cmd" ] && exit 0

block() { echo "GEBLOKKEERD: $1" >&2; exit 2; }

# 1. rm met recursieve flag op een root- of home-pad
if printf '%s' "$cmd" | grep -qE 'rm[[:space:]]+(-[a-zA-Z]+[[:space:]]+)*-[a-zA-Z]*[rR][a-zA-Z]*[[:space:]]+(-[a-zA-Z]+[[:space:]]+)*["'"'"']?(/|/\*|~|\$HOME|/home/?[a-z0-9_]*/?|/Users/?[A-Za-z0-9_]*/?)["'"'"']?([[:space:]]|$)'; then
  block "recursief verwijderen van een root- of home-pad is verboden."
fi

# 2. Schijven formatteren
if printf '%s' "$cmd" | grep -qiE '(^|[[:space:]"'"'"';|&])mkfs(\.[a-z0-9]+)?[[:space:]]'; then
  block "schijven formatteren is verboden."
fi

# 3. Complete databases verwijderen (werkt ook binnen mysql -e en ssh)
if printf '%s' "$cmd" | grep -qiE '\bDROP[[:space:]]+(DATABASE|SCHEMA)\b'; then
  block "databases verwijderen gebeurt alleen handmatig."
fi

# 4. Crontab wissen
if printf '%s' "$cmd" | grep -qE '\bcrontab[[:space:]]+-r\b'; then
  block "crontab -r wist je hele takenplanning zonder bevestiging."
fi

exit 0

Stap 2. Registreer het script als hook in ~/.claude/settings.json, in hetzelfde bestand als je deny-regels:

{
  "hooks": {
    "PreToolUse": [
      {
        "matcher": "Bash",
        "hooks": [
          {
            "type": "command",
            "command": "bash \"$HOME/bin/claude-guard.sh\"",
            "timeout": 10
          }
        ]
      }
    ]
  }
}

Stap 3. Controleer dat de JSON klopt. Een kapot settings-bestand schakelt geruisloos ál je instellingen uit, dus deze check is geen overbodige luxe:

jq -e '.permissions.deny, .hooks.PreToolUse' ~/.claude/settings.json

Krijg je de inhoud netjes terug, dan staat het vangnet aan voor elke nieuwe sessie. Al draaiende sessies pikken de wijziging op na een herstart. Meer over alle hook-types en velden lees je in de hooks-documentatie van Anthropic.

Hoe weet je zeker dat de guard werkt?

Een guard die stilletjes niets doet is gevaarlijker dan geen guard, dus testen is verplicht. Dat kan zonder Claude Code: je voert het script precies zo aan als Claude Code dat zou doen, met een regel JSON op de standaardinvoer:

echo '{"tool_input":{"command":"rm -rf /"}}' | bash ~/bin/claude-guard.sh; echo "exit=$?"

Zie je de GEBLOKKEERD-melding en exit=2, dan werkt de kern. Test daarna twee kanten op: rampen die geblokkeerd moeten worden én normaal werk dat gewoon door moet. Een testset van een handvol gevallen per kant draait in een seconde en voorkomt dat je guard te streng of te soepel is.

Terminal met de uitkomst van het testharnas: negen rampcommando's geblokkeerd met exit 2, vier normale commando's doorgelaten met exit 0
Het testharnas test beide kanten: blokkeert de guard alle rampen, en laat hij normaal werk door?

Overigens bewees de guard uit deze tutorial zichzelf op een onverwacht moment. Tijdens het opzetten blokkeerde hij zijn eigen testmail: de mailtekst legde uit welke patronen verboden zijn en noemde die letterlijk, en de guard leest álles wat door de terminal gaat. De uitlegtekst over DROP DATABASE werd dus zelf tegengehouden. Onhandig voor die ene mail. Maar wel het definitieve bewijs dat er niets langs glipt.

Waar houdt de bescherming op?

Dit vangnet beschermt tegen ongelukken, niet tegen opzet. Wie dat verschil kent, weet precies wat hij heeft. Een guard die op tekstpatronen filtert is te omzeilen: een commando kan in een variabele worden opgebouwd, in een tijdelijk script worden geschreven of worden gecodeerd. Een AI-agent die actief om de regels heen wil, vindt een weg. Daar is de guard niet voor. Hij is er voor het realistische scenario: de agent die een opdracht nét verkeerd interpreteert en met de beste bedoelingen iets onherstelbaars doet.

Wie een hardere grens nodig heeft, kijkt naar de sandbox-modus van Claude Code. Die isoleert commando's op besturingssysteemniveau, met een eigen netwerk- en bestandssysteembeleid. Dat is de zwaarste bescherming, maar voor veel automatiseringswerk ook te beperkend.

Er speelt ook een zakelijke kant. Onder de AVG blijft jouw organisatie verantwoordelijk voor wat er met klantdata gebeurt, ook als een AI-agent de handeling uitvoert. En de AI Act verwacht sinds februari 2025 van organisaties die AI inzetten dat ze zich er aantoonbaar voor inspannen dat hun mensen AI-geletterd zijn. Een gedocumenteerd vangnet rond je AI-agents is voor beide een concreet, uitlegbaar antwoord: je kunt laten zien dat autonomie bij jou samengaat met controle.

Drie stappen, een kwartier werk

De volgorde om dit vandaag op te zetten is dezelfde als de volgorde van dit artikel. Begin met de deny-regels: acht regels kopiëren in settings.json, direct resultaat. Bouw daarna de guard: het script hierboven dekt de vier grootste rampcategorieën en is aan te passen aan je eigen omgeving. Sluit af met de test, twee kanten op. Wie alle drie de stappen doet, heeft in een kwartier een vangnet dat elke sessie meedraait, niets kost en precies één taak heeft: die ene slechte dag voorkomen.

Meer over autonome agents en wat er in Claude Code verandert, vind je in onze Claude Code-hub. Wil je dit soort praktische tutorials in je inbox, meld je dan aan voor de dagelijkse AI-nieuwsbrief van TheAIDaily.

Veelgestelde vragen

Werken deny-regels en hooks ook als Claude Code zonder toestemmingsvragen draait?

Ja. De bypass-modus slaat alleen het vragen om toestemming over. Deny-regels en hooks worden in elke stand afgedwongen, dus ook in volledig autonome sessies die 's nachts draaien.

Kost een PreToolUse-hook tokens of geld?

Nee. Een command-hook is een gewoon shellscript dat lokaal draait, zonder AI-model. Het draait in enkele milliseconden per commando. Alleen bij een blokkade komt er een korte foutmelding in het gesprek terecht, en dat zijn hooguit enkele tientallen tokens.

Kan de AI-agent de guard zelf uitschakelen?

Technisch wel, als het settings-bestand niet beschermd is: de agent kan bestanden bewerken, dus ook de configuratie. Daarom is dit vangnet een bescherming tegen ongelukken en niet tegen opzet. Uitschakelen vereist een expliciete, zichtbare handeling, en dat is precies de drempel die je wilt.

Vangt de guard ook commando's af die binnen ssh of mysql verstopt zitten?

Ja, en dat is het grootste voordeel boven deny-regels. De hook ontvangt de volledige commandotekst en scant alles, dus ook een rm binnen een ssh-aanroep of een DROP-statement binnen mysql -e. Deny-regels zien alleen het begin van het commando en missen dit soort verpakte opdrachten.

Michael Groeneweg
Geschreven door Michael Groeneweg AI-consultant bij Digital Impact en oprichter van UnicornAI.nl

Michael is AI-consultant bij Digital Impact in Rotterdam en oprichter van UnicornAI.nl, waar hij AI-oplossingen en SaaS-integraties bouwt voor bedrijven. Al tien jaar ondernemer, en sinds een paar jaar weigert hij iets te doen waar geen AI in verweven zit, zakelijk noch privé, tot mild ongenoegen van zijn omgeving. Zijn reizen door de wereld zijn inmiddels een serie experimenten in wat AI wel en niet kan vanaf een terrasje in Lissabon of een treinstation in Tokio. Hij test obsessief nieuwe tools, bouwt oplossingen voor klanten, en vindt dat niemand de hype moet geloven, maar ook niemand meer kan doen alsof AI niet alles verandert. Houdt van goede koffie, lange vluchten en mensen die met AI bouwen in plaats van er alleen over praten.

Gemaakt door een mens, met AI als assistent bij research en redactie. Meer over onze werkwijze in de AI-disclosure en het redactiestatuut.