# Discovery-Aufrufe vs. Mutation-Aufrufe für sicherere AI-Agents

Ein Agent, der ein System umfassend untersuchen und beiläufig verändern kann, hat die falsche Autoritätsstruktur. Die sinnvolle Trennung ist einfach: Gib dem Agent genug Möglichkeiten zur Discovery, damit er einen fundierten Plan erstellen kann. Setze dann eine klare Grenze um Vorgänge, die Zustände anlegen, ändern, auslösen oder löschen.

Diese Trennung klingt offensichtlich, bis man auf eine echte API trifft. Ein angeblich schreibgeschützter Endpunkt aktualisiert einen Cache. Eine Vorschau reserviert einen entfernten Job. Ein Update-Endpunkt akzeptiert einen leeren Filter und bearbeitet dadurch jeden Datensatz. Ein SSH-Befehl wirkt harmlos, bis eine Shell-Erweiterung aus einem engen Pfad einen viel größeren macht. Methodennamen und gute Absichten schützen kein Produktionskonto.

Ich habe Teams gesehen, die dieses Problem lösten, indem sie jeden Aufruf von einem Menschen freigeben ließen. Das schützt das Konto einen Nachmittag lang und bringt alle dazu, bis Freitag Freigaben zu erteilen, ohne sie zu lesen. Das bessere Design lässt Agents untersuchen, macht Zustandsänderungen sichtbar und setzt die stärkste Hürde dort, wo eine falsche Aktion irreversible oder teure Folgen hätte.

## Discovery braucht eine andere Berechtigungsstruktur

Discovery-Aufrufe sollten Fragen zum aktuellen Zustand beantworten, ohne diesen Zustand zu verändern. Mutation-Aufrufe versuchen dagegen, etwas anzulegen, zu bearbeiten, auszuführen oder zu entfernen. Diese Unterscheidung ist wichtig: Ein Agent kann ohne aktuelle Informationen nicht sicher planen, sollte aber auch kein dauerhaftes Recht zum Handeln erhalten, nur weil er Kontext braucht.

Ein Coding-Agent, der einen fehlgeschlagenen Deployment untersucht, muss möglicherweise Services auflisten, aktuelle Ereignisse abrufen, eine Konfigurationsrevision vergleichen, den Repository-Status prüfen und ein entferntes Issue lesen. Diese Anfragen verringern die Unsicherheit. Wenn du jede einzelne freigeben lässt, sieht der Bediener eine Reihe kleiner Aufforderungen mit zu wenig Kontext für eine sinnvolle Entscheidung. Außerdem verliert der Agent während des Wartens den roten Faden seiner Untersuchung.

Derselbe Agent könnte später einen Workload neu starten, einen Pull Request zusammenführen, ein Zugangstoken erneuern, ein Issue schließen oder ein Objekt löschen. Jede dieser Aktionen verändert die Welt außerhalb des Kontextfensters des Agents. Der Bediener sollte das geplante Ziel und die Auswirkung sehen, bevor er sie autorisiert.

Das ist nicht dasselbe, wie eine weitreichende Rolle «schreibgeschützt» zu vergeben und die Sache damit abzuschließen. Discovery kann sensible Informationen offenlegen. Sie kann Kosten verursachen, Rate Limits verbrauchen oder in einem schlecht entworfenen Dienst Verhalten auslösen. Die Trennung kontrolliert Aktionen. Sie erklärt Inspektion nicht pauschal für harmlos.

Eine nützliche Klassifizierung fragt, was das entfernte System nach Abschluss der Anfrage beobachten kann:

1. Ein Discovery-Aufruf gibt Informationen zurück und verändert keinen relevanten geschäftlichen, operativen oder abrechnungsbezogenen Zustand.
2. Ein Mutation-Aufruf legt etwas an, aktualisiert, löscht, führt aus, veröffentlicht, versendet oder verändert auf andere Weise einen extern sichtbaren Zustand.
3. Ein mehrdeutiger Aufruf wird wie eine Mutation behandelt, bis jemand das Gegenteil nachweist.

