# Fehler in Agenten-Tools, die helfen, ohne Geheimnisse offenzulegen

Fehler in Agenten-Tools brauchen genug Struktur, damit sich ein Agent davon erholen kann. Sie dürfen aber nicht jede fehlgeschlagene Anfrage in einen Export von Zugangsdaten verwandeln. Diese Grenze lässt sich leicht beschreiben und wird in der Praxis regelmäßig verletzt: Ein Wrapper fängt eine Exception ab, gibt die Meldung der Bibliothek zurück und überreicht dem Modell nebenbei eine URL, einen Authorization-Header, die Bezeichnung eines Zertifikats, ein SSH-Ziel oder einen Teil eines Tokens.

Ich habe erlebt, wie der Schaden mit einem gut gemeinten Debugging-Feld begann. Jemand fügte `request_headers` hinzu, weil ein Agent ständig 401-Antworten erhielt. Der Agent kopierte den Fehler in seine Arbeitsnotizen. Diese Notizen wurden in einen Pull Request eingefügt, an ein Supportsystem geschickt oder in einem Evaluierungs-Trace aufbewahrt. Der ursprüngliche Fehler war vorbei. Das Geheimnis blieb.

Das richtige Design gibt dem Agenten eine begrenzte Erklärung dessen, was geschehen ist, nennt eine sichere nächste Handlung und liefert eine Korrelationskennung für eine zuständige Person. Rohdaten bleiben hinter der Aktionsgrenze. Es geht nicht um eine Wahl zwischen nützlichen und geheimnissicheren Fehlern. Es geht um das Design einer Schnittstelle.

## Eine Fehlerantwort gehört zur Sicherheitsgrenze

Ein Agent behandelt die Ausgabe eines Tools als Arbeitsgedächtnis. Er kann diese Ausgabe einem Nutzer zitieren, in einer Datei ablegen, an ein anderes Tool senden oder für die Wahl eines erneuten Versuchs verwenden. Jedes Feld, das ein Action-Gateway zurückgibt, muss daher als Offenlegung gegenüber einem nicht vertrauenswürdigen Aufrufer behandelt werden, selbst wenn der Aufrufer ein Agent ist, den ein Entwickler gestartet hat, dem die Maschine gehört.

Ein Tool-Aufruf hat zwei Zielgruppen. Der Agent braucht operative Fakten: Wurde die Aktion ausgeführt, darf er es erneut versuchen, braucht er eine Zustimmung und welche Eingabe muss er ändern? Die zuständige Person braucht forensische Fakten: Welche Zugangsdaten wurden ausgewählt, welche genaue Route wurde aufgerufen, welcher DNS-Resolver ist ausgefallen und was hat die Gegenstelle gesagt? Befriedige die zweite Zielgruppe nicht, indem du deren Beweise an die erste weitergibst.

Der Unterschied ist besonders wichtig, wenn ein Agent Tools wiederholt aufrufen kann. Ein Mensch bemerkt vielleicht schon beim einmaligen Lesen einer ausführlichen Fehlermeldung ein darin enthaltenes Bearer-Token. Ein Agent kann es über Dutzende Durchläufe hinweg bewahren und später in generierten Code oder ein Test-Fixture aufnehmen. Dafür braucht das Modell keine böswillige Absicht.

Baue die Schnittstelle nach einer klaren Regel: Der Aufrufer erhält nur Felder, die auch dann sicher bleiben, wenn sie in einem öffentlichen Ticket kopiert werden. Besteht ein Feld diesen Test nicht, speichere es in geschützten Diagnosen oder lasse es weg.

## Gib Agenten Entscheidungen statt Exception-Strings

Eine nützliche Antwort sagt dem Agenten, welcher Entscheidungstyp vor ihm liegt. Rohe Exceptions leisten das weder zuverlässig noch sicher. Ihre Formulierung ändert sich mit Betriebssystem-Releases und Versionen von Client-Bibliotheken. Außerdem vermischen sie oft die technische Ursache mit Material, das privat bleiben muss.

Verwende ein kleines, dokumentiertes Vokabular von Codes. Jeder Code sollte einem bestimmten Verhalten des Aufrufers entsprechen. Gestalte die Codes nicht so detailliert, dass du am Ende jeden möglichen Fehler der vorgelagerten Systeme nachbildest.

