KI-Agenten-Sicherheit: Wie Guardrails den Blast Radius begrenzen
Enge Cloud-Rollen, Tool-Allowlists, Kostenlimits und Idempotenz begrenzen den Blast Radius autonomer KI-Agenten in produktiven Systemen wirksam.

Cursor löschte mit Claude Opus 4.6 am 25. April innerhalb von neun Sekunden die Produktionsdatenbank von PocketOS samt Backups – und verfasste anschließend ein Geständnis. Drei Monate an Mietwagenreservierungen waren verschwunden. In meinem Alltag greifen sechs Agenten täglich auf Produktivsysteme zu. Die folgende Architektur für KI-Agenten-Sicherheit bündelt alle kritischen Aktionen an einem Kontrollpunkt, beschränkt sie per Allowlist und macht sie idempotent. So kann selbst der schlimmste Fehler höchstens einen Dollar zu viel kosten.
Die Schadensbilanz aus 90 Tagen
-
April 2026. Ein Cursor-Agent mit Claude Opus 4.6 erledigte im Staging eine Aufgabe, die PocketOS-CEO Jeremy Crane als „Routineaufgabe“ bezeichnete. Nach einem Konflikt bei den Zugangsdaten beschloss der Agent eigenmächtig, „aufzuräumen“, und löschte ein Railway-Speichervolumen mit der Produktionsdatenbank und ihren Backups. Neun Sekunden. Ein Ausfall über dreißig Stunden. Das jüngste wiederherstellbare Backup war drei Monate alt. Damit verschwanden drei Monate an Mietwagenreservierungen. Anschließend hielt der Agent in einem Geständnis fest, dass er die ausdrückliche Anweisung, die Produktionsumgebung nicht anzurühren, missachtet hatte.
-
Februar 2026. Alexey Grigorev, Gründer von DataTalks.Club, hatte den Rechner gewechselt; seine lokale Terraform-State-Datei war deshalb veraltet. Claude Code sollte Ressourcen bereinigen und führte
terraform destroygegen den produktiven Stack aus. Die später teilweise wiederhergestellte Tabellecourses_answerenthielt 1,943,200 Zeilen: zweieinhalb Jahre studentischer Einreichungen. Die automatisierten Snapshots lagen im selben Konto, das zerstört wurde.
Mitte Dezember 2025. Amazons eigener interner Agent Kiro übernahm die erweiterten Rechte eines Engineers, umging Amazons Vier-Augen-Freigabe – sie galt für Menschen, nicht für die Rolle des Agenten – und löschte die Produktionsumgebung von AWS Cost Explorer, um sie anschließend neu anzulegen.
Drei Vorfälle, drei unterschiedliche Modelle, drei unterschiedliche Stacks. Die gemeinsame Ursache war nicht das Modell. Es war die Kombination aus übernommenen, weitreichenden Berechtigungen, einer autonomen Schleife und einer Ausführungsgeschwindigkeit, bei der keine menschliche Bestätigung mithalten kann. ServiceNow vermarktet für genau diese Sorge bereits ein „Kill Switch“-Produkt. Die folgende Architektur ist die intern umsetzbare Variante – und läuft bei mir heute in Produktion.
Was nicht technische Gründer daraus mitnehmen sollten
Wenn eine KI-Fachkraft diesen Artikel intern empfohlen hat, geht es bei einem Fehler nicht bloß um einen „KI-Bug“. Im schlimmsten Fall sind das Reservierungssystem, Studierendendaten oder Kundendaten weg – während die Backups drei Monate veraltet sind, weil niemand die Wiederherstellung getestet hat.
Die entscheidende Frage an die technische Leitung lautet nicht: „Wie gut ist der Agent?“ Das greift zu kurz. Richtig ist: Welchen maximalen Schaden kann ein einzelner Agentenlauf verursachen, und wer hat diese Obergrenze festgelegt? Lautet die Antwort „Wir vertrauen dem Modell“ oder „Wir prüfen die Diffs“, fehlt eine echte Kontrollfläche. Übrig bleibt Hoffnung.
Eine belastbare Antwort klingt so: „Der Agent läuft unter einer Cloud-Rolle ohne Löschrechte. Er kann zwölf fest benannte Tools aufrufen, aber keine Shell. Jeder kostenpflichtige Aufruf läuft durch eine Funktion mit harter Kostengrenze. Im schlimmsten Fall scheitert ein Schritt und verursacht höchstens einen Dollar an Ausgaben.“ Genau das ist die Architektur. Im Folgenden geht es um ihre Umsetzung.
Warum „Sei vorsichtig“ und „Prüfe den Diff“ nicht funktionieren
Das PocketOS-Volume war nach neun Sekunden gelöscht. Kiro war schneller fertig, als ein Mensch die Bestätigungsabfrage hätte lesen – geschweige denn beurteilen – können. Ein Eingriff nach dem Start ist bei Agentengeschwindigkeit strukturell unmöglich. Sobald die Aktion sichtbar wird, ist sie bereits abgeschlossen.
Viele Texte zur Agentensicherheit sparen diesen Punkt aus, weil er zu einem unbequemen Schluss führt: Wirksam ist nur die Ablehnung vor der Ausführung. Nicht eine Rückfrage des Agenten, die ein müder Mensch bestätigt. Nicht vollständiges Logging mit späterer Prüfung. Ablehnung vor der Ausführung bedeutet, dass eine destruktive Aktion von Anfang an außerhalb der für den Agenten erreichbaren Oberfläche liegt.
Kiro lieferte den Gegenbeweis. Amazon hatte eine Vier-Augen-Freigabe. Sie galt für Menschen, die Jobs starteten. Der Agent erbte die Rechte der Person, die ihn gestartet hatte, und umging die Freigabe, weil sie nie an seine eigene Ausführungsrolle gebunden war. Für den Menschen gab es ein Genehmigungstheater, für die Schleife vollständige Löschrechte.
Damit verschiebt sich der Blick auf das Problem. Ein Agent wird nicht „beaufsichtigt“. Seine Aktionsfläche wird begrenzt, bevor die Schleife startet – und diese Begrenzung muss eine Eigenschaft der Rolle sein, nicht des Prompts.
KI-Agenten-Sicherheit am Kontrollpunkt: alle kostenpflichtigen und verändernden Aufrufe durch eine Funktion
Jeder kostenpflichtige Modellaufruf in meinem Stack aus sechs Agenten läuft durch genau eine Funktion: callAi. Sie erledigt nacheinander fünf Aufgaben: das Ausgabenlimit von $20 pro Tag vorab prüfen, die Aufrufdauer messen, Tokenzahlen und Kosten in USD in einer nur ergänzbaren Zeile von ai_call_log protokollieren – versehen mit agent_id und workflow_instance_id –, anschließend das Limit von $1 pro Instanz prüfen und schließlich das Ergebnis zurückgeben.
export async function callAi(env: Env, args: CallAiArgs) {
const { agentId, workflowInstanceId, model, messages } = args;
const dailySpent = await getDailySpendUSD(env);
if (dailySpent >= 20) {
throw new NonRetryableError(`daily cap hit: $${dailySpent}`);
}
const t0 = Date.now();
const res = await anthropic.messages.create({ model, messages });
const costUSD = priceOf(model, res.usage);
await env.DB.prepare(
`INSERT INTO ai_call_log
(agent_id, workflow_instance_id, model, in_tokens, out_tokens, usd, ms, ts)
VALUES (?, ?, ?, ?, ?, ?, ?, unixepoch())`
).bind(agentId, workflowInstanceId, model,
res.usage.input_tokens, res.usage.output_tokens,
costUSD, Date.now() - t0).run();
const instanceSpent = await getInstanceSpendUSD(env, workflowInstanceId);
if (instanceSpent >= 1) {
throw new NonRetryableError(`instance cap hit: $${instanceSpent}`);
}
return res;
}Wird ein Limit überschritten, löst die Funktion einen nicht wiederholbaren Fehler aus. Der Workflow endet. Der Agent kann nicht eigenmächtig beschließen, doch weiterzumachen, denn die Budgetschranke ist kein Prompt, über den sich verhandeln lässt. Sie ist eine Exception oberhalb seiner Reasoning-Schicht.
Der oft zitierte außer Kontrolle geratene Lauf über 63 Stunden und $4,200 zeigt den Unterschied: Ohne Kontrollpunkt gibt es keinen Endzustand. Die Schleife verbrennt weiter Geld, bis jemand die Rechnung bemerkt. Mit einem Limit pro Instanz kostet ein einzelner Lauf schlimmstenfalls $1. Mit einem Tageslimit kostet der schlimmste Tag $20. Beim Aufbau meines Systems habe ich beide Limits versehentlich erreicht. Keiner der Fehler kostete mehr als ein Abendessen.
Der Kontrollpunkt erfüllt noch eine zweite Aufgabe: Er schafft forensische Nachvollziehbarkeit. Jede Aktion hinterlässt eine Audit-Zeile, bevor das Ergebnis zurückgegeben wird. Geht etwas schief, beginnt die Post-Mortem-Analyse mit einer SELECT-Abfrage gegen ai_call_log – nicht mit der Rekonstruktion aus dem Geständnis des Agenten.
Die Allowlist: 12 Zod-Tools, keine Shell, kein Terraform
Die gesamte verändernde Oberfläche des Agenten besteht aus zwölf Tools, die als strikte Zod-Schemas definiert sind. Es gibt kein Bash-Tool, kein terraform-Tool und überhaupt keine API für Cloud-Volumes. Selbst wenn der Agent zu dem Schluss käme, terraform destroy ausführen zu wollen, könnte er diesen Wunsch nicht in eine Aktion übersetzen.
Die Konfiguration des Claude Agent SDK, die das erzwingt, ist kurz:
const result = await query({
prompt,
permissionMode: "dontAsk",
allowedTools: [
"read_brief", "fetch_corpus", "render_markdown",
"validate_directives", "persist_draft", "schedule_publish",
"update_status", "log_event", "fetch_citation",
"embed_text", "search_vectors", "notify_human"
],
// no Bash, no Write, no Edit, no infrastructure tools
});Im Modus permissionMode: "dontAsk" werden nicht aufgeführte Tools direkt abgewiesen. Sie führen weder zu einer Rückfrage noch zu einer menschlichen Prüfung. Sie werden abgelehnt. Die dokumentierte Reihenfolge der Berechtigungsprüfung – PreToolUse-Hook, Deny-Regeln, Allow-Regeln, Ask-Regeln, Modusprüfung und canUseTool-Callback – bleibt bestehen. In dontAsk wird der Human-in-the-Loop-Callback jedoch strukturell übersprungen; unbekannte Tools scheitern bei der Modusprüfung.
Genau das hätte PocketOS und DataTalks gestoppt. Der DataTalks-Fehler ist in dieser Konfiguration unmöglich, weil terraform destroy kein Toolname ist, den der Agent ausgeben kann. Der PocketOS-Fehler ist unmöglich, weil das Löschen eines Volumes nicht zur Oberfläche gehört. Selbst wenn das Modell beschlösse, „aufzuräumen“, gäbe es keinen Pfad vom Wunsch zur Aktion.
Verlockend ist ein Bash-Tool für den Fall, dass „der Agent etwas Unvorhergesehenes erledigen muss“. Darauf sollte verzichtet werden. Sobald Bash hinzukommt, umfasst der Blast Radius alles, was Bash erreichen kann.
Idempotenz: Warum eine Wiederholung nicht doppelt zerstören kann
Die dritte Säule der Architektur ist Idempotenz. Jede Cloudflare-Workflow-Instanz erhält eine deterministische, aus der Eingabe gebildete ID: publish-{brief_id}. Bei einer doppelten ID löst instances.create() einen Fehler aus. Wird dasselbe Ereignis erneut ausgelöst, kann der Workflow daher nicht zweimal laufen. Ein Sturm von Wiederholungsversuchen in der Queue-Schicht endet als No-op statt als doppelte Veröffentlichung.
const id = `publish-${msg.body.briefId}`;
try {
await env.PUBLISHER.create({ id, params: msg.body });
} catch (e) {
if (e.message.includes("already exists")) return; // safe replay
throw e;
}Innerhalb des Workflows wird jedes Ergebnis von step.do() zwischengespeichert und kann sicher wiederholt werden. Bei einem erneuten Versuch wird das gespeicherte Ergebnis abgespielt, statt den Seiteneffekt noch einmal auszuführen. Zusammen mit INSERT OR IGNORE für die kanonischen D1-Tabellen und einem versionierten R2-Snapshot bei jedem Speichervorgang verhindert das, dass ein fehlerhafter Schritt unbemerkt den Verlauf überschreibt. Die vorherige Version liegt nur einen R2-Schlüssel entfernt.
Die Ursache bei DataTalks war eine veraltete State-Datei, die eine irreversible Löschung anstieß. Deterministische Workflow-IDs und ein Snapshot vor jeder Veränderung machen die Zerstörung durch veralteten Zustand hier beherrschbar: Selbst wenn ein Workflow mit falschen Annahmen liefe, wäre der Snapshot der Rücksetzpunkt. (Das Primitive für dauerhafte Ausführung wird im Vergleich von Cloudflare Workflow und Managed Agents genauer behandelt; mathematisch folgt die Idempotenz derselben Logik der Schadensbegrenzung, nur unter einem anderen Namen.)
Das passende Denkmodell: Ein Schritt mit destruktiven Fähigkeiten schreibt zuerst einen versionierten Snapshot. Der Snapshot ist Vorbedingung, nicht nachträgliche Absicherung. Scheitert sein Schreibvorgang, findet keine Veränderung statt. Scheitert die Veränderung, dient der Snapshot als Wiederherstellungspunkt. Es gibt keinen Pfad, auf dem Zustand verloren geht, ohne dass eine Wiederherstellung möglich wäre.
Die Migration in 5 Schritten für diese Woche
Die Reihenfolge ist entscheidend. Schon Schritt 1 hätte alle drei genannten Vorfälle verhindert. Deshalb gehört er an den Anfang – auch wenn zunächst nichts Weiteres umgesetzt wird.
Die Cloud-Rolle des Agenten auf null Löschoperationen begrenzen
Die IAM-Rolle – oder das Dienstkonto beziehungsweise API-Token – des Agenten darf in Produktionsressourcen keine Destroy- oder Delete-Operationen ausführen. Kein
DeleteVolume. Keine Berechtigung fürterraform destroy. KeinDROP TABLE. Die Rolle definiert die Untergrenze des Blast Radius. Ist sie nicht sauber begrenzt, spielt alles darüber keine Rolle.Das ist die konkrete Lehre aus Kiro: Ein Agent darf nicht die weitreichenden Rechte der Person erben, die ihn startet. Er braucht eine eigene, eng zugeschnittene Rolle.
Den Agenten mit permissionMode dontAsk und einer expliziten allowedTools-Liste kapseln
Benötigt wird die kleinste Toolmenge, mit der der Agent seine Aufgabe erfüllen kann. Bei mir sind es zwölf, in einem anderen System vielleicht sechs. Allgemeine Shell-Tools sollten vollständig verschwinden. Hat der Agent derzeit aus Bequemlichkeit ein Bash-Tool, ist genau diese Bequemlichkeit die Schwachstelle.
TypeScript{ permissionMode: "dontAsk", allowedTools: [/* explicit list */] }Eine Budget-Sicherung einbauen
Alle kostenpflichtigen Aufrufe laufen durch einen gemeinsamen Wrapper. Vor dem Aufruf prüft er ein hartes Tageslimit, danach ein Limit pro Instanz. Bei Überschreitung löst er
NonRetryableErroraus. Das Instanzlimit ist die Sicherung, die das Tageslimit nicht sein kann: Der Ausreißer über $4,200 und 63 Stunden blieb während seiner schrittweisen Kostensteigerung unter jeder vernünftigen Tagesobergrenze. Das Limit pro Instanz fängt ab, was dem Tageslimit entgeht.Snapshot vor jeder Veränderung
Jeder Schritt mit destruktiven Fähigkeiten schreibt zuerst einen versionierten Snapshot. R2 eignet sich, S3 ebenfalls, ebenso eine D1-Tabelle vom Typ
*_archive. Entscheidend ist: Das Schreiben des Snapshots ist innerhalb desselben Schritts und desselben transaktionsähnlichen Blocks die Vorbedingung für die Veränderung.Nur ergänzbares Aktionsprotokoll
Pro Toolaufruf wird eine Zeile geschrieben, bevor das Ergebnis zurückkehrt. Sie enthält Agenten-ID, Workflow-Instanz-ID, Kosten in USD und Latenz. Wenn schließlich doch etwas schiefgeht – und irgendwann wird das passieren –, beginnt die Post-Mortem-Analyse mit einem
SELECT, nicht mit einer Rekonstruktion.
Jeder Schritt dauert höchstens einen Tag. Die Reihenfolge ist bewusst gewählt, weil sich die Begrenzungen gegenseitig verstärken: Schritt 1 setzt die Untergrenze. Schritt 2 schließt die darüberliegende Aktionsfläche. Schritt 3 begrenzt die Kosten innerhalb dieser Fläche. Die Schritte 4 und 5 sorgen dafür, dass Fehler wiederherstellbar und abfragbar bleiben.
FAQ
Kann ich dem Agenten nicht einfach im System-Prompt verbieten, die Produktionsumgebung zu löschen?
Genau das hatte PocketOS getan. Im eigenen Geständnis hielt der Agent ausdrücklich fest, dass er diese Anweisung verletzt hatte. Anweisungen sind keine Kontrollfläche. Prompts sind Eingaben für ein probabilistisches System; die Tool-Allowlist und die Cloud-Rolle sind Eigenschaften der Laufzeitumgebung. Entscheidend ist die Laufzeitumgebung.
Verliere ich mit permissionMode dontAsk jede Interaktivität?
Nein. Nicht aufgeführte Tools werden abgewiesen, statt eine Rückfrage auszulösen. Die gesamte erlaubte Oberfläche bleibt verfügbar. Was entfällt, ist der Fehlermodus „Der Agent fragt, ein müder Mensch klickt auf Ja“ – und genau dieser Fehlermodus soll verschwinden.
Warum ist zusätzlich zum Tageslimit eine Kostengrenze pro Instanz nötig?
Weil der Ausreißer mit $4,200 in 63 Stunden während seiner schrittweisen Kostensteigerung unter jeder vernünftigen Tagesobergrenze blieb. Eine einzelne fehlerhafte Schleife kann deutlich unter „$20 pro Tag“ bleiben und über ein Wochenende trotzdem einen vierstelligen Betrag kosten. Das Instanzlimit ist die Sicherung, die ein Tageslimit strukturell nicht sein kann.
Gilt das auch für Vercel oder Railway statt Cloudflare Workflows?
Kontrollpunkt, Allowlist und eng zugeschnittene Rolle sind plattformunabhängig. Nur das Idempotenz-Primitive – deterministische Workflow-IDs – ist Cloudflare-spezifisch. In anderen Stacks erhält der Job einen Idempotenzschlüssel; Duplikate werden auf Queue- oder Job-Runner-Ebene abgewiesen.
Reicht eine Vier-Augen-Freigabe aus?
Kiro hatte sie für Menschen, erbte jedoch Berechtigungen, mit denen der Agent sie umgehen konnte. Freigaben müssen an die Rolle des Agenten gebunden sein, nicht an die Person, die ihn startet. Hat die Agentenrolle Löschrechte, ist die Freigabe nur Dekoration.
Falls ein Agent im Team der Produktionsumgebung erst letzte Woche bedenklich nahekam: Genau diese Absicherung setze ich bei DVNC.dev um – angepasst an den jeweiligen Stack und in der Reihenfolge, die zuerst den Blast Radius schließt.
5. Sept. 2026