Die dritte Kategorie ist wichtiger, als viele Teams annehmen. Wenn niemand die Seiteneffekte eines Endpunkts anhand seines Vertrags und eines kontrollierten Tests erklären kann, nimm ihn nicht in die unbeaufsichtigte Discovery-Menge auf, nur weil sein Name harmlos klingt.

## HTTP-Verben sind ein Hinweis, keine Berechtigungsentscheidung

HTTP-Methodennamen helfen bei der Einordnung, ersetzen aber keine Prüfung des Endpunkts. RFC 9110 bezeichnet GET, HEAD, OPTIONS und TRACE als «sichere» Methoden. Damit ist gemeint, dass der Client keine Zustandsänderung anfordert. Die RFC warnt zugleich, dass ein Server Anfragen trotzdem protokollieren, ein Konto belasten oder andere unbeabsichtigte Effekte auslösen kann.

Diese Unterscheidung wird leicht übersehen. HTTP-Sicherheit beschreibt die beabsichtigte Semantik einer Anfrage, nicht die kryptografische Zusicherung, dass die Implementierung nichts getan hat. RFC 9110 legt dem Eigentümer der Ressource die Verantwortung auf, unsichere Aktionen zu vermeiden, wenn Nutzer den Konventionen sicherer Methoden folgen. Dein Agent kann dieses Versprechen nicht erzwingen, wenn der Dienst es verletzt.

Behandle diese Regeln als Ausgangspunkt, nicht als endgültige Entscheidung:

1. GET und HEAD gehören normalerweise zur Discovery-Kandidatenmenge. Prüfe zuerst Query-Parameter und Dokumentation des Endpunkts.
2. POST, PUT, PATCH und DELETE gehören zur Mutation-Menge, sofern ein bestimmter Endpunkt nicht ausdrücklich dokumentiertes und getestetes Leseverhalten hat.
3. OPTIONS kann Server-Fähigkeiten untersuchen, doch manche Plattformen liefern kontospezifische Details, die ebenfalls eine Begrenzung des Umfangs brauchen.
4. Ein Webhook-Test, eine Job-Vorschau, ein Berichtsexport oder ein Suchendpunkt kann POST verwenden und trotzdem nur beobachten. Überprüfe das, statt pauschal alle POST-Aufrufe freizugeben.

Auch der umgekehrte Fehler kommt häufig vor. Entwickler verbinden aus Bequemlichkeit einen Link oder eine GET-Route mit einer Aktion. Eine URL wie `/reports/monthly?refresh=true` kann einen teuren Berichtscache neu aufbauen. Ein GET-Endpunkt mit `?send=true` kann eine Benachrichtigung versenden. Ein Agent verwendet, was er in der API-Beschreibung vorfindet. Erwarte nicht, dass das Modell bemerkt, dass der Serverentwickler die HTTP-Semantik ignoriert hat.

Achte in der Endpunktdokumentation auf Wörter wie «erstellt», «startet», «aktualisiert», «generiert», «versendet», «speichert», «synchronisiert» und «berechnet». Diese Verben sollten den Aufruf aus Discovery herausnehmen, selbst wenn die Route GET verwendet. Teste den Endpunkt anschließend mit einem Wegwerfkonto und vergleiche den Zustand davor und danach, einschließlich Jobwarteschlangen, Benachrichtigungen, Nutzungszählern und Audit-Einträgen.

Auch die HTTP-Antwort hilft bei der Einordnung. Eine Antwort mit einer Job-ID, einer Operations-ID oder der URL einer neuen Ressource zeigt oft, dass der entfernte Dienst Arbeit gestartet hat. Ein Statuscode 200 beweist nur, dass der Server die Anfrage verarbeitet hat. Er beweist nicht, dass sie lediglich beobachtend war.

## Ressourcen und Auswirkungen definieren, bevor Allowlists entstehen

Eine Allowlist von Pfaden ist zu grob, wenn sie die dahinterliegende Ressource und Wirkung ignoriert. Erstelle ein kleines Aktionsinventar, das festhält, was ein Agent untersuchen darf, was er vorschlagen darf und was er niemals ohne direkte menschliche Entscheidung tun darf.

Verwende für jede externe Aktion einen Eintrag wie diesen. Die Namen sind nicht entscheidend. Die Belege sind es.