Eine praktische Antwortstruktur sieht so aus:

```json
{
  "ok": false,
  "code": "AUTH_FAILED",
  "message": "The remote service rejected the stored credential.",
  "action": "stop_and_report",
  "retryable": false,
  "request_id": "act_7f3c2a91",
  "http_status": 401
}
```

Der Agent kann anhalten, dem Nutzer mitteilen, dass die Authentifizierung geprüft werden muss, und die Request-ID angeben. Für diese Entscheidung braucht er weder das Bearer-Token noch das Autorisierungsschema, die E-Mail-Adresse des Kontos oder den kopierten Antworttext.

`action` ist nützlicher als ein einzelner vager boolescher Wert. Ein boolescher Wert sagt, ob Zeit das Problem möglicherweise behebt. Eine Aktion sagt dem Agenten, was er tun soll. Halte die erlaubten Werte knapp:

- `retry_after_delay` für vorübergehende, sicher wiederholbare Vorgänge.
- `repair_input` für eine Anfrage, die der Agent ohne neue Berechtigung korrigieren kann.
- `request_approval`, wenn eine Person die Aktion erlauben muss.
- `stop_and_report` für Fehler, bei denen eine zuständige Person eingreifen muss.
- `inspect_outcome`, wenn ein Schreibvorgang die Gegenstelle erreicht haben könnte.

Der letzte Wert verdient besondere Beachtung. Ein Timeout nach dem Senden eines Schreibvorgangs ist nicht dasselbe wie ein Timeout davor. Wenn du beide Fälle zu `NETWORK_ERROR` zusammenfasst, wird ein Agent eine möglicherweise bereits ausgeführte Aktion wiederholen. So entstehen doppelte Tickets, Bereitstellungen und Datensätze sowie wiederholte destruktive Befehle.

Gib `http_status` nur zurück, wenn der Wert aussagekräftig und sicher ist. Bei HTTP-Aufrufen liefert er oft hilfreichen Kontext. Tu aber nicht so, als gäbe er die vollständige Antwort. Ein 403 kann auf einen Autorisierungsfehler der Gegenstelle, eine Einschränkung auf Ressourcenebene oder eine Entscheidung eines Gateways hindeuten. Dein Tool-Code muss das Verhalten benennen, das der Agent zeigen soll.

## Halte die Code-Taxonomie klein genug zum Testen

Eine Code-Taxonomie sollte Zuständigkeit und Wiederherstellung beschreiben, nicht jede Schicht des Netzwerkstapels. Wenn deine Liste schon nach der ersten Woche fünfzig Codes umfasst, exportierst du wahrscheinlich Implementierungsdetails unter einem anderen Namen.

Beginne mit Kategorien, bei denen der Aufrufer unterschiedliche Aktionen ausführen kann:

| Code | Bedeutung | Verhalten des Agenten |
| --- | --- | --- |
| `INVALID_INPUT` | Das Tool hat die gelieferten Felder vor einer externen Aktion abgelehnt. | Eingabe korrigieren. |
| `VAULT_LOCKED` | Das Gateway kann keine gespeicherten Geheimnisse verwenden. | Eine Person bitten, das Tresor zu entsperren. |
| `USER_DENIED` | Eine Person hat diese Aktion abgelehnt. | Anhalten. Nicht umformulieren und erneut senden. |
| `AUTH_FAILED` | Der externe Dienst hat die ausgewählten Zugangsdaten abgelehnt. | Anhalten und melden. |
| `REMOTE_FORBIDDEN` | Die Anfrage wurde authentifiziert, besitzt aber keine Berechtigung auf der Gegenseite. | Anhalten und melden. |
| `RATE_LIMITED` | Der externe Dienst hat die Aufrufer aufgefordert, langsamer zu werden. | Warten, wenn eine sichere Verzögerung existiert. |
| `TEMPORARY_FAILURE` | Eine wiederholbare Anfrage ist vorübergehend fehlgeschlagen. | Innerhalb eines begrenzten Budgets erneut versuchen. |
| `OUTCOME_UNKNOWN` | Ein Schreibvorgang könnte vor dem Fehler abgeschlossen worden sein. | Vor jedem neuen Versuch das Ergebnis prüfen. |
| `NETWORK_UNREACHABLE` | Das Gateway konnte einen externen Endpunkt nicht erreichen. | Nur erneut versuchen, wenn die Aktion sicher wiederholbar ist. |
| `INTERNAL_FAILURE` | Das Gateway ist ohne sichere Abhilfe für den Aufrufer fehlgeschlagen. | Anhalten und die Request-ID melden. |

