Wer nach „Claude Code permissions“ sucht, findet zur Hälfte Anleitungen zum Deaktivieren. --dangerously-skip-permissions, das YOLO-Flag, eine kilometerlange Allow-List. Das fühlt sich produktiv an. Es ist aber der falsche Instinkt, und in diesem Beitrag geht es um den richtigen.
Warum das Überspringen von Claude Code-Berechtigungen der falsche Ansatz ist
Das Überspringen von Berechtigungen entfernt die Abfrage, ohne eine echte Entscheidungsgrundlage zu schaffen. Das ist das ganze Problem in einem Satz. Die Abfrage war nie der eigentliche Punkt. Es ging um die Entscheidung dahinter: Ist diese Aktion gerade sicher? Schaltet man die Abfrage stumm, wird die Entscheidung nicht besser gefällt. Sie wird gar nicht mehr gefällt. Ein fehlerhaftes rm -rf oder ein Force-Push in den gemeinsamen Git-Verlauf läuft dann ab, ohne dass noch etwas zwischen dem Agenten und deinem Repo steht.
Die Reibung ist real, die Leute hassen sie völlig zurecht. Wenn man zum fünfzigsten Mal dasselbe harmlose ls absegnet, klickt man irgendwann bei allem blind auf Ja. Genau so rutscht der eine gefährliche Aufruf durch. Die Lösung ist aber nicht weniger Kontrolle. Die Lösung ist Kontrolle, die im Code lebt. So bist du nicht mehr das Nadelöhr, ohne dich wehrlos zu machen.