```text
Action: repository pull request list
Channel: HTTP
Target pattern: GET /repos/{owner}/{repo}/pulls
Class: discovery
Data returned: title, status, branch names, review metadata
Side-effect evidence: API reference defines this endpoint as a list operation
Scope limit: named repositories only
Review date: 2025-02-14

Action: repository merge pull request
Channel: HTTP
Target pattern: PUT /repos/{owner}/{repo}/pulls/{number}/merge
Class: mutation
Effect: changes merge state and source history
Required control: explicit approval for each call
```

Das Inventar erzwingt eine Entscheidung, die Teams oft vage lassen: Darf der Agent von dieser Ressource wissen oder darf er sie verändern? Das sind getrennte Berechtigungen. Ein Ticketsystem kann die Discovery von Titel und Status eines Issues erlauben, während Kommentartexte mit Kundendaten verborgen bleiben. Ein Cloud-Konto kann das Auflisten eines eng begrenzten Workloads erlauben, aber den Zugriff auf kontoweite Identitäten und Abrechnungsdaten verweigern.

Halte den Umfang im Aktionsdatensatz fest. `GET /projects` ist keine brauchbare Berechtigungsbeschreibung, wenn das Zugangstoken jedes Projekt auflisten kann, das ein Unternehmen je angelegt hat. Eine bessere Beschreibung nennt die Organisation, das Repository, den Namespace, das Konto oder den Pfad, den der Agent benötigt. Kann der vorgelagerte Dienst das Token nicht entsprechend begrenzen, erzwinge eine Ziel-Allowlist im Action-Gateway oder mache die Discovery nicht automatisch verfügbar.

Fülle diese Liste nicht allein aus Swagger-Dateien. API-Beschreibungen nennen oft Methode und Parameter, verschweigen aber betriebliche Folgen. Kombiniere die Dokumentation mit einem Testkonto, dem Audit-Trail des Dienstes und einem Maintainer, der für das entfernte System verantwortlich ist. So entsteht eine ausdrückliche Aussage, die bei Änderungen an der API erneut geprüft werden kann.

## Eine Leseanfrage kann dem System trotzdem schaden

Lesezugriff hat eine eigene Reichweite und braucht eigene Grenzen. Ein Agent, der jedes Repository, jeden Geheimnisnamen, jeden Incident-Vermerk, jeden Kundendatensatz und jedes Deployment-Ereignis untersuchen darf, verfügt über genug Kontext, um Schaden anzurichten, wenn ein Angreifer den Agent-Prozess oder seine Anweisungen kontrolliert.

Die verbreitete Empfehlung lautet: «Zuerst schreibgeschützten Zugriff gewähren.» Sie ist beliebt, weil sie vorsichtig klingt und zu bekannten IAM-Rollennamen passt. Sie ist falsch, wenn eine weitreichende Leseberechtigung die Auseinandersetzung mit der Datenklassifizierung ersetzt. Eine umfassende Discovery verursacht im Design oft die größte Offenlegung von Informationen.

Trenne zwei Fragen:

- Kann die Anfrage den entfernten Zustand verändern?
- Kann die Antwort Informationen offenlegen, die der Agent nicht erhalten sollte?

Eine Anfrage erhält erst dann Discovery-Behandlung, wenn sie die erste Frage besteht. Überhaupt eine Berechtigung erhält sie erst, wenn sie auch die zweite besteht. Fasse diese Prüfungen nicht zu einem einzigen Label zusammen.

Gib bei sensiblen Ressourcen nur die benötigten Felder zurück. Für die Diagnose eines Deployments können Pod-Phase, Image-Digest und aktuelle Ereignismeldungen genügen. Umgebungswerte oder ein vollständiges Konfigurationsobjekt braucht der Agent nicht. Ein Agent für Issue-Triage benötigt vielleicht Labels und Zeitstempel, aber nicht jeden privaten Kommentar. Fehlt der API eine Feldauswahl, schalte eine enge Vermittleraktion davor oder halte den Vorgang hinter einer Freigabe.

Auch die Pagination muss berücksichtigt werden. Ein Listenendpunkt kann in einem erfolgreichen Test begrenzt wirken und zu einem unbegrenzten Datenabfluss werden, sobald der Agent Cursor verfolgt. Begrenze Seitengröße und Gesamtzahl der Seiten, sofern der Kanal das erlaubt, und trage diese Grenze in das Aktionsinventar ein. Rate Limits schützen den Anbieter, bilden aber keine angemessene Informationsgrenze für deinen Agent.

Suchendpunkte brauchen dieselbe Behandlung. Eine Volltextsuche über Quellcode oder Supportdaten kann mehr offenlegen als der direkte Abruf eines Objekts, und der Prompt kann die Suchanfrage beeinflussen. Begrenze durchsuchbare Sammlungen und die Abfragesyntax. Übergib vom Agent erstellte Suchausdrücke nicht direkt an ein mächtiges Backend, nur weil die Anfrage GET verwendet.

## Zugangsdaten müssen die Trennung möglichst erzwingen

Am sichersten wird die Unterscheidung zwischen Inspektion und Aktion im Autorisierungsmodell des entfernten Dienstes umgesetzt. Verwende für Discovery ein Zugangstoken, das die freigegebenen Ressourcen lesen kann, und ein separates Token für die begrenzten Mutation-Aktionen des Workflows.

Diese Anordnung begrenzt einen einfachen, aber unschönen Fehler: Ein bösartiger oder verwirrter Agent findet einen Mutation-Endpunkt, den du vergessen hast zu sperren. Kann das Discovery-Token nicht schreiben, scheitert der Aufruf, selbst wenn deine Aktionsschicht ihn falsch klassifiziert. Das ist eine unabhängige Schutzmaßnahme und kein Grund, beim Aktionsinventar nachlässig zu werden.

Manche Dienste machen das mit Scopes, Rollen, Projektberechtigungen oder getrennten Maschinenidentitäten einfach. Andere bieten nur ein weitreichendes persönliches Token. Wenn ein Anbieter nur Letzteres unterstützt, verwende die engste verfügbare Konto- und Projektgrenze und setze zusätzlich bestimmte Endpunkte und Zielmuster in deinem Gateway durch. Gib einem autonomen Agent niemals das persönliche Administratorkonto, nur weil es bereits vorhanden ist.

Eine saubere Einrichtung hat oft drei Klassen von Zugangsdaten:

1. Ein Discovery-Token mit Zugriff auf genau die Ressourcen, die der Agent untersuchen darf.
2. Ein Mutation-Token für begrenzte Schreibvorgänge, die weiterhin eine Freigabe erfordern.
3. Ein Break-Glass-Token, das Agents niemals verwenden und das Menschen nur über einen Incident-Prozess abrufen.

Lass ein Mutation-Token standardmäßig keine Discovery-Aufrufe beantworten. Das wirkt harmlos, weil der Endpunkt schreibgeschützt ist, erschwert aber spätere Prüfungen. Ein Log, das zeigt, dass ein mächtiges Token eine Ressource abgefragt hat, sagt nicht, ob der Agent diese Berechtigung brauchte. Halte Identitäten aussagekräftig.

Sallyport verwahrt API- und SSH-Zugangsdaten in seinem verschlüsselten Tresor und führt die ausgehende Aktion selbst aus. Ein MCP-Agent erhält dadurch nur das Ergebnis, nicht das Geheimnis. So lässt sich eine enge Discovery-Route bereitstellen, ohne ein Bearer-Token oder private SSH-Daten in den Kontext des Agents zu legen.

## Die Freigabe sollte die Änderung beschreiben, nicht jede Anfrage bestrafen

Eine Freigabe pro Aufruf funktioniert, wenn der Prüfer eine konkrete Auswirkung sieht und schnell entscheiden kann. Sie scheitert, wenn nach jeder harmlosen Abfrage eine Zustimmung verlangt wird. Dann lernt der Mensch, dass die Aufforderung keine Entscheidung enthält, die sich zu treffen lohnt.

Verwende eine Sitzungsautorisierung, um festzulegen, welcher Agent-Prozess die Discovery-Menge verwenden darf. Verlange anschließend für Mutation-Aktionen eine einzelne Freigabe und zeige die Anfrage in Begriffen, die ein Mensch beurteilen kann. «POST /v1/jobs» ist ein schlechter Freigabetext. «Datenexport für Projekt northwind starten, Ziel: Archiv-Bucket, geschätzte Dauer: 30 Tage» gibt dem Prüfer etwas, das er kontrollieren kann.

Die Freigabekarte sollte Ziel, Operation, wichtige Parameter und Identität des Zugangstokens enthalten. Verstecke das Ziel nicht in einem langen JSON-Body. Betrifft eine Aktion mehrere Ressourcen, zeige die Anzahl und eine kompakte Auswahl. Wenn die Anzahl den üblichen Bereich überschreitet, muss der Bediener vor der Freigabe die vollständige Menge öffnen können.

Eine Anfrage für ein begrenztes Update könnte so aussehen:

```json
{
  "action": "update_issue",
  "target": {
    "repository": "payments-api",
    "issue": 1842
  },
  "changes": {
    "labels_add": ["needs-review"],
    "assignee": "release-manager"
  },
  "reason": "The release checklist is complete."
}
```

Der Agent kann diese Anfrage nach einer uneingeschränkten Discovery innerhalb seines erlaubten Umfangs vorbereiten. Der Mensch sollte die Änderung freigeben, nicht die gesamte Untersuchung des Agents rekonstruieren müssen. Bewahre die Begründung auf, weil sie eine spätere Prüfung weniger spekulativ macht. Vertraue ihr aber nicht als Sicherheitskontrolle. Ein Agent kann auch für ein falsches Ziel einen plausiblen Satz erzeugen.

Vermeide Freigaberichtlinien, die ausschließlich auf natürlichsprachlicher Absicht beruhen. «Deployment-Änderungen freigeben» klingt vernünftig, bis ein Agent das Löschen einer Datenbank als Deployment-Änderung bezeichnet. Binde die Freigabe an Operationsklasse, Zielumfang und Zugangstoken. Text hilft Menschen, die Anfrage zu verstehen. Typisierte Aktionsgrenzen verhindern Fehlzuordnungen.

## Löschung und externe Ausführung brauchen eine eigene Klasse

Löschungen, Berechtigungsänderungen, Token-Erneuerungen, finanzielle Vorgänge und Aufrufe, die externe Systeme auslösen, sollten strenger behandelt werden als gewöhnliche Updates. Sie können Wiederherstellungswege entfernen, den Zugriff verändern, Kosten verursachen oder Arbeit außerhalb des Systems starten, in dem der Agent begonnen hat.

Verstecke Löschungen nicht in der allgemeinen Mutation-Klasse. Ein Patch, der ein Issue-Label korrigiert, lässt sich meist einfach rückgängig machen. Ein Löschaufruf kann Anhänge, untergeordnete Datensätze, Verlauf oder eine benannte Umgebung entfernen. Die API kann nach einer erfolgreichen Antwort eine asynchrone Bereinigung einreihen. Dann lässt sich ein Fehler nicht immer mit einer einzigen Gegenaktion korrigieren.

Verlange eine eigene Kontrolle pro Aufruf für Aktionen wie:

1. Löschen, endgültiges Entfernen, Archivieren, wenn das Archiv die Verfügbarkeit verändert, sowie Massenlöschungen.
2. Änderungen an Berechtigungen, Mitgliedschaften, Rollen, Geheimnissen, Zugangsdaten und Zugriffsrichtlinien.
3. Deployments, Neustarts, Skalierung, Migrationen und die Ausführung entfernter Befehle.
4. Das Versenden von E-Mails, Veröffentlichen von Nachrichten, Eröffnen externer Tickets und Starten kostenpflichtiger Jobs.

Bevor die Freigabe einen Menschen erreicht, muss der Agent Kennungen in eine Vorschau auflösen. Eine Löschanfrage gegen `records?filter=status=inactive` sollte die genaue Anzahl, den Filter und repräsentative Namen zeigen. Noch besser ist es, wenn der Agent zuerst die Kandidatenkennungen abruft und eine Liste einreicht, die das Gateway mit der späteren Ausführungsanfrage vergleicht. Das beseitigt Race Conditions nicht, fängt aber den häufigsten Fehler ab: einen Filter, der etwas anderes bedeutet als vom Agent angenommen.