Verwende `ERROR`, `FAILED` oder `EXCEPTION` nicht als primären Vertrag. Solche Bezeichnungen übertragen die Interpretationslast auf den Agenten, der aus dem Beschreibungstext eine Abhilfe ableiten muss. Das kann schiefgehen.

Halte die Bedeutung der Codes stabil. Du kannst die menschliche Meldung verbessern, ein Feld `retry_after_seconds` ergänzen oder einen neuen sicheren Statuswert aufnehmen. Ändere jedoch nicht die Bedeutung von `AUTH_FAILED`, sodass der Code zugleich falsche Zugangsdaten und eine lokal verweigerte Freigabe bezeichnet. Agenten und ihre umgebende Orchestrierung werden irgendwann darauf reagieren.

RFC 9457, „Problem Details for HTTP APIs“, liefert eine nützliche Grundlage: Antworten können einen stabilen Problemtyp, einen Titel, einen Status, Details und eine Instanzreferenz enthalten. Der Hinweis, den Teams oft überspringen, ist entscheidend. Der RFC sagt, dass `detail` bei der Behebung des Problems helfen soll und dass Problemdetails sensible Informationen offenlegen können. Bei Agenten-Tools sollte der stabile Typ oder Code der Vertrag sein, die Detailangabe kurz bleiben und die Instanz- oder Request-ID eine Verbindung zwischen dem Agenten und geschützten Beweisen für die zuständige Person herstellen.

## Request-Header und Verbindungsfehler sind Beweise, kein Kontext

Teams bezeichnen rohe Header und Transportmeldungen häufig als „Kontext“. Sie sind Beweise. Beweise gehören mit Zugriffskontrollen in einen Audit-Datensatz, nicht in eine Agentenantwort.

Betrachte eine fehlgeschlagene API-Anfrage. Eine typische Exception einer HTTP-Bibliothek kann die vollständige angeforderte URL, eine Weiterleitungsadresse, die Proxy-Adresse, Antwort-Header und einen Teil des Antworttexts enthalten. Jeder dieser Werte kann Geheimnisse tragen. Query-Parameter enthalten in älteren APIs weiterhin API-Schlüssel. `Location`-Header enthalten häufig signierte Download-URLs. Cookies und benutzerdefinierte Authentifizierungs-Header sind offensichtliche Lecks. Weniger auffällige Felder wie `X-Request-Id` können unproblematisch sein, während `X-Forwarded-Host` oder ein interner Service-Header Infrastruktur offenlegen kann, die der Agent nie kennen musste.

Für SSH gilt dieselbe Disziplin. Gib keine Befehlszeile mit einem privaten Ziel, einem Pfad zu known_hosts, einer angebotenen Identitätsdatei oder dem rohen Text eines Host-Key-Konflikts zurück. Ein Host-Key-Konflikt hat eine für den Aufrufer relevante Bedeutung: Die Verbindung ist blockiert, weil die Identität der Gegenstelle nicht verifiziert werden kann. Gib diese Bedeutung zurück. Bewahre den Fingerabdruckvergleich, Pfade und Bibliotheksdiagnosen für die zuständige Person auf.

OAuth 2.0 macht diesen Punkt besonders deutlich. RFC 6750 sagt, dass ein Bearer-Token jedem Zugriff gewährt, der es besitzt, und weist Clients an, Tokens vor Offenlegung in Speicherung und Transport zu schützen. Ein Fehler-Handler, der ein Bearer-Token in einen Trace kopiert, hat diese Anforderung verletzt, selbst wenn die ursprüngliche Anfrage TLS korrekt verwendet hat.

Bereinige vor der Serialisierung, nicht erst nachdem sich Logs verbreitet haben. Ein Redaktionsfilter in einem allgemeinen Log-Sink ist eine sinnvolle Rückfallebene, aber nicht die Grenze. Bis dahin kann eine ausgelöste Exception bereits an ein Tool-Ergebnis, ein Telemetrieereignis oder einen Crash-Report angehängt worden sein.

