Wiederholt die Verarbeitung von Anfragen bei gesperrtem Tresor einen Aufruf?
Teste die Verarbeitung von Anfragen bei gesperrtem Tresor, damit abgelehnte Aufrufe von KI-Agenten verworfen und nach dem Öffnen weder aufbewahrt noch wiederholt werden.

Ein gesperrter Tresor muss eine klare zeitliche Grenze schaffen. Eine Anfrage, die vor dem Aufheben dieser Grenze ein Aktions-Gateway erreicht, muss sofort scheitern. Sie darf nicht in einer Warteschlange liegen bleiben, eine erneute Verbindung überdauern oder ausführbar werden, weil sich später jemand am Tresor authentifiziert.
Das klingt selbstverständlich, bis du einen echten Agent-Stack testest. Agenten wiederholen Anfragen. MCP-Clients verbinden sich neu. HTTP-Bibliotheken senden eine Anfrage nach einer abgebrochenen Antwort erneut. Worker bewahren Aufgaben auf. Eine Oberfläche kann eine Ablehnung anzeigen, während eine andere Komponente bereits genug Zustand gespeichert hat, um den Aufruf später auszuführen. Wenn du nur die Bestätigungskarte oder das Agent-Transkript beobachtest, kann dir der gefährliche Teil entgehen.
Der hier beschriebene Test beantwortet eine eng gefasste Frage: Hat das Gateway Aufrufe verworfen, die während der Sperre des Tresors eingegangen sind, oder hat das Öffnen dazu geführt, dass einer dieser alten Aufrufe ausgeführt wurde? Der Test verwendet einen kontrollierten HTTP-Empfänger, zwei eindeutige Request-IDs und Nachweise von beiden Seiten des Gateways. Führe ihn durch, bevor du einem autonomen Agenten einen Endpunkt anvertraust, der Geld, Infrastruktur, Quellcode oder Kundendaten verändern kann.
Die Tresorsperre muss eine Aktion abbrechen, nicht verschieben
Die erwartete Regel ist einfach: Wenn der Tresor gesperrt ist, verweigert das Gateway jede Aktion, die ihn benötigt. Das Öffnen ändert die Antwort für einen späteren Aufruf. Es ändert nicht die Antwort für einen Aufruf, der bereits eingegangen ist.
Diese Unterscheidung ist wichtig, weil eine Anfrage einen Lebenszyklus hat. Ein Prozess schreibt Bytes nach stdin. Ein MCP-Shim analysiert JSON-RPC. Das Gateway identifiziert eine konfigurierte Aktion, fragt ab, ob sie ein Geheimnis verwenden darf, fügt bei entsprechender Berechtigung Zugangsdaten ein, öffnet eine ausgehende Verbindung und gibt ein Ergebnis zurück. Ein Fehler kann die Anfrage an mehreren Stellen dieses Wegs zurückhalten.
Ein sicheres Design behandelt die Entscheidung bei gesperrtem Tresor für diesen Aufruf als endgültig. Das Gateway darf die Ablehnung protokollieren, aber es darf keine ausführbare Closure, keinen serialisierten Anfrage-Body, keinen ausgehenden Auftrag und kein Wiederholungstoken behalten, die später mit einem neu geöffneten Tresor ausgeführt werden könnten.
Oft werden zwei unterschiedliche Verhaltensweisen vermischt:
- Ein neuer Versuch ist ein neuer Aufruf, den der Agent sendet, nachdem er einen Fehler oder eine Zustandsänderung beobachtet hat.
- Ein Replay ist die Ausführung des ursprünglichen Aufrufs, den das Gateway oder einer seiner Helfer während der verweigerten Zugriffszeit aufbewahrt hat.
Ein neuer Versuch kann legitim sein, braucht aber weiterhin die normale Autorisierung. Ein Replay überschreitet eine Sicherheitsgrenze ohne eine neue Entscheidung. Wenn du beides verwechselst, kann der Test fälschlich erfolgreich wirken: Du öffnest den Tresor, siehst eine Anfrage am Ziel ankommen und nimmst an, sie stamme von einem bewussten neuen Versuch.
Das Model Context Protocol nimmt dir dieses Designproblem nicht ab. Sein stdio-Transport verwendet zeilengetrennte JSON-RPC-Nachrichten zwischen einem vom Client gestarteten Serverprozess und dem Client. JSON-RPC-Anfragen mit einer id erhalten eine zugeordnete Antwort, Benachrichtigungen dagegen nicht. Diese Protokollregeln liefern eine nützliche Zuordnung, legen aber nicht fest, ob ein Gateway eine verweigerte Aktion für eine spätere Ausführung aufbewahren darf. Diese Entscheidung muss dein Gateway ausdrücklich treffen.
Der Eingangszeitpunkt liegt vor dem ausgehenden HTTP-Aufruf
Eine Anfrage geht ein, sobald das Gateway genügend Informationen hat, um über ihre Ausführung zu entscheiden, nicht erst, wenn der Zielserver Datenverkehr sieht. Ist der Tresor zu diesem Zeitpunkt gesperrt, sollte die Ablehnung vor dem Einfügen der Zugangsdaten erfolgen und bevor das Gateway die Arbeit an etwas übergibt, das die Entscheidung überdauern kann.
Hier werden Tests oft schlampig. Jemand sperrt den Tresor, weist den Agenten an, eine API aufzurufen, wartet auf einen Fehler, öffnet den Tresor wieder und prüft, ob nicht sofort eine Anfrage erscheint. Dieser Test übersieht verzögerte Wiederholungen, blockierte Worker, Verbindungspools und Wiederholungstimer des Clients. Er übersieht auch die Möglichkeit, dass der Aufruf das Ziel erreicht hat, bevor die Oberfläche den Fehler angezeigt hat.
Verwende drei Zeitpunkte, die an unabhängigen Stellen aufgezeichnet werden:
T_lock: der Zeitpunkt, an dem bestätigt wurde, dass der Tresor gesperrt ist.T_attempt: der Zeitpunkt, an dem der Agent die alte Request-ID übermittelt hat.T_unlock: der Zeitpunkt, an dem der Tresor wieder geöffnet wurde.
Beobachte den Empfänger auch nach T_unlock weiter. Die Wartezeit muss jedes Wiederholungs- und Timeout-Intervall überschreiten, das du im Client, Gateway und in jedem Vermittler konfiguriert hast. Wenn du diese Werte nicht kennst, wähle keine beruhigend kurze Verzögerung. Ermittle sie zuerst oder verwende einen Empfänger, der lange genug verfügbar bleibt, um eine verzögerte Zustellung sichtbar zu machen.
Eine nützliche Abnahmebedingung ist genauer als «Die Anfrage bei gesperrtem Tresor ist fehlgeschlagen»:
Für die Request-ID
locked-...protokolliert der kontrollierte Empfänger vor und nachT_unlockgenau null Ausführungen. Für die Request-IDfresh-..., die erst nachT_unlockgesendet wurde, protokolliert der Empfänger genau eine Ausführung.
Diese Aussage erfasst beide Seiten des Fehlers. Sie erkennt einen alten Aufruf, der später ausgeführt wird, und beweist, dass der Test nicht einfach deshalb fehlgeschlagen ist, weil der Empfänger oder die Aktionskonfiguration defekt war.
Verwende für beide Aufrufe nicht denselben Payload. Wenn beide deploy=true enthalten, kannst du nicht feststellen, welcher angekommen ist. Setze die Request-ID in den URL-Pfad, ein harmloses JSON-Feld und einen Header, sofern deine konfigurierte Aktion das zulässt. Diese Redundanz ist hilfreich, weil sie versehentliche Änderungen oder Caching sichtbar macht.
In Warteschlangen und Wiederholungen verstecken sich Replay-Fehler
Die gefährlichsten Replay-Fehler sind nicht spektakulär. Sie entstehen meist durch gewöhnlichen Zuverlässigkeitscode, den jemand geschrieben hat, weil er annahm, eine Autorisierungsverweigerung verhalte sich wie ein vorübergehender Netzwerkfehler.
Betrachte eine typische fehlerhafte Abfolge. Der Agent sendet einen MCP-Tool-Aufruf, während der Tresor gesperrt ist. Der Shim akzeptiert die Nachricht und erstellt ein internes Arbeitselement. Die Tresorprüfung liefert einen Fehler wegen der Sperre, aber der Worker stuft ihn als wiederholbar ein, weil das Ziel nie erreicht wurde. Der Aufrufer trennt die Verbindung oder die Sitzung endet. Später öffnet der Benutzer den Tresor. Der Worker wird aktiv, findet gültige Zugangsdaten und sendet die ursprüngliche HTTP-Anfrage.
Die Oberfläche kann während der gesamten Abfolge korrekt aussehen. Der ursprüngliche Agent erhielt einen Fehler. Der Benutzer sah, dass der Tresor gesperrt war. Das Ziel erhielt gültige Zugangsdaten erst nach dem Öffnen. Trotzdem hat das Gateway eine Aktion über eine Grenze hinweg getragen, an der sie hätte enden müssen.
Nach diesen Mustern solltest du suchen:
- Ein allgemeiner Wiederholungs-Wrapper fängt jeden Fehler außer ungültigen Eingaben ab.
- Eine dauerhafte Aufgabenwarteschlange speichert die Absicht vor der Tresorentscheidung.
- Ein Future oder Promise wartet auf das Öffnen, statt einen endgültigen Fehler zurückzugeben.
- Ein Wiederverbindungspfad sendet eine Anfrage aus dem Speicher erneut, nachdem der Clientprozess beendet wurde.
- Ein Hintergrundhelfer verwaltet den Wiederholungszustand unabhängig vom Tresor-Gate.
Die verbreitete Empfehlung, «jede fehlgeschlagene Netzwerkoperation zu wiederholen», ist an dieser Grenze falsch. Sie ist verbreitet, weil Fehler beim Netzwerktransport häufig sind und Wiederholungen die Zustellung oft verbessern. Ein gesperrter Tresor ist kein Transportfehler. Er ist die ausdrückliche Weigerung, eine Berechtigung zu verwenden. Behandle ihn für diesen Aufruf als endgültig.
Das gilt auch für Abbrüche. Die Trennung eines Clients bedeutet nicht zwangsläufig, dass eine HTTP- oder SSE-Anfrage abgebrochen wurde. Die Spezifikation des MCP-Transports sagt, dass eine Verbindung jederzeit getrennt werden kann und dies nicht selbst als Abbruch interpretiert werden sollte. Wenn der Client abbrechen möchte, ist eine ausdrückliche Abbruchbenachrichtigung vorgesehen. Für lang laufende Aufgaben ist dieses Verhalten sinnvoll, es macht den lokalen Gateway-Zustand aber umso wichtiger: Ein verweigerter Aufruf darf nicht ausführbar bleiben, nur weil der Transportzustand unklar geworden ist.
Baue einen Empfänger, der jede Ausführung sichtbar macht
Ein kontrollierter Empfänger liefert bessere Belege als ein Agent-Chat-Transkript. Er zeigt, ob ein ausgehender Aufruf tatsächlich angekommen ist, welche ID er trug und wann er eingetroffen ist. Halte ihn von der Produktion getrennt und beschränke seine einzige Nebenwirkung auf ein lokales Protokoll, das nur angehängt wird.
Führe diesen kleinen Python-Empfänger auf einem Rechner und Port aus, die dein Gateway erreichen kann. Er akzeptiert POST-Anfragen, schreibt für jede Ankunft eine JSON-Zeile und gibt eine harmlose Erfolgsantwort zurück. Er protokolliert absichtlich nur eine kurze Markierung aus dem Authorization-Header, nicht die Zugangsdaten selbst.
# receiver.py
from http.server import BaseHTTPRequestHandler, HTTPServer
from datetime import datetime, timezone
import hashlib
import json
LOG = "receiver-events.jsonl"
class Receiver(BaseHTTPRequestHandler):
def do_POST(self):
length = int(self.headers.get("Content-Length", "0"))
body = self.rfile.read(length).decode("utf-8", errors="replace")
auth = self.headers.get("Authorization", "")
auth_marker = hashlib.sha256(auth.encode()).hexdigest()[:12] if auth else None
event = {
"received_at": datetime.now(timezone.utc).isoformat(),
"method": self.command,
"path": self.path,
"request_id": self.headers.get("X-Replay-Test-Id"),
"auth_marker": auth_marker,
"body": body,
}
with open(LOG, "a", encoding="utf-8") as log:
log.write(json.dumps(event) + "\n")
self.send_response(200)
self.send_header("Content-Type", "application/json")
self.end_headers()
self.wfile.write(b'{"received":true}')
def log_message(self, format, *args):
return
HTTPServer(("127.0.0.1", 8787), Receiver).serve_forever()
Starte ihn mit:
python3 receiver.py
Die Ausgabedatei sieht ungefähr so aus:
{"received_at":"2026-07-22T16:42:12.103841+00:00","method":"POST","path":"/replay-test/fresh-8f1c","request_id":"fresh-8f1c","auth_marker":"a4d7e02c1b9f","body":"{\"kind\":\"fresh\"}"}
Lege kein echtes Geheimnis in den Anfrage-Body. Konfiguriere die Testaktion mit einer eigenen Testberechtigung mit niedrigen Rechten im Tresor und lass das Gateway sie über den normalen HTTP-Kanal einfügen. Der Fingerabdruck des Headers beweist nur, dass irgendein Autorisierungswert angekommen ist. Er schreibt den Wert nicht in eine Datei, die den Test überdauern könnte.
Sende vor dem gesperrten Test eine normale Anfrage, während der Tresor geöffnet ist. Bestätige, dass der Empfänger sie protokolliert und der konfigurierte Endpunktpfad stimmt. Lösche anschließend receiver-events.jsonl oder verschiebe die Datei. Ein leeres Protokoll verhindert, dass eine frühere Einrichtungsanfrage dein Ergebnis verfälscht.
Führe den Test mit zwei bewusst unterschiedlichen Aufrufen aus
Der Test braucht eine alte ID, die bei gesperrtem Tresor versucht wird, und eine neue ID, die erst nach dem Öffnen erzeugt wird. Verwende zufällig wirkende Bezeichnungen und notiere sie vor dem Lauf. Verständliche Bezeichnungen erleichtern den Abgleich bei der Prüfung.
Zum Beispiel:
old request ID: locked-3d4a
fresh request ID: fresh-91ce
Bereite eine Agent-Anweisung oder eine MCP-Client-Anfrage vor, die deine konfigurierte HTTP-Aktion mit diesen Informationen aufruft:
{
"path": "/replay-test/locked-3d4a",
"headers": {
"X-Replay-Test-Id": "locked-3d4a"
},
"body": {
"kind": "locked-period-attempt",
"request_id": "locked-3d4a"
}
}
Der genaue Toolname und die Form der Argumente hängen von der von dir konfigurierten Aktionsschnittstelle ab. Fälsche keinen erfolgreichen Test, indem du den Empfänger direkt mit einem Shell-Befehl aufrufst. Die Anfrage muss denselben Weg durch Agent, MCP-Shim, Gateway, Tresor und HTTP-Aktion nehmen, dem du später vertrauen willst.
Führe die Abfolge jetzt ohne Improvisation aus:
- Bestätige, dass das Empfängerprotokoll leer und der Tresor gesperrt ist.
- Starte einen neuen Agent-Prozess und übermittle anschließend den Aufruf
locked-3d4a. - Erfasse den Fehler auf Agentenseite und den Zeitpunkt. Sende die Anfrage nicht erneut.
- Lass den Agent-Prozess für eine kurze Beobachtungszeit laufen und beende ihn anschließend. So erkennst du sowohl sofortige als auch an den Prozess gebundene Wiederholungen.
- Öffne den Tresor und warte die vollständige Beobachtungszeit ab. Prüfe das Empfängerprotokoll wiederholt.
locked-3d4adarf nicht erscheinen. - Starte erst nach dieser Wartezeit einen neuen Agent-Prozess und übermittle
fresh-91ce. Der Empfänger sollte diese ID genau einmal protokollieren.
Halte den alten und den neuen Aufruf in getrennten Agent-Prozessen. Eine sitzungsweite Bestätigung oder ein interner Client-Cache kann das Ergebnis sonst verfälschen. Du testest, ob eine alte Aktion die Sperrgrenze überschreiten kann, nicht ob sich ein einzelner Prozess an einen Autorisierungszustand erinnert.
Wenn der gesperrte Aufruf nach dem Öffnen eine Bestätigungsaufforderung erzeugt, ohne dass der Agent einen neuen Aufruf sendet, brich ab. Das ist ein Hinweis auf eine gespeicherte Absicht. Wenn der Empfänger locked-3d4a irgendwann nach dem Öffnen erhält, gilt der Sicherheitstest als fehlgeschlagen, selbst wenn der Server 200 zurückgegeben hat, ohne Daten zu verändern.
Prüfe beide Journale, aber ersetze den Empfänger nicht durch Protokolle
Ein Gateway-Journal hilft dir nachzuvollziehen, was das Gateway nach eigener Einschätzung getan hat. Der Empfänger beweist, was außerhalb des Gateways passiert ist. Du brauchst beides, weil jede Quelle allein falsche Sicherheit vermitteln kann.
Sallyport führt ein Sitzungsjournal für Agent-Läufe und ein Aktivitätsjournal für einzelne Aufrufe. Beide werden aus einem gemeinsamen verschlüsselten, hashverketteten Auditprotokoll erzeugt. Die Offline-Prüfung ist über sp audit verify verfügbar und benötigt den Tresorschlüssel nicht, um die Kette zu validieren. Führe den Befehl nach dem Test aus und bewahre das Ergebnis zusammen mit dem Empfängerprotokoll und dem Agent-Transkript auf.
Nutze die Aufzeichnungen, um konkrete Fragen zu beantworten:
- Hat der alte Aufruf einen Aktivitätseintrag erzeugt, und zeigt dieser eine verweigerte Ausführung?
- Welcher Agent-Prozess und welche Codesignatur wurden in der Sitzung aufgezeichnet?
- Gibt es später eine Aktivität mit der alten Request-ID, dem Endpunktpfad oder einem passenden Zeitfenster?
- Wurde für den neuen Aufruf nach dem Öffnen eine neue Sitzung gestartet?
- Ist die Auditprüfung für die gesammelten Aufzeichnungen erfolgreich?
Nimm nicht an, dass ein Protokolleintrag mit dem Text «abgelehnt» beweist, dass die Anfrage den Rechner nie verlassen hat. Ein Protokoll hält die Einschätzung des Gateways zu seiner eigenen Entscheidung fest. Der kontrollierte Empfänger liefert die unabhängige Prüfung. Umgekehrt kann ein fehlender Eintrag bedeuten, dass deine Suchbegriffe falsch waren, Zeitstempel voneinander abwichen oder der Test nicht die vorgesehene Aktion verwendet hat. Deshalb ist die erfolgreiche neue Anfrage wichtig.
Für einen wiederholbaren Teamtest speicherst du vier Artefakte unter einer gemeinsamen Testlauf-ID: das Agent-Transkript, die JSONL-Datei des Empfängers, den Journal-Export oder Screenshots zur Identifizierung der Aufrufe und das Ergebnis von sp audit verify. Vermeide geheime Werte in allen diesen Dateien.
Benachrichtigungen, Batches und erneute Verbindungen brauchen eigene Fälle
Ein erfolgreicher Test mit einer Anfrage deckt nicht jede Nachrichtenform ab, die ein Agent-Client senden kann. Anfragen mit IDs sind am einfachsten zu testen, weil JSON-RPC verlangt, dass die Antwort dieselbe ID trägt. Benachrichtigungen haben keine ID und erhalten keine Antwort. Damit fehlt der normale Nachweis, dass das Gateway sie abgelehnt hat. JSON-RPC sagt ausdrücklich, dass ein Server nicht auf Benachrichtigungen antworten darf.
Gib einem Pfad, der Benachrichtigungen unterstützt, eine Markierung wie notification-77b2 im ausgehenden Payload, die der Empfänger protokolliert. Sperre den Tresor, sorge dafür, dass die Benachrichtigung einmal gesendet wird, öffne den Tresor und prüfe, dass die Markierung nie eintrifft. Leite Sicherheit nicht aus dem Schweigen der Client-Oberfläche ab, denn Schweigen ist hier das erwartete Protokollverhalten.
Batch-Eingaben verdienen einen eigenen Test, wenn dein Client oder Shim sie akzeptiert. Setze zwei harmlose Aufrufe in den Batch: einen während der Sperre und einen, der erst nach dem Öffnen in einem separaten Batch gesendet wird. Lege alte und neue Aufrufe nicht in denselben Batch, weil ein Gateway, das einen Batch teilweise vor einer Zustandsänderung verarbeitet, ein nicht interpretierbares Ergebnis erzeugen kann.
Bei Tests zu erneuten Verbindungen solltest du jeweils nur eine Sache ändern. Führe diese Fälle in getrennten Läufen aus:
- Lass den Agent-Prozess bis zum Öffnen des Tresors laufen.
- Beende den Agent-Prozess vor dem Öffnen.
- Starte vor dem Öffnen nur den MCP-Client oder den Shim neu.
- Trenne den Netzwerkpfad nach dem gesperrten Fehler und verbinde ihn nach dem Öffnen wieder.
Die Erwartung bleibt gleich. Die alte Empfänger-ID darf nie erscheinen. Wenn eine alte ID erst nach einer erneuten Verbindung auftaucht, hast du einen Replay-Pfad gefunden, der an die Transportwiederherstellung und nicht an die Tresor-Oberfläche gebunden ist.
Eine sitzungsbezogene Autorisierung kann eine gespeicherte Aktion nicht reparieren
Eine Autorisierung pro Sitzung und eine Bestätigung pro Aufruf entscheiden, ob eine aktuelle Aktion fortgesetzt werden darf. Sie machen es nicht sicher, eine Aktion aufzubewahren, die bei gesperrtem Tresor abgelehnt wurde.
Die Reihenfolge ist entscheidend. Das Tresor-Gate ist absolut: Solange es gesperrt ist, wird jede Aktion abgelehnt. Erst nach dem Öffnen kann das Gateway den Prozess hinter einer Sitzungsautorisierung berücksichtigen oder eine Bestätigung pro Aufruf für eine konfigurierte Zugangsdaten anfordern. Ein umgekehrtes Denkmodell führt dazu, dass Teams fragen, ob eine frühere Bestätigungskarte eine verzögerte Aktion autorisieren sollte. Das darf sie nicht, weil der gesperrte Aufruf nicht länger als ausführbare Arbeit existieren sollte.
Teste die Grenzen unabhängig voneinander. Beweise zuerst, dass ein Aufruf aus der Sperrzeit nach dem Öffnen nie ausgeführt wird. Teste danach bei geöffnetem Tresor, ob ein neuer Agent-Prozess das erwartete Verhalten der Sitzungsautorisierung zeigt. Wenn eine Zugangsdaten-Option die Bestätigung pro Aufruf aktiviert hat, prüfe schließlich, ob jede neue Verwendung erneut fragt. Wenn du alle drei Fälle in einem langen Lauf kombinierst, lassen sich Fehler nur schwer zuordnen.
Es gibt außerdem eine subtile Frage zur Prozessidentität. Eine Sitzungsbestätigung gehört zu einem bestimmten Lauf eines Agent-Prozesses, nicht zu der Vorstellung «derselbe Assistent». Wenn du einen Prozess neu startest, behandle ihn als neu, bis das Gateway ihn nach seinen eigenen Regeln identifiziert und autorisiert. Lass ein Testskript diese Tatsache nicht verbergen, indem es einen Prozess mit einer alten Verbindung wiederverwendet.
Mache das Ergebnis zur Freigabebedingung
Führe diesen Test aus, wann immer du das Gateway-Dispatching, den Lebenszyklus des Tresors, den MCP-Shim, das Wiederholungsverhalten, die HTTP-Client-Konfiguration oder den Helfer für SSH-Aktionen änderst. Ein Replay-Fehler entsteht oft bei einer Zuverlässigkeitsänderung, weil der Code in der Prüfung harmlos wirkt: eine Warteschlange, ein Handler für erneute Verbindungen oder eine weit gefasste catch-Klausel.
Eine Freigabe muss scheitern, wenn eine dieser Aussagen falsch ist:
- Der kontrollierte Empfänger hat für jede bei gesperrtem Tresor übermittelte ID null Einträge, auch nach dem Öffnen.
- Eine neue ID nach dem Öffnen erreicht den Empfänger genau einmal über dieselbe konfigurierte Aktion.
- Ein neu gestarteter Client oder Agent kann nicht dazu führen, dass die alte ID erscheint.
- Die Journale identifizieren die erwarteten verweigerten und erlaubten Ereignisse ohne ungeklärte Duplikate.
- Die Auditkette lässt sich für die aufbewahrten Nachweise validieren.
Schreibe den Negativfall nach Möglichkeit in einen automatisierten Integrationstest. Die Testumgebung sollte den Tresor sperren, den alten Aufruf senden, den Tresor öffnen, ein begrenztes Wiederholungsfenster abwarten und bestätigen, dass die alte ID im Empfänger fehlt. Danach sollte sie den neuen Aufruf senden und genau eine Ankunft bestätigen. Halte den Empfänger lokal und kurzlebig, damit der Test keine Berechtigung über seine eigene Protokolldatei hinaus besitzt.
Das schlechte Ergebnis lässt sich einfach beschreiben: Jemand öffnet den Tresor, um die nächste Aktion zu autorisieren, und stattdessen wird eine frühere Aktion ausgeführt. Akzeptiere kein Gateway, das lediglich den richtigen Fehler bei gesperrtem Tresor anzeigt. Lass es mit einem Beobachter außerhalb des Gateways beweisen, dass es die alte Anfrage vergessen hat.
FAQ
Wie beweise ich, dass eine Anfrage bei gesperrtem Tresor verworfen und nicht verzögert wurde?
Eine Ablehnung zeigt nur, dass das Gateway einen Aufruf zu einem bestimmten Zeitpunkt verweigert hat. Ein Test auf Verwerfen geht weiter: Öffne den Tresor, warte länger als jedes relevante Wiederholungsfenster und belege, dass die alte Request-ID nie ein kontrolliertes Ziel erreicht hat. Sende anschließend eine neue Anfrage mit einer anderen ID, um zu zeigen, dass der Testpfad weiterhin funktioniert.
Kann ein Agent nach dem Öffnen des Tresors einfach einen neuen Versuch starten?
Nein. Das Gateway kann einen Agenten nicht daran hindern, eine neue Anfrage zu stellen, nachdem dieser erfahren hat, dass der Tresor geöffnet ist. Dein Test muss eine neue Anfrage nach dem Öffnen von der alten Anfrage vor dem Öffnen unterscheiden. Verwende dafür unterschiedliche Request-IDs und einen Empfänger, der sie getrennt protokolliert.
Reicht ein Timeout als Beleg dafür, dass keine Aktion ausgeführt wurde?
Ein Timeout ist nicht eindeutig. Der Client kann es wiederholen, das Gateway kann die Anfrage noch verarbeiten oder das Ziel kann sie bereits erhalten haben, bevor der Timeout angezeigt wurde. Behandle einen Timeout als fehlgeschlagenen Test, bis das Empfängerprotokoll und die Gateway-Aufzeichnungen klären, was passiert ist.
Wie teste ich JSON-RPC-Benachrichtigungen bei gesperrtem Tresor?
Benachrichtigungen verdienen besondere Aufmerksamkeit, weil JSON-RPC dem Aufrufer keine Antwort liefert, die sich mit dem Ergebnis verknüpfen lässt. Verwende für eine sicherheitsrelevante Aktion im Test eine Anfrage mit ID oder ergänze eine unabhängige Markierung auf Empfängerseite, durch die eine Ausführung sichtbar wird.
Wird eine alte Anfrage dadurch sicher, dass ich den Agenten neu starte?
Ein neuer Agent-Prozess muss die Sitzungsautorisierung erneut erfüllen, sofern diese Kontrolle aktiviert ist. Das allein beweist jedoch nicht, dass Aufrufe aus der Zeit des gesperrten Tresors verworfen wurden. Teste den Neustart des Prozesses und das Öffnen des Tresors als getrennte Zustandsänderungen. Prüfe anschließend, ob eine von ihnen eine alte Absicht freigibt.
Lösen Idempotenzschlüssel das Replay-Problem nach dem Öffnen des Tresors?
Nur wenn der Zielendpunkt doppelte Zustellungen unschädlich macht und den Idempotenzschlüssel protokolliert. Ein Idempotenzschlüssel verhindert wiederholte Auswirkungen am Ziel. Er berechtigt das Gateway jedoch nicht dazu, eine bei gesperrtem Tresor eingegangene Aktion aufzubewahren.
Kann ich diesen Test gegen eine Produktions-API ausführen?
Verwende einen Empfänger, den du kontrollierst, einen eigenen Testpfad und Daten ohne operativen Wert. Leite diesen Test nicht an produktive Abrechnungs-, Deployment-, DNS- oder Quellcodeverwaltungs-Endpunkte weiter, nur weil sie bereits vorhanden sind.
Was ist der schnellste manuelle Replay-Test?
Prüfe zuerst den kontrollierten Empfänger auf die alte ID. Sende danach nach dem Öffnen eine neue ID und bestätige, dass sie genau einmal eintrifft. Wenn die alte ID nach dem Öffnen auftaucht, behandle das Ergebnis als Sicherheitsfehler, selbst wenn am Ziel nichts verändert wurde.
Welche Auditnachweise sollte ich für diesen Test aufbewahren?
Du brauchst eine Aufzeichnung, die eine Ablehnung oder den gesperrten Zustand, die Identität der Agent-Sitzung und den Korrelationswert der Anfrage festhält. Eine manipulationssichere Auditspur hilft zu belegen, dass diese Aufzeichnungen später nicht unbemerkt geändert wurden. Sie ersetzt jedoch nicht den Nachweis auf Empfängerseite.
Was muss ein Tresor-Gate garantieren?
Eine saubere Schnittstelle weist den Aufruf zurück, bevor er in eine dauerhafte Arbeitswarteschlange oder einen Wiederholungsmechanismus gelangt. Das Öffnen des Tresors ändert die Berechtigung für Aufrufe, die danach eintreffen. Frühere abgelehnte Aufrufe dürfen dadurch nicht zu ausführbaren Aufgaben werden.