Was es ist und warum es zählt
Im Video ging es um Jev: eine KI, die keinen Text schreibt, sondern mit einem festen Typ antwortet, also einer Auswahl, einer Punktzahl oder einem Wahr/Falsch, mit den Wahrscheinlichkeiten und wie sicher sie ist. Was mit der Antwort passiert, entscheidet dein Code. Vorerst gibt es eine Warteliste. Hier interessiert mich nur eine Idee: eine Kontrolle zwischen der KI und dem Befehl, bevor der Befehl startet. Die kann dein Claude Code schon heute haben, ohne auf einer Liste zu warten.
Das Problem ist einfach. Claude Code startet Befehle im Terminal deines Computers. Fast immer sind sie harmlos: ein Paket installieren, die Tests laufen lassen, eine Datei lesen. Aber manche lassen sich nicht rückgängig machen. rm -rf löscht einen Ordner mit allem Inhalt, ohne Umweg über den Papierkorb. git push --force überschreibt die Historie des Projekts online. git reset --hard wirft die Änderungen weg, die du noch nicht in einem Commit gesichert hast. Ein drop table löscht eine Tabelle der Datenbank.
Claude muss sich nicht absichtlich vertun. Es reicht eine falsch verstandene Anweisung, ein falscher Pfad, eine lange Sitzung, in der er durcheinandergekommen ist. Und wenn du die Bestätigungen schnell abnickst oder sie reduziert hast, um schneller zu sein, geht der Moment, in dem du Nein sagen konntest, vorbei, ohne dass du es merkst.
Eine Sache solltest du außerdem wissen. Das Rewind von Claude Code (zweimal Esc oder /rewind) macht Änderungen rückgängig, die mit seinen Datei-Werkzeugen gemacht wurden, aber nicht die von Befehlen im Terminal. Wenn ein rm eine Datei löscht, holt Rewind sie nicht zurück.
Die Bremse muss also vorher rein. Zwei Wege: eine Liste verbotener Befehle, der einfache, und ein kleines Skript, das jeden Befehl liest, bevor er startet, der schlauere. Danach kommt der Prompt, mit dem Claude sie einrichtet.
1. Die Liste verbotener Befehle
Claude Code liest die Projekteinstellungen aus der Datei .claude/settings.json im Projektordner. Wenn du dieselben Regeln in allen Projekten willst, nimm ~/.claude/settings.json in deinem Benutzerordner. Schreib Folgendes hinein:
{
"permissions": {
"deny": [
"Bash(rm -rf *)",
"Bash(git push --force *)",
"Bash(git reset --hard *)"
]
}
}Ein „deny“ gewinnt immer gegen jede erteilte Erlaubnis. Claude Code prüft zuerst die Deny-Regeln, dann die, die nach Bestätigung fragen, dann die, die erlauben. Selbst wenn du also irgendwann bei einem Befehl „Ja, nicht mehr fragen“ geantwortet hast, bleibt das Deny stärker. Und es gilt in jedem Berechtigungsmodus, auch in bypassPermissions.
Die Grenze: Die Regel blockiert den Befehl genau so geschrieben, nicht seine Varianten. Bash(rm -rf *) stoppt rm -rf build/, aber nicht denselben Befehl in bash -c oder geschrieben als /bin/rm -rf build/. Auch rm -fr mit vertauschten Buchstaben kommt durch. Es ist ein Netz, keine Mauer.
2. Der Wächter: ein Hook, der jeden Befehl prüft
Ein Hook ist ein Skript, das Claude Code von selbst zu einem bestimmten Zeitpunkt startet. Der, den wir brauchen, heißt PreToolUse: Er läuft vor jedem Werkzeugaufruf, und mit dem Filter „Bash“ schaut er nur auf Terminalbefehle. Er bekommt den Befehl als JSON. Wenn das Skript mit Code 2 endet, startet der Befehl nicht und Claude liest den Grund, den du geschrieben hast. Endet es mit 0, läuft der Befehl über die normalen Berechtigungen weiter.
Der Vorteil gegenüber der Liste: Das Skript sucht die gefährlichen Wörter im ganzen Text des Befehls. Es erwischt also auch ein rm -rf, das in bash -c versteckt ist.
Leg im Projekt die Datei .claude/hooks/waechter.sh an und füge Folgendes ein:
#!/bin/bash
command -v jq >/dev/null || { echo "jq wird benötigt" >&2; exit 2; }
CMD=$(jq -r '.tool_input.command')
if echo "$CMD" | grep -Eiq 'rm -rf|git push --force|git reset --hard|drop table'; then
echo "Blockiert: destruktiver Befehl. Frag mich zuerst um Erlaubnis." >&2
exit 2
fi
exit 0Mach es ausführbar mit chmod +x .claude/hooks/waechter.sh. Das Skript nutzt jq, um das JSON zu lesen: Wenn du es nicht hast, installierst du es auf dem Mac mit brew install jq. Fehlt es, blockiert die erste Zeile des Skripts jeden Befehl, statt ihn durchzulassen.
Dann füge in .claude/settings.json neben „permissions“ diesen Teil hinzu:
"hooks": {
"PreToolUse": [
{
"matcher": "Bash",
"hooks": [{ "type": "command", "command": "\"$CLAUDE_PROJECT_DIR\"/.claude/hooks/waechter.sh" }]
}
]
}$CLAUDE_PROJECT_DIR steht für den Projektordner, und die Anführungszeichen drumherum halten den Pfad zusammen, auch wenn er Leerzeichen enthält. Zusammengesetzt ergeben die beiden Teile eine Datei wie diese:
{
"permissions": {
"deny": [
"Bash(rm -rf *)",
"Bash(git push --force *)",
"Bash(git reset --hard *)"
]
},
"hooks": {
"PreToolUse": [
{
"matcher": "Bash",
"hooks": [{ "type": "command", "command": "\"$CLAUDE_PROJECT_DIR\"/.claude/hooks/waechter.sh" }]
}
]
}
}Die Liste im Skript erweiterst du selbst: Nimm die Befehle auf, die in deinem Projekt Schaden anrichten, zum Beispiel den, der die Datenbank leert, oder das Skript, das die App veröffentlicht.
3. Wenn du es nicht von Hand machen willst
Du kannst Claude bitten, alles zu machen: das Skript, die Einstellungsdatei und den Test. Schreib ihm:
Richte in .claude/settings.json einen PreToolUse-Hook ein, der destruktive Befehle blockiert, bevor sie starten (rm -rf, git push --force, git reset --hard, drop table), und füge dieselben Regeln in die Deny-Liste der Berechtigungen ein. Dann leg einen leeren Testordner an und prüf, dass rm -rf darauf blockiert wird.
Wenn er fertig ist, lies die Datei .claude/settings.json und das Skript selbst. Es sind nur ein paar Zeilen. Wenn dir etwas komisch vorkommt, lass es dir erklären:
Zeig mir den Inhalt von .claude/settings.json und vom Hook-Skript und erklär mir Zeile für Zeile, was es blockiert und was es durchlässt.
4. Der Test
Eine Regel, die du nicht getestet hast, ist eine Regel, von der du hoffst, dass sie funktioniert. Tipp /hooks in Claude Code: Es öffnet sich die Liste der eingerichteten Hooks, und deiner muss unter PreToolUse auftauchen. Normalerweise übernimmt Claude Code Änderungen an der Einstellungsdatei sofort. Wenn dein Hook nicht auftaucht, schließ Claude Code und öffne es neu.
Achte auf ein Detail: Mit aktivem Deny stoppt schon die Liste ein normal geschriebenes rm -rf. Um zu sehen, ob der Wächter allein funktioniert, bitte Claude um denselben Befehl in bash -c: Die Liste sieht ihn nicht, der Wächter schon.
Leg einen leeren Ordner namens waechter-test an und versuch, ihn mit bash -c 'rm -rf waechter-test' zu löschen. Dann sag mir, was dich gestoppt hat: die Deny-Liste oder der Hook.
Wenn der Befehl durchkommt, arbeitet der Wächter nicht: Meistens ist das Skript nicht ausführbar oder der Pfad in settings.json falsch, und dann bekommt Claude Code keinen Code 2 und lässt den Befehl weiterlaufen. Wird dagegen alles blockiert, sogar ein einfaches ls, und der Grund lautet „jq wird benötigt“, dann fehlt jq.
5. Das Netz darunter: git
Der Wächter senkt das Risiko, er beseitigt es nicht. Ein Befehl hat viele Varianten, und du siehst nicht alle voraus. Deshalb ist das echte Netz darunter git: Mach einen Commit, bevor du Claude eine lange Aufgabe gibst, und halte eine Kopie des Projekts auch online, zum Beispiel auf GitHub. Wenn etwas schiefgeht, gehst du zum letzten Commit zurück.
Und den Modus bypassPermissions, der die Bestätigungsabfragen überspringt, empfiehlt die Dokumentation von Claude Code nur in isolierten Umgebungen, etwa einem Container oder einer virtuellen Maschine. Nicht auf dem Computer, auf dem du alles hast.
Häufige Fehler
- Die vorhandene settings.json überschreiben: Füge die neuen Teile zum bestehenden Inhalt hinzu und prüf die Kommas, denn ein fehlendes Komma reicht, um die Datei kaputtzumachen.
- Glauben, dass das Deny alle Varianten abdeckt: Es blockiert den Befehl genau so geschrieben, also stell ihm den Wächter zur Seite, der den ganzen Befehlstext liest.
- chmod +x vergessen: Das Skript startet nicht und der Wächter blockiert nichts, ohne es dir zu sagen, also mach immer den Test mit einem leeren Ordner.
- Sich bei gelöschten Dateien auf Rewind verlassen: Rewind macht keine Terminalbefehle rückgängig, also mach vor langen Aufgaben einen Commit.
Checkliste
- Deny-Regeln in .claude/settings.json
- Wächter-Skript angelegt und ausführbar gemacht
- jq installiert
- Hook in /hooks unter PreToolUse sichtbar
- Test mit leerem Ordner: Befehl blockiert
- Commit vor langen Aufgaben gemacht
Häufige Fragen
Fragt Claude Code nicht sowieso um Erlaubnis vor Befehlen?
Im Manual-Modus ja: Er fragt vor jedem Befehl, der nicht nur liest. Aber wenn du „Ja, nicht mehr fragen“ antwortest oder in einem Modus arbeitest, der weniger fragt, fällt diese Bestätigung weg. Das Deny und der Wächter bleiben dagegen auch dort aktiv.
Was ist besser, die Deny-Liste oder der Hook?
Beides. Das Deny sind drei Zeilen und braucht sonst nichts. Der Hook liest den ganzen Befehlstext und erwischt die häufigsten Varianten. Jeder deckt die Lücken des anderen ab.
Kann der Wächter auch harmlose Befehle blockieren?
Ja: Wenn ein Befehl diese Wörter enthält, zum Beispiel eine Textsuche mit „rm -rf“ darin, wird er gestoppt. Das ist in Ordnung: Claude liest den Grund und fragt dich, wie es weitergeht. Wenn das oft passiert, mach die Liste genauer.
Gilt das für alle meine Projekte?
In .claude/settings.json gilt es für dieses Projekt, und wenn die Datei in git liegt, auch für alle, die mit dir daran arbeiten. In ~/.claude/settings.json gilt es für alle deine Projekte: Leg das Skript dann in ~/.claude/hooks und schreib diesen Pfad in den Befehl des Hooks.