Verwende für Felder, die an den Agenten gelangen, eine Allowlist. Eine Denylist übersieht irgendwann `x-api-token`, einen signierten Query-Parameter, ein anbieterspezifisches Sitzungsfeld oder eine neue Eigenschaft der Bibliothek. Eine Allowlist beginnt ohne Offenlegung und ergänzt nur Felder, für die eine konkrete Verwendung durch den Aufrufer feststeht.

## Trenne, was fehlgeschlagen ist, davon, ob eine Aktion ausgeführt wurde

Ein sicheres Fehlerdesign muss einem Agenten sagen, ob die Gegenstelle möglicherweise gehandelt hat. Genau hier wird die Anleitung zum erneuten Versuch meistens gefährlich.

Angenommen, ein Agent sendet `POST /deployments` und seine Verbindung läuft in einen Timeout. Das Gateway weiß, dass es den Aufruf versucht hat. Es weiß nicht, ob die Gegenstelle ihn empfangen hat, ob sie eine Bereitstellung angelegt hat oder ob die Antwort auf dem Rückweg verschwunden ist. `TEMPORARY_FAILURE` zurückzugeben lädt den Agenten dazu ein, eine weitere Bereitstellungsanfrage zu senden. `AUTH_FAILED` wäre schlicht falsch. Der korrekte Zustand ist `OUTCOME_UNKNOWN`.

Die Antwort sollte das klar sagen:

```json
{
  "ok": false,
  "code": "OUTCOME_UNKNOWN",
  "message": "The connection ended after the request started. The remote action may have completed.",
  "action": "inspect_outcome",
  "retryable": false,
  "request_id": "act_9b18d4e0",
  "operation": "create_deployment"
}
```

`operation` bezeichnet eine allgemeine Aktionsklasse, nicht die vollständige Route oder Nutzlast. Der Agent kann nun einen separaten, schreibgeschützten Statusaufruf verwenden, sofern die Integration einen solchen anbietet. Unterstützt die API Idempotenzreferenzen, kann das Gateway die sichere Referenz mit der Operation verknüpfen und sie intern abfragen. Gib einen Idempotenzwert nicht heraus, wenn er im Zielsystem zugleich als Zugriffsmaterial dient.

Auch Leseoperationen sind nicht automatisch sicher wiederholbar. Ein Lesevorgang kann eine Abrechnung auslösen, einen externen Zustand aktualisieren oder hinter einer harmlosen Bezeichnung einen Befehl mit Nebenwirkungen ausführen. Der Autor der Integration muss kennzeichnen, ob eine Operation wiederholbar ist. Überlasse diese Entscheidung nicht einem Sprachmodell, das sie aus dem Methodennamen ableitet.

Lege im Gateway ein Wiederholungsbudget fest. Eine Antwort kann eine begrenzte Verzögerung wie `retry_after_seconds: 30` enthalten, aber nur, wenn die Gegenstelle einen sicheren Wert geliefert hat oder das Gateway das Limit kontrolliert. Lass einen Agenten nicht unbegrenzt wiederholen, nur weil eine Meldung „vorübergehend“ sagt. Wiederholte Fehler erzeugen Rauschen, verbrauchen Rate-Limits und erschweren spätere Untersuchungen.

## Eine menschliche Ablehnung braucht eine eigene Bedeutung

Wenn eine Person eine Freigabe ablehnt, handelt es sich nicht um einen Authentifizierungsfehler der Gegenstelle. Es bedeutet, dass die angeforderte Aktion nicht ausgeführt wurde. Diese Unterscheidung schützt Sicherheit und Bedienbarkeit.

Ordnet ein Tool eine abgelehnte Freigabe `AUTH_FAILED` zu, kann ein Agent alternative Zugangsdaten versuchen, die Rotation eines Geheimnisses verlangen oder eine leicht veränderte Anfrage senden. Keine dieser Aktionen respektiert die Person, die abgelehnt hat. Wird die Ablehnung als allgemeiner interner Fehler abgebildet, kann der Nutzer nicht erkennen, ob das Gateway ausgefallen ist.

Gib `USER_DENIED` mit einer kurzen Meldung wie „Die angeforderte Aktion wurde nicht genehmigt und nicht ausgeführt“ zurück. Erwähne nicht den Namen des Geheimnisses, das ausgewählte Konto oder das genaue Ziel, wenn diese Angaben nicht bereits Teil des sicheren Eingabevertrags des Tools sind. Der Aufrufer muss anhalten. Eine Person kann entscheiden, ob sie eine neue, sichtbare Anfrage startet.