Das echte Berechtigungsmodell: erlauben, ablehnen oder nachfragen
Jeder Tool-Aufruf in Claude Code durchläuft vor der Ausführung einen PreToolUse-Schritt. Ein auf dieses Tool abgestimmter Hook kann eines von drei Ergebnissen zurückgeben: erlauben, ablehnen oder nachfragen. Das ist das Modell. Berechtigungen sind keine statische Allow-List, die man von Hand pflegt. Es ist eine Richtlinienfrage, die dein Code für jeden Aufruf individuell beantwortet, direkt anhand des konkreten Befehls.
Du verknüpfst einen Hook über einen Matcher mit einem Tool. Matchst du auf Bash, sieht dein Skript jeden Shell-Befehl vor der Ausführung. Matchst du auf Edit|Write|MultiEdit|NotebookEdit, sieht es jede Datei, die der Agent gleich ändern will. Der Hook liest den Tool-Input aus stdin, entscheidet und gibt sein Ergebnis aus. Um abzulehnen, gibt er JSON aus, bei dem hookSpecificOutput.permissionDecision auf "deny" gesetzt ist, und Claude Code verweigert den Aufruf. Das ist die Funktionsweise. Die vollständigen Details haben wir unter Claude Code-Hooks aufgeschrieben.
| Matcher | Was der Hook tut | Entscheidung |
|---|---|---|
| Bash | safety-guard.mjs matcht auf einen destruktiven Befehl: ein rekursives Löschen des Root- oder Home-Pfads, ein Force-Push, ein Hard-Reset oder eine gelöschte Tabelle. Es gibt eine Warnung auf stderr aus und beendet sich mit Code 0. | keine Entscheidung |
| Bash | safety-guard.mjs matcht auf nichts und verhält sich ruhig. Ein Kit, das deine Shell komplett blockiert, wird deinstalliert. | keine Entscheidung |
| Edit|Write|MultiEdit|NotebookEdit | clarity.mjs befindet sich im Strict-Mode, das Ziel ist noch nicht bestätigt und die Datei ist keine Planungsdatei. | ablehnen |
| Edit|Write|MultiEdit|NotebookEdit | clarity.mjs sieht CLAUDE.md, AGENTS.md, DESIGN.md oder einen Pfad unter .kitstarter/. Das Nachdenken auf dem Papier wird nie blockiert. | keine Entscheidung |
| beide Matcher | Der Hook wirft einen Fehler. Beide fangen den Fehler ab und schweigen bewusst. | keine Entscheidung |
Zwei gegensätzliche Entscheidungen, die wir ausgeliefert haben, und warum
Im kitstarter-Kit führen wir zwei PreToolUse-Hooks aus, die bewusst gegensätzliche Entscheidungen treffen. Einer blockiert rigoros. Der andere warnt nur. Dieser Unterschied ist der Kern der Sache. Hier ist die Erklärung für beide Ansätze.
Die Bausperre: clarity.mjs lehnt Änderungen ab, bis das Ziel bestätigt ist
Unser Clarity-Hook matcht auf Edit|Write|MultiEdit|NotebookEdit und gibt für jede Änderung permissionDecision: "deny" zurück, solange eine vage Bauanfrage noch nicht bestätigt ist. Der Agent kann physisch keinen Code schreiben, bevor das Ziel vereinbart wurde. Das ist eine echte Sperre, die vom Tool erzwungen wird, und keine höfliche Zeile in einer Markdown-Datei, die das Modell einfach überfliegen und ignorieren kann.
Der ausgegebene Ablehnungsgrund ist das Coaching im Wortlaut: „Das Ziel ist noch nicht bestätigt, daher ist das Bauen gesperrt. Schließe die Clarity-Runde ab: Stelle Multiple-Choice-Fragen, eine nach der anderen, spiegele das Ziel zurück und hole ein ausdrückliches Ja vom Benutzer ein. Die Sperre wird nach der Freigabe aufgehoben.“ Planungsdateien bleiben während der Runde beschreibbar, denn das Schreiben von CLAUDE.md oder einer Design-Notiz ist der Weg, wie sich der Agent aus der Sperre befreit. Blockiert wird das Schreiben von Code, nicht das Nachdenken auf dem Papier. Dies greift Hand in Hand mit den Befehle, die die Clarity-Runde selbst ausführen.
Warum hier blockieren? Weil die Kosten für Fehler hoch sind und die Reibung gering ist. Einen Agenten zurückzuholen, der zwanzig Minuten lang das falsche Feature gebaut hat, ist mühsam und teuer. Vorab eine klärende Frage zu stellen, kostet Sekunden. Wenn das Verhältnis so extrem unausgewogen ist, erzwingt man es im Code und muss nie wieder darüber nachdenken.
Die Warnung: safety-guard.mjs markiert Gefahren, blockiert aber nie
Unser Safety-Hook matcht auf Bash und achtet auf wirklich destruktive Shell-Befehle: rekursives Löschen des Root- oder Home-Pfads, Force-Pushes, Hard-Resets oder das Löschen einer Datenbank. Wenn er einen solchen Befehl erkennt, gibt er eine Warnung aus und macht dann ganz bewusst den Weg frei. Er ruft process.exit(0) mit dem Kommentar „warn only, never block“ auf.
Die Begründung steht direkt im Header der Datei: Sie warnt und blockiert nicht, weil „ein Kit, das deine Befehle komplett blockiert, deinstalliert wird.“ Das ist kein Kompromiss, sondern die richtige Entscheidung. Über Shell-Befehle erledigt ein Agent echte, vielfältige und legitime Arbeit. Blockiert man sie rigoros, wird jedes False Positive zu einer Barriere zwischen dem Entwickler und seiner eigenen Maschine. Die Warnung übernimmt den nützlichen Teil („Meintest du das und hast du vorher einen Checkpoint erstellt?“), ohne dir jemals die Schlüssel wegzunehmen.
Die Regel: Blockieren, wenn Fehler teuer sind und die Reibung gering ist
Das ist das gesamte Konzept, und genau deshalb zielen die beiden Hooks in entgegengesetzte Richtungen. Das Blockieren von Dateiänderungen vor der Bestätigung eines Ziels ist leicht zu akzeptieren und erspart dir teure Nacharbeit, daher ist es ein striktes „Ablehnen“. Das Blockieren von Shell-Befehlen wäre im Alltag extrem störend und würde ständig bei legitimer Arbeit anschlagen, daher ist es eine Warnung. Derselbe Event, gegensätzliche Entscheidungen, abgewogen nach den Kosten eines Fehlers im Vergleich zum Aufwand für den korrekten Weg.
Beide Hooks nutzen zudem das Prinzip „Fail Open“. Bei jedem Fehler schweigen sie und lassen den Aufruf durchgehen. Ein Coaching-Feature, das deine Session abstürzen lässt, ist schlimmer als gar kein Feature. Wenn der Hook also einen Fehler wirft, erlaubt er die Aktion. Das ist ein echtes Designprinzip und kein nachträglicher Gedanke: Das Sicherheitsnetz darf niemals das sein, was dich lahmlegt.
Zahlt sich diese Art der Berechtigungssteuerung überhaupt aus?
In unserem Clean-Room-Benchmark lautet die Antwort: Ja, wenn auch mit ehrlichen Verlusten. Die Clarity-Sperre sorgte bei 5 von 5 Aufgaben dafür, dass das Kit vor dem Bauen nachfragte, und zwar bei jedem Durchlauf. Beim Standard-Claude Code war das nur bei 2 von 5 Aufgaben der Fall, da das Nachfragen dort stimmungsabhängig war. Der Output war bei gleichem Ergebnis um etwa 40 Prozent schlanker. Hier zeigt sich der Wert des deterministischen Ablehnens.
Die Verluste sind real und wir verheimlichen sie nicht, das ist bei uns Ehrensache. Bei einer ohnehin klaren To-do-App-Aufgabe war das Kit etwa doppelt so langsam und rund 75 Prozent teurer bei fast identischem Ergebnis. Die Clarity-Runde ist reiner Overhead, wenn der Prompt von Anfang an eindeutig war. Über die gesamte Suite hinweg sorgten die Kontext-Token der Hooks für durchschnittlich 25 Prozent höhere Kosten. Eine Berechtigungsrichtlinie gibt es nicht umsonst. Es ist ein Abwägen, und dieses Abwägen lohnt sich nur, wenn das, was du schützt, am Ende teurer ist als der Schutz selbst.
Häufige Fragen
Sollte ich --dangerously-skip-permissions in Claude Code verwenden? Nur in einer Wegwerf-Sandbox, die du zerstören kannst. Das Flag entfernt jede Abfrage, ohne eine Entscheidungsgrundlage zu schaffen. Ein fehlerhaftes rm oder ein Force-Push läuft also völlig ungebremst ab. Entscheide Berechtigungen in einem echten Repo stattdessen lieber mit einem PreToolUse-Hook: Blockiere die wenigen extrem riskanten Aktionen, warne bei den übrigen und erlaube alles andere.
Kann ein Claude Code-Hook einen Tool-Aufruf ablehnen? Ja. Ein PreToolUse-Hook kann JSON ausgeben, bei dem hookSpecificOutput.permissionDecision auf deny gesetzt ist. Claude Code verweigert dann den Tool-Aufruf, noch bevor er ausgeführt wird. Das verwandelt eine Berechtigungsregel in echten Code, der deterministisch bei jedem passenden Aufruf erzwungen wird, statt nur eine Zeile in einer Markdown-Datei zu sein, die der Agent einfach überfliegt.
Wie funktionieren die Berechtigungen in Claude Code eigentlich? Jeder Tool-Aufruf durchläuft vor der Ausführung PreToolUse. Ein auf ein Tool abgestimmter Hook kann allow, deny oder ask zurückgeben. Berechtigungen sind also eine Richtlinie, die dein Code pro Aufruf beantwortet, und keine statische Allow-List. Du verknüpfst einen Hook über den Namen mit einem Tool, liest den Tool-Input aus stdin und entscheidest.
Berechtigungen im Code entscheiden, nicht überspringen
kitstarter liefert die PreToolUse-Hooks, die Clarity-Sperre und die Sicherheitswarnungen direkt mit. Alles ist so abgestimmt, dass dein Agent nachfragt, bevor er baut, und dir ansonsten nicht im Weg steht. Für Claude Code, Codex und Antigravity.