Eine zeitlich begrenzte Bestätigung ist ebenfalls sinnvoll. Wenn ein Bediener eine destruktive Anfrage vor einer Stunde freigegeben hat, sollte der Agent diese Freigabe nach einer Änderung des umgebenden Zustands nicht mehr verwenden können. Binde die Freigabe an genau einen Request-Body oder einen unveränderlichen Request-Digest, nicht an eine breite Kategorie wie «Zugriff heute löschen».

## SSH braucht eine Klassifizierung auf Befehlsebene

SSH ist schwieriger zu klassifizieren als eine gut entworfene API, weil eine Befehlszeile Inspektion und Mutation verbinden, eine Shell aufrufen, Aliase verwenden oder ihr Verhalten an die entfernte Umgebung anpassen kann. Du kannst nicht einen ganzen Host als schreibgeschützt behandeln, nur weil der Agent einen Lesevorgang ausführen möchte.

Beginne mit ausdrücklichen Befehlen und Argumenten. `git status --short`, `git log -n 20 --oneline` und `kubectl get pods -n staging` sind plausible Discovery-Aktionen, wenn Arbeitsverzeichnis, Cluster-Kontext und Namespace begrenzt werden. `git push`, `kubectl apply`, `kubectl delete`, `rm`, die Installation von Paketen und Neustarts von Diensten gehören in die Klassen Mutation oder destruktive Ausführung.

Lehne Shell-Komposition für unbeaufsichtigte Discovery ab. Ein solcher Befehl sieht wie eine Auflistungsanfrage aus, gibt die Kontrolle aber an die Shell zurück:

```sh
find "$WORKDIR" -maxdepth 2 -type f -name '*.log' -print; $EXTRA_COMMAND
```

Selbst wenn der Agent beim Testen ein leeres `EXTRA_COMMAND` übergibt, kann ein späterer Wert alles ausführen, was die SSH-Identität erlaubt. Genehmige keine Befehlsgrammatik mit `;`, `&&`, `||`, Befehlsersetzung, Umleitungen, Wildcard-Erweiterungen über unkontrollierte Pfade oder einem Interpreter-Aufruf, es sei denn, die Aktion wird selbst als Ausführung geprüft.

Verwende stattdessen strukturierte Argumente. Ein Gateway kann eine Aktion namens `list_recent_logs` akzeptieren, ein festes Verzeichnis und ein numerisches Limit prüfen und anschließend den entfernten Befehl selbst erstellen. Der Agent sollte niemals einen Shell-String einreichen, wenn eine typisierte Aktion genügt.

Dasselbe Prinzip gilt für Tools mit Leseverben. `kubectl get` kann geheime Daten offenlegen, wenn Ressource und Namespace zu weit gefasst sind. `git show` kann ein versehentlich eingechecktes Zugangstoken preisgeben. Baue Befehlsberechtigungen um ausführbare Datei, Unterbefehl, Argumente, Arbeitsverzeichnis und entfernte Identität herum. Das Verb allein sagt sehr wenig aus.

## Audit-Einträge müssen zeigen, dass die Grenze gehalten hat

Ein Audit-Trail sollte einem Prüfer beantworten, wer einen Aufruf ausgeführt hat, über welchen Zugangstoken-Weg die Aktion lief, welches Ziel erreicht wurde, ob ein Mensch sie freigegeben hat und was das entfernte System zurückgab. Wenn der Trail nur «Agent hat Tool aufgerufen» protokolliert, kann er nicht belegen, dass Discovery-Zugriff und Mutation-Berechtigung getrennt blieben.

Protokolliere sowohl versuchte als auch abgeschlossene Aktionen. Eine abgelehnte Löschanfrage ist relevant. Sie kann zeigen, dass der Agent seinen Umfang missverstanden hat, dass eine Prompt Injection ihn steuern wollte oder dass jemand die Grenze testet. Zeichne den Ablehnungsgrund auf, aber schreibe keine Geheimnisse oder sensiblen Antwortdaten in ein Log, auf das mehr Personen Zugriff haben als auf das Ursprungssystem.

Erfasse für jede Aktion mindestens diese Felder in einem manipulationssicheren Datensatz:

- Identität des Agent-Prozesses und Sitzungskennung.
- Aktionsklasse: Discovery, Mutation, destruktive Aktion oder externe Ausführung.
- Zielidentität, Request-Methode oder Befehlsform und eine sichere Darstellung der Parameter.
- Freigabeereignis einschließlich des freigebenden Menschen, sofern erforderlich.
- Ergebnis, Status des entfernten Systems, Ergebnisreferenz und Zeitstempel.

Eine Hash-Kette hilft, nachträgliche Änderungen am Log zu erkennen. Sie macht einen vagen Eintrag aber nicht nützlich. Speichere vor der Ausführung einen kanonischen Aktionsdatensatz und binde den Antwortdatensatz daran. Wenn der Eintrag nur `POST /jobs` lautet, kann ein späterer Prüfer nicht erkennen, ob der Agent einen harmlosen Bericht oder einen teuren Export gestartet hat.

Sallyport führt Sitzungs- und Aufrufprotokolle in einem verschlüsselten, hashverketteten Audit-Log zusammen. Mit `sp audit verify` lässt sich die Kette offline prüfen, ohne auf den Tresor zuzugreifen. Diese Prüfung ist nur dann hilfreich, wenn die Aktionstypen den Eintrag verständlich machen. Halte die Klassifizierung deshalb nahe am Ausführungspfad, statt sie erst später in einer Berichtsschicht hinzuzufügen.

## Die Grenze mit Fehlern testen, nicht nur mit erfolgreichen Abläufen

Eine Berechtigungstrennung verdient Vertrauen, wenn sie vorhersehbare schlechte Anfragen blockiert. Behandle jede Discovery-Aktion als testbaren Vertrag und führe negative Tests aus, sobald sich API, Befehls-Wrapper oder Agent-Workflow ändern.

Teste bei einer HTTP-Discovery-Route ein erlaubtes Ziel, ein benachbartes verbotenes Ziel, eine nicht unterstützte Methode, eine zu große Seitenanfrage und eine Query, die versucht, eine Mandanten- oder Projektgrenze zu überschreiten. Erwarte spezifische Ablehnungen. Ein allgemeiner Serverfehler ist ein schlechter Beleg, weil aus ihm nach einer kleinen Codeänderung ein Erfolg werden kann.

Teste bei einer Mutation-Route, dass eine gültige Anfrage auf eine Freigabe wartet, dass die Änderung jedes relevanten Feldes die Freigabe ungültig macht und dass ein zweiter Agent-Prozess die Sitzungsberechtigung des ersten nicht übernimmt. Teste bei Löschungen leere Selektoren, Selektoren mit Wildcard-Charakter, unerwartet große Listen und Ziele, die zwischen Vorschau und Ausführung verschwunden sind.

Bewahre für jede Aktionsklasse einen vollständigen Ablauf auf. Ein guter Trace ist kurz genug zum Lesen und konkret genug, um eine Fehlzuordnung sichtbar zu machen:

```text
09:14:03  discovery  GET /projects/acme/services?limit=20  allowed
09:14:05  discovery  GET /projects/acme/services/api-7/events  allowed
09:14:11  mutation   POST /projects/acme/services/api-7/restart  approval required
09:14:32  mutation   POST /projects/acme/services/api-7/restart  approved by operator
09:14:34  mutation   result: accepted, operation=op_481
```

Wenn die dritte Zeile stattdessen `GET /services/api-7?action=restart` lautet, hat dein Klassifizierungsmodell bereits einen Fehler gefunden. Korrigiere den Aktionsvertrag oder stelle die Route unter die Mutation-Kontrolle. Lege keine Ausnahme an, nur weil der Endpunkt unpraktisch ist.

Beginne mit den externen Aktionen, die deine Agents bereits ausführen. Ordne jede nach ihrer Wirkung ein, überprüfe ihr tatsächliches Verhalten, begrenze das Ziel und teste die Ablehnungsfälle. Wenn der Agent etwas Neues tun möchte, verlange eine ausdrückliche Klassifizierung, bevor die Aktion die Produktion erreicht. Diese kurze Pause ist günstiger, als im Nachhinein eine ungeprüfte Änderung erklären zu müssen.