Ein gesperrter Geheimnisspeicher ist wiederum etwas anderes. `VAULT_LOCKED` bedeutet, dass das Gateway die Aktion abgelehnt hat, bevor es Zugangsdaten auswählen oder verwenden konnte. Die sichere Abhilfe besteht darin, eine Person zum Entsperren des Gateways aufzufordern, nicht darin, den Agenten um ein Token zu bitten. So wird ein vertrautes Fehlermuster verhindert, bei dem ein Modell wegen nicht verfügbarer verwalteter Zugangsdaten in seinem Kontext nach einem anderen Geheimnis sucht.

Sallyport setzt diese Trennung direkt um: Solange das Tresortor gesperrt ist, lehnt es jede Aktion ab. Seine sitzungsbezogene Autorisierung kann außerdem einen neuen Prozess, der eine Freigabe benötigt, von einem externen Dienst unterscheiden, der einen authentifizierten Aufruf abgelehnt hat. Der Agent erhält das Ergebnis der Aktion, während die Zugangsdaten im verschlüsselten App-Tresor bleiben.

Überdecke Freigabemüdigkeit nicht mit mehr Diagnoseinformationen. Wenn Nutzer regelmäßig Aufrufe genehmigen, die sie nicht geprüft haben, verbessere die für die Freigabe angezeigte Gruppierung, den Umfang und die Prozessidentität. Ausführlichere Ablehnungen machen hastige Zustimmung nicht sicherer.

## Baue einen Diagnosepfad mit zwei Datensätzen

Ein Datensatz sollte für den Agenten sicher sein, der andere vollständig genug für eine autorisierte Person. Der Versuch, einen einzigen Datensatz für beide Aufgaben zu verwenden, führt entweder zu schlechter Unterstützung oder zu einem Geheimnisleck.

Der für den Aufrufer sichere Datensatz braucht einen Code, eine Meldung, eine Aktion, Hinweise zum Wiederholen, eine Request-ID und gegebenenfalls einen Protokollstatus. Der geschützte Datensatz kann die Kennung des ausgewählten Zugangsdaten-Eintrags, das normalisierte Ziel, die Methode, Zeitangaben, Metadaten der Antwort der Gegenstelle, einen bereinigten Fingerabdruck der Nutzlast, die rohe Exception und einen Trace der Gateway-Entscheidung enthalten. Speichere diesen Datensatz an einem Ort, den Agenten nicht über gewöhnliche Tools abfragen können.

Eine Request-ID sollte undurchsichtig sein. Erzeuge sie unabhängig von Zugangsdaten und Zielen. Kodiere keinen Hostnamen, keinen Zeitstempel, der Aktivitätsmuster verrät, und keine fortlaufende Datenbank-ID, wenn diese Details in deiner Umgebung relevant sind. Die ID ermöglicht es einem Nutzer zu sagen: „Bitte prüfe act_9b18d4e0“, ohne die zugrunde liegenden Diagnosen auszuhändigen.

Bei Aktionen mit hohem Wert solltest du festhalten, ob das Gateway jede Grenze erreicht hat: Eingabevalidierung, Auswahl der Zugangsdaten, Autorisierung durch den Nutzer, Beginn der Verbindung, gesendete Anfrage-Bytes, empfangene Antwort und zurückgegebenes Ergebnis. Diese Abfolge liefert einer zuständigen Person eine belastbare Erklärung für `OUTCOME_UNKNOWN`, ohne dem Agenten die rohe Anfrage zu zeigen.

Für diesen internen Pfad ist Manipulationserkennung wichtig. Wenn jemand fehlgeschlagene Autorisierungsversuche unbemerkt entfernen oder den Grund für eine blockierte Aktion umschreiben kann, wird der Audit-Trail zu einem bloßen Komfort-Log. Sallyport erzeugt Ansichten für Sitzungen und Aufrufe aus einem verschlüsselten, hashverketteten Audit-Log. `sp audit verify` prüft die Kette offline über Chiffretext. Das ist hilfreich, wenn eine zuständige Person dem Datensatz vertrauen muss, ohne dem Agenten Zugriff auf seinen Inhalt zu geben.

Ein geschützter Datensatz könnte so aussehen. Er ist absichtlich keine Agentenantwort:

```json
{
  "request_id": "act_9b18d4e0",
  "event": "http_call_failed",
  "credential_record": "cred_42",
  "destination": "api.internal.example",
  "method": "POST",
  "path_template": "/deployments",
  "bytes_sent": true,
  "response_received": false,
  "exception_class": "ReadTimeout",
  "result_code": "OUTCOME_UNKNOWN"
}
```

Prüfe auch hier die Felder sorgfältig. Ein vollständiger Pfad kann Ressourcenkennungen offenlegen. Ein Anfrage-Body sollte normalerweise zu einem Einweg-Fingerabdruck, einem Schemanamen oder einer stark bereinigten Darstellung werden. Zuständige Personen müssen oft zwei Versuche vergleichen und nicht jeden übermittelten Wert lesen.

## Fehlermeldungen brauchen eine bewusste Redaktionsrichtlinie

Redaktion bedeutet nicht, ein Token durch acht Sternchen zu ersetzen. Damit behandelst du nur die geheimen Formate, die du bereits kennst. Eine geeignete Richtlinie klassifiziert Felder, bevor sie in Meldungen, Logs, Metriken und Tool-Ergebnisse gelangen.

Klassifiziere zuerst direkte Geheimnisse: Bearer-Tokens, Passwörter, private Schlüssel, Cookies, signierte URLs, Authorization-Header und Client-Zertifikate. Ordne danach sensiblen Kontext ein: interne DNS-Namen, lokale Pfade, Benutzernamen, Repository-Namen, Ressourcen-IDs, Request-Bodies und Header, die die Bereitstellungstopologie verraten. Die zweite Klasse kann in einem geschützten Datensatz vertretbar sein, gehört aber selten in einen für Agenten sichtbaren Fehler.

Gib nicht zurück: „Zugangsdaten mit dem Ende 7KQ2 wurden abgelehnt.“ Teams ergänzen diese Angabe, weil mehrere Zugangsdaten existieren und die zuständige Person wissen möchte, welche fehlgeschlagen sind. Dadurch entsteht eine dauerhafte Kennung, die über Traces hinweg korreliert werden kann. Gib dem Agenten `AUTH_FAILED` zurück. Die zuständige Person kann den Zugangsdaten-Eintrag über die geschützte Request-ID prüfen.

Gib Tool-Eingaben standardmäßig nicht wieder aus. Ein Agent weiß bereits, was er versucht hat. Das Gateway kann aber nicht voraussetzen, dass diese Eingabe selbst sicher wiederholt werden kann. Eine URL kann eine signierte Query-Zeichenfolge enthalten. Ein Befehl kann eine Umgebungszuweisung enthalten. Eine JSON-Nutzlast kann ein temporäres Zugangsdatenmaterial enthalten, das der Agent von einem anderen System erhalten hat. Gib einen feldbezogenen Validierungsfehler wie `invalid_fields: ["repository"]` zurück, nicht den kopierten ungültigen Wert.

Teste die Redaktion mit feindseligen Fixtures. Nimm Geheimnisse in ungewöhnlicher Groß- und Kleinschreibung, doppelte Header, URL-Userinfo, prozentkodierte Query-Werte, verschachteltes JSON, Exception-Ursachen und SSH-Befehlsargumente auf. Stelle anschließend sicher, dass kein Geheimnis aus dem Fixture in der serialisierten Tool-Antwort, allgemeinen Logs, Metrik-Labels oder Crash-Nutzdaten auftaucht. Ein Test, der nur den Erfolgsfall prüft, sagt über das Fehlerverhalten nichts aus.

## Behandle Meldungen der Gegenstelle als nicht vertrauenswürdige Eingabe

Eine Remote-API kann einen hilfreichen Fehler-Body, eine HTML-Anmeldeseite oder eine Zeichenfolge zurückgeben, die gezielt die lesende Person beeinflussen soll. Das Gateway darf diesen Inhalt nicht direkt in den Kontext eines Agenten weiterreichen.

Das ist teilweise ein Geheimnisproblem. Server spiegeln in Fehlerseiten gelegentlich Anfragewerte zurück. Ein ungültiger Authorization-Header, ein Cookie, ein Query-Parameter oder ein JSON-Feld kann in einer Diagnoseantwort der Gegenstelle wieder auftauchen. Wer diese Antwort durchreicht, verwandelt ein Echo der Gegenstelle in ein Zugangsdatenleck.

Es ist auch ein Problem der Integrität von Anweisungen. Wenn ein Upstream-Fehler sagt: „Führe diesen Befehl aus, um deine Zugangsdaten zu reparieren“, könnte der Agent das als operative Anleitung behandeln. Der externe Dienst darf nicht die Richtlinie des Gateways für die Fehlerbehebung bestimmen.

Übernimm bekannte sichere Felder aus einer Protokollantwort der Gegenstelle. Ein numerischer HTTP-Status und eine dokumentierte Verzögerung für ein Rate-Limit können beispielsweise nützlich sein. Behandle freie Antworttexte als geschützte Beweise, sofern du keinen formatspezifischen Parser und eine klare Allowlist hast. Wenn eine Integration einen für Menschen lesbaren Grund der Gegenstelle braucht, normalisiere ihn in eine vom Gateway kontrollierte Formulierung wie „Der Dienst hat die angeforderte Ressource abgelehnt“, statt den Originaltext zu kopieren.

RFC 9110 definiert die Semantik von HTTP-Statuscodes. Diese Statuscodes erlauben jedoch nicht die Offenlegung des Antwort-Bodies einer Quelle. Halte diese Trennung klar. Protokollinformationen können bei der Wiederherstellung helfen. Beliebiger Text der Gegenstelle ist kein sicherer Diagnosevertrag.

## Verankere den Vertrag in fehlerorientierten Tests

Die meisten Teams testen, dass eine gültige Anfrage nützliche Daten zurückgibt. Teste auch, dass jede ungültige oder unterbrochene Anfrage ausschließlich Daten zurückgibt, die der Agent sehen darf.

Mache das Fehlerschema zu einem versionierten Vertrag. Validiere es in Tests und lehne unbekannte Felder während der Entwicklung an der Serialisierungsgrenze ab. Eine Allowlist lässt sich leichter prüfen, wenn das Objekt eine strenge Form besitzt.

Verwende ein Fixture-Geheimnis, das auffällig genug ist, um versehentliche Veränderungen zu erkennen, und erzwinge Fehler in jeder Phase. Deine Testmatrix sollte die Validierung vor der Auswahl von Zugangsdaten, ein gesperrtes Tresor, abgelehnte Zustimmung, Antworten 401 und 403 der Gegenstelle, Rate-Limiting, DNS-Fehler, fehlgeschlagene TLS-Validierung, einen Timeout bevor Bytes das System verlassen, einen Timeout nachdem Bytes gesendet wurden, fehlerhaftes JSON der Gegenstelle und eine vom Gateway selbst ausgelöste Exception abdecken.

Prüfe für jeden Fall vier Dinge:

- Die Tool-Antwort enthält den erwarteten Code und die erlaubte Aktion.
- Das Fixture-Geheimnis kommt in keinem für den Aufrufer sichtbaren serialisierten Feld vor.
- Die Antwort enthält weder rohe Header noch den rohen Antworttext der Gegenstelle oder lokale Verbindungsdetails.
- Der geschützte Diagnose-Datensatz enthält die Request-ID und genügend Zustand für eine Untersuchung durch die zuständige Person.

Verlass dich nicht ausschließlich auf reguläre Ausdrücke. Suche nach dem exakten Fixture-Geheimnis, seiner URL-kodierten Form, seiner Base64-Form, sofern relevant, sowie nach gängigen Präfixen und Suffixen. Prüfe anschließend eine aufgezeichnete Fehlerantwort manuell, wann immer du eine HTTP-, SSH-, Telemetrie- oder Crash-Reporting-Abhängigkeit aktualisierst. Bibliotheken ändern das Format von Exceptions, ohne dich um Erlaubnis zu bitten.

Die schwierige Aufgabe besteht darin, dem Agentenfehler nicht das Aussehen deiner Debug-Konsole geben zu wollen. Halte den Vertrag für den Aufrufer klein, stabil und auf Aktionen ausgerichtet. Bewahre die Beweise geschützt und korreliert auf. Wenn der nächste Ausfall eintritt, gibt diese Trennung dem Agenten genug Informationen für ein sicheres Verhalten und der zuständigen Person genug Informationen, um den tatsächlichen Fehler zu beheben.
