8 Min. Lesezeit

Agentenaktivitäten für eine zuverlässige Vorfallsrekonstruktion ordnen

Die Reihenfolge von Agentenaktivitäten braucht mehr als Zeitstempel. Bewahren Sie Sitzungsidentität, Lebenszyklusereignisse, dauerhafte Sequenzen und Ergebniszeiten für Untersuchungen auf.

Agentenaktivitäten für eine zuverlässige Vorfallsrekonstruktion ordnen

Die Reihenfolge von Agentenaktivitäten entscheidet darüber, ob ein Vorfallsbericht erklärt, was passiert ist, oder lediglich einen Stapel Zeitstempel anzeigt. Wenn ein autonomer Programmieragent APIs aufrufen und SSH-Sitzungen öffnen kann, müssen Ermittler feststellen, welcher Prozess gehandelt hat, was er versucht hat, was abgeschlossen wurde und welches Ergebnis der Agent erhielt, bevor er seine nächste Aktion auswählte.

Eine nach Zeit sortierte Liste reicht nicht aus. Uhren gehen vor oder nach, Anfragen überschneiden sich, Antworten treffen in anderer Reihenfolge ein, und eine Zeitüberschreitung kann eine remote erfolgreiche Aktion verbergen. Erstellen Sie Datensätze, die Sitzungskontext, eine dauerhafte lokale Reihenfolge und getrennte Zeitstempel für die einzelnen Lebenszyklusphasen bewahren. Sonst wird der erste ernste Vorfall Ihren Audit-Trail in eine Diskussion über Vermutungen verwandeln.

Zeit allein kann die Reihenfolge von Aktionen nicht belegen

Ein Zeitstempel sagt, wann eine Uhr ein Ereignis beobachtet hat. Er beweist nicht, dass dieses Ereignis vor jedem anderen Ereignis mit einem späteren Zeitstempel stattgefunden hat. Das klingt akademisch, bis zwei Aufrufe einen Agenten fast gleichzeitig verlassen, ein entfernter Dienst stockt und der zweite Aufruf zuerst zurückkommt. Wenn Sie nach completed_at sortieren, erhalten Sie die Reihenfolge der Antworten, nicht die Reihenfolge der Entscheidungen des Agenten.

Jeder Aufruf hat mehrere wichtige Zeitpunkte. Der Agent entscheidet, ein Tool aufzurufen. Das Gateway nimmt die Anfrage an. Es autorisiert sie. Es übergibt die Arbeit an einen HTTP-Dienst oder SSH-Helfer. Die Gegenseite kann sie annehmen. Eine Antwort trifft ein. Das Gateway gibt dieses Ergebnis an den Agenten zurück. Wenn Sie all das als ein Ereignis behandeln, entfernen Sie die Belege, die zur Erklärung eines Fehlers nötig sind.

Führen Sie innerhalb jeder Sitzung eine lokale, monoton steigende call_sequence. Vergeben Sie sie, sobald das Gateway einen Aufruf annimmt, bevor Netzwerkaktivitäten beginnen. Diese Zahl beantwortet eine begrenzte, nützliche Frage: «In welcher Reihenfolge hat dieses Gateway Aufrufe von diesem Agentenprozess angenommen?» Sie behauptet nicht, die Reihenfolge der Ausführung auf der Gegenseite abzubilden. Ein ehrlicher Geltungsbereich ist besser als eine weitreichende Behauptung, die Sie nicht verteidigen können.

Verwenden Sie eine zweite dauerhafte Sequenz für das Audit-Journal selbst. Aufrufe verschiedener Sitzungen können sich überschneiden, und Autorisierungen, Widerrufe, Tresorsperren und Prüfereignisse müssen im selben Beweisstrom liegen. Eine Journal-Sequenz zeigt einem Ermittler die Schreibreihenfolge des Recorders. Eine Sitzungs-Aufrufsequenz zeigt die Reihenfolge der Absichten innerhalb eines Agentenlaufs. Kein Feld ersetzt das andere.

Verwenden Sie die Genauigkeit von Zeitstempeln nicht als Ersatz für Sequenznummern. Mehr Dezimalstellen zeichnen nur eine genauere Ablesung einer Uhr auf. Sie lösen weder eine Uhrkorrektur noch eine globale Reihenfolge zwischen parallel schreibenden Prozessen.

RFC 3339 definiert eine nützliche, interoperable Darstellung für Uhrzeitstempel mit explizitem UTC-Offset. Verwenden Sie für Exporte und die menschliche Prüfung die UTC-Form, etwa 2025-03-08T21:14:03.482Z. RFC 3339 verspricht keine kausale Reihenfolge. Dafür ist Ihr Recorder zuständig, und er braucht Sequenzfelder sowie klare Ereignisgrenzen.

Eine Sitzung identifiziert den handelnden Prozess, keine vage Aufgabe

Eine Sitzung sollte einen geordneten Lauf an den konkreten Agentenprozess binden, der die Berechtigung zum Handeln erhalten hat. Sie sollte beginnen, wenn dieser Prozess eine Verbindung herstellt, und enden, wenn er beendet wird, seinen Kanal verliert oder ein Operator die Berechtigung widerruft. Machen Sie aus einer Sitzung nicht «Arbeit an Ticket 184» oder «die Bereitstellung am Nachmittag». Solche Bezeichnungen erleichtern die Suche, definieren aber keine Ausführungsgrenze.

Der Sitzungsdatensatz muss genug Identität enthalten, um tatsächliche Ermittlungsfragen zu beantworten: Welche ausführbare Datei hat die Verbindung hergestellt, wer hat sie signiert, welcher lokale Benutzer hat sie gestartet, welcher Transport wurde verwendet und wann begann und endete die Berechtigung? Erfassen Sie Kennungen, die das Betriebssystem oder die Verbindung belegen können. Lassen Sie den Agenten seine Identitätsangaben nicht selbst in die maßgeblichen Felder schreiben.

Diese Trennung ist wichtig, wenn jemand eine Toolkonfiguration in einen anderen Prozess kopiert. Die Aktionsanfrage kann angeben, dass sie auf einem bestimmten Repository arbeiten soll. Das Gateway sollte die beobachtete Prozessidentität aufzeichnen. Bei einem Vorfall wiegt die zweite Aussage schwerer.

Ein praktischer Sitzungsdatensatz könnte so aussehen:

{
  "event_id": "01JNRQ2Q9Y9J0R3E5P8F7K2X4M",
  "journal_sequence": 8124,
  "event_type": "session.opened",
  "occurred_at": "2025-03-08T21:14:02.901Z",
  "session_id": "sess_7f31c4",
  "process": {
    "pid": 48102,
    "code_signing_authority": "observed signing authority",
    "local_user": "developer account"
  }
}

Der Agent sollte ein undurchsichtiges Sitzungshandle erhalten, nicht die Berechtigung, die Sitzungskennung zu wählen oder ihre Metadaten zu ändern. Er kann weiterhin sein eigenes Lauf-Label, den Repository-Pfad oder eine Aufgabenreferenz in einem getrennten Feld für den deklarierten Kontext angeben. Kennzeichnen Sie diese Werte als vom Agenten geliefert. Das Label kann die Absicht erklären, darf aber niemals beobachtete Prozessfakten überschreiben.

Eine sitzungsbezogene Autorisierung bringt einen weiteren Vorteil für Ermittlungen. Sie dokumentiert eine menschliche Entscheidung, die an einen begrenzten Prozesslauf gebunden ist. Wenn dieser Lauf später einen schädlichen Aufruf ausführt, sehen Prüfer das vorausgehende Berechtigungsereignis und das Sitzungsende oder den Widerruf, der ihn beendet hat. Eine Freigabe, die stillschweigend für spätere Prozesse gilt, erzeugt eine Lücke, die keine noch so detaillierte Aufrufprotokollierung schließen kann.

Ein Aufruf braucht einen Lebenszyklus, nicht nur eine Abschlusszeile

Ein brauchbarer Aufrufdatensatz bewahrt den Lebenszyklus eines Versuchs. Er fasst eine versuchte Anfrage, eine Netzwerkweiterleitung, ein entferntes Ergebnis und das für den Agenten sichtbare Ergebnis nicht in einem vagen Feld «Erfolg» oder «Fehler» zusammen.

Beginnen Sie mit einer unveränderlichen call_id und der nächsten call_sequence der Sitzung. Zeichnen Sie ein akzeptiertes Ereignis auf, bevor Sie die Außenwelt kontaktieren. Wenn eine Richtlinie oder eine Freigabe die Anfrage blockiert, sind das akzeptierte Ereignis und das Ablehnungsereignis weiterhin wichtig. Sie zeigen die Absicht und das Kontrollverhalten, ohne vorzutäuschen, dass die externe Aktion stattgefunden hat.

Für eine erlaubte HTTP-Aktion sollten Sie diese Ereignisgrenzen getrennt erfassen:

  1. call.accepted zeichnet die geordnete Anfrage am Gateway auf.
  2. call.authorized oder call.denied zeichnet die Kontrollentscheidung auf.
  3. call.dispatched zeichnet auf, dass das Gateway die Anfrage an seinen Netzwerkclient übergeben hat.
  4. call.result_received zeichnet das Transportergebnis oder die entfernte Antwort auf.
  5. call.result_returned zeichnet das an den Agenten zurückgegebene Ergebnis auf.

Die Namen können abweichen, die Bedeutung nicht. Ein empfangenes Ergebnis ist nicht immer ein zurückgegebenes Ergebnis. Das Gateway kann eine Antwort redigieren, fehlerhafte Daten ablehnen, die Verbindung zum Agenten verlieren oder bei der Vorbereitung des Ergebnisses intern scheitern. Ermittler müssen diese Lücke sehen können.

Bewahren Sie request_started_at, dispatched_at, result_received_at und result_returned_at auf, sobald diese Zeitpunkte eintreten. Verwenden Sie null, wenn ein Zeitpunkt nicht eingetreten ist. Erfinden Sie keine Endzeit, wenn ein Prozess abgestürzt ist. Zeichnen Sie später ein Wiederherstellungsereignis auf, das besagt, dass der Recorder einen unvollständigen Aufruf gefunden hat.

Dieses Beispiel zeigt die Form einer abgeschlossenen Anfrage, ohne ein Bearer-Token oder den vollständigen Antworttext offenzulegen:

{
  "event_id": "01JNRQ3M8W7P0Q4R6S9T1V2X3Y",
  "journal_sequence": 8131,
  "event_type": "call.result_received",
  "occurred_at": "2025-03-08T21:14:05.841Z",
  "session_id": "sess_7f31c4",
  "call_id": "call_00017",
  "call_sequence": 17,
  "channel": "http",
  "target": "api.internal.example/v1/releases",
  "method": "POST",
  "dispatch_event_id": "01JNRQ3G2A...",
  "outcome": {
    "transport": "response",
    "http_status": 201,
    "response_digest": "sha256:..."
  }
}

Die Hashwerte von Anfrage und Antwort ermöglichen den Vergleich aufbewahrter Belege, ohne Geheimnisse oder große vertrauliche Nutzdaten jedem Leser des Journals zugänglich zu machen. Ein Hash macht ein Geheimnis nicht sicher protokollierbar. Werte mit geringer Entropie, vorhersehbare Kennungen und kurze Tokens bleiben erratbar. Schließen Sie Zugangsdaten bereits bei der Erfassung aus und entscheiden Sie danach, welche Teile der Nutzdaten der Vorfallsprozess wirklich benötigt.

Wiederholungen und Zeitüberschreitungen erzeugen die schwierigste Unklarheit

Eine Zeitüberschreitung bedeutet, dass Sie nicht wissen, ob die Gegenseite gehandelt hat. Sie bedeutet nicht, dass dort nichts geschehen ist. Teams machen diesen Fehler immer wieder, weil Anwendungs-Logs eine Zeitüberschreitung oft als einfachen Fehler behandeln und die nächste Wiederholung als Ersatz für den ersten Versuch ansehen.

Stellen Sie sich einen Agenten vor, der über eine HTTP-Anfrage eine Veröffentlichung erstellt. Aufruf 41 erhält nach der Weiterleitung eine Anfrage-Zeitüberschreitung. Der Agent liest diesen Fehler und sendet Aufruf 42, eine Wiederholung. Später verarbeitet der entfernte Dienst beide Anfragen. Wenn Ihr Journal Aufruf 41 mit dem endgültigen Status «wiederholt» überschrieben hat, sehen Ermittler eine erfolgreiche Anfrage und übersehen die doppelte Aktion.

Geben Sie jedem Netzwerkversuch eine eigene call_id und call_sequence. Fügen Sie retry_of hinzu, wenn ein Versuch direkt auf einen früheren folgt. Bewahren Sie den für den Agenten sichtbaren Grund der Wiederholung auf, etwa Zeitüberschreitung, Verbindungsabbruch oder einen erhaltenen wiederholbaren Status. Diese Beziehung ermöglicht es Ermittlern, die Kette nachzuverfolgen, ohne sie zu verflachen.

Eine vollständige Folge kann so aussehen:

sequence 41  accepted       21:14:11.024Z  create release, request r_8d2
sequence 41  dispatched     21:14:11.027Z
sequence 41  result_received 21:14:41.031Z timeout
sequence 41  result_returned 21:14:41.034Z timeout returned to agent
sequence 42  accepted       21:14:42.112Z  retry_of call_00041, request r_8d2
sequence 42  dispatched     21:14:42.115Z
sequence 42  result_received 21:14:42.490Z HTTP 201
sequence 42  result_returned 21:14:42.493Z HTTP 201 returned to agent

Die wiederholte Anfragekennung ist nur dann nützlich, wenn die entfernte API einen Idempotenzmechanismus oder eine andere stabile Operationskennung unterstützt. Wenn der Dienst einen Idempotenzschlüssel akzeptiert, erzeugen und speichern Sie einen nicht geheimen Schlüssel, der bei Wiederholungen für dieselbe beabsichtigte Operation gleich bleibt. Wenn er dies nicht tut, halten Sie fest, dass das Wiederholungsrisiko ungelöst bleibt. Behaupten Sie keine Idempotenz, nur weil die Nutzdaten ähnlich aussehen.

SSH bringt ein anderes Problem mit sich. Ein Befehl kann remote ausgeführt werden, während die Verbindung ausfällt, bevor der Client Ausgabe oder einen Exit-Code erhält. Zeichnen Sie die Befehlsweiterleitung, die Verbindungskennung, den Hostverweis und den beobachteten Beendigungszustand auf. Kennzeichnen Sie einen unterbrochenen SSH-Befehl als «Ergebnis unbekannt», nicht als «fehlgeschlagen». Ein späterer Befehl zur Prüfung des entfernten Zustands kann die Unsicherheit verringern, schreibt das ursprüngliche Ergebnis aber nicht um.

Machen Sie nicht jeden Fehler zu einem endgültigen Ereignis. Eine Autorisierungsablehnung ist für diesen Aufruf endgültig, weil keine externe Weiterleitung stattfand. Ein lokaler DNS-Fehler kann für den Versuch endgültig sein. Eine Zeitüberschreitung, nachdem Bytes den Rechner verlassen haben, bedeutet ein unbekanntes externes Ergebnis. Diese Kategorien führen zu unterschiedlichen Entscheidungen im Vorfall.

Erfassen Sie zwei Arten von Zeit und erklären Sie ihre Grenzen

Eine geordnete Beweisquelle behalten
Sallyport protokolliert Agentenläufe und einzelne Aufrufe in einem verschlüsselten, hashverketteten Audit-Log.

Die Uhrzeit macht eine Zeitleiste systemübergreifend lesbar. Monotone Zeit misst die verstrichene Zeit, ohne durch Zeitsynchronisierung im Netzwerk oder eine manuelle Uhrenkorrektur verändert zu werden. Erfassen Sie beide Werte, sofern das Betriebssystem sie bereitstellt, und erklären Sie in Ihrem Schema, wofür jeder Wert steht.

Zeichnen Sie für jedes Journalereignis einen RFC-3339-UTC-Wert occurred_at auf. Für Ereignisse innerhalb einer laufenden Sitzung speichern Sie zusätzlich monotonic_ns, gemessen ab dem vom Prozess gewählten Ursprung der monotonen Uhr. Vergleichen Sie monotone Werte verschiedener Rechner nicht, außer Sie haben ausdrücklich eine gemeinsame Referenz hergestellt. Es handelt sich um lokale Messungen.

Eine Uhrenkorrektur kann zu verwirrenden Datensätzen führen:

journal 901  wall 21:19:07.900Z  monotonic 5562019921  call accepted
journal 902  wall 21:18:58.104Z  monotonic 5562026310  call dispatched

Die Uhrzeit ist zurückgesprungen. Die Journal-Sequenz und der monotone Wert zeigen weiterhin, dass die Weiterleitung nach der Annahme erfolgte. Der Export sollte die ursprünglichen Zeitstempel behalten, statt sie stillschweigend zu sortieren und umzuschreiben. Fügen Sie ein Recorder-Ereignis hinzu, wenn das Betriebssystem eine erhebliche Zeitänderung meldet und Sie diese beobachten können. Dieses Ereignis liefert Prüfern einen Grund für die Abweichung.

NIST Special Publication 800-92, Guide to Computer Security Log Management, empfiehlt Organisationen, Uhren zu synchronisieren und Anforderungen an Logdaten vor einem Vorfall festzulegen. Das ist richtig, aber synchronisierte Uhren liefern keine Reihenfolge innerhalb eines Agentenlaufs. Die Synchronisierung verbessert die Korrelation mit einer entfernten API, einem CI-Dienst oder Host-Logs. Ihre lokale Sequenz stellt weiterhin die Reihenfolge des Recorders her.

Zeitstempel von entfernten Systemen verdienen eigene Felder. Ein HTTP-Date-Header, eine Provider-Anfrage-ID und eine serverseitig erzeugte Ereigniszeit sind externe Angaben. Bewahren Sie ihre Quelle und den exakten Wert auf. Kopieren Sie sie nicht in occurred_at und nummerieren Sie Ihr lokales Journal nicht anhand dieser Werte neu. Ein entfernter Zeitstempel kann später beim Abgleich helfen, aber er kann eine Warteschlange, eine andere Uhr oder den Zeitpunkt der Antworterzeugung widerspiegeln.

Auch Dauerfelder brauchen eine genaue Definition. gateway_duration_ms kann die Zeit von der Annahme bis zur Ergebnisrückgabe bedeuten. network_duration_ms kann die Zeit von der Weiterleitung bis zum Ergebniseingang bedeuten. Schreiben Sie die Definition neben das Schema. Andernfalls kann ein Bericht, der besagt, ein Aufruf habe 30 Sekunden gedauert, nicht erklären, ob die Verzögerung vor der Weiterleitung, beim entfernten Dienst oder nach dem Eintreffen der Antwort lag.

Der Audit-Writer muss die Reihenfolge vor der Veröffentlichung der Ergebnisse festlegen

Sie können die Reihenfolge nicht rekonstruieren, wenn parallele Worker Datensätze erst schreiben, sobald sie zufällig fertig werden. Geben Sie dem Audit-Writer einen einzigen Append-Pfad, der eine Journal-Sequenz vergibt, die Ereigniszeit erfasst, den vorherigen Datensatz verknüpft und den Datensatz festschreibt, bevor das System dem Agenten mitteilt, dass eine extern bedeutsame Zustandsänderung eingetreten ist.

Dafür ist keine große Sperre um sämtliche Netzwerkaktivitäten nötig. Aufrufe können parallel laufen. Der Recorder braucht nur einen schmalen serialisierten Festschreibungspunkt. Wenn ein Worker eine Ereignisgrenze erreicht, übermittelt er dem Writer ein Ereignis. Der Writer vergibt die nächste dauerhafte Journal-Sequenz. Die resultierende Reihenfolge entspricht der Festschreibungsreihenfolge. Diese müssen Sie in Dokumentation und Exporten korrekt benennen.

Das Fehlermuster ist bekannt. Worker A nimmt Aufruf 17 an und startet eine langsame Anfrage. Worker B nimmt Aufruf 18 an und wird schnell fertig. Wenn die Worker nur ihre Abschlussdatensätze anhängen, beginnt das Journal mit dem Erfolg von Aufruf 18. Ein Ermittler kann nicht erkennen, ob Aufruf 17 noch lief, nie gesendet oder ausgelassen wurde. Die Ereignisse «angenommen» und «weitergeleitet» für Aufruf 17 schließen diese Lücke.

Eine Hash-Verkettung fügt der festgeschriebenen Folge einen Manipulationsnachweis hinzu. Jeder Eintrag enthält den Hash des vorherigen festgeschriebenen Eintrags und den Hash seines eigenen kanonischen Inhalts. Die Kanonisierung ist wichtig. Dieselben Daten müssen vor dem Hashing dieselben Bytes ergeben. Legen Sie Feldreihenfolge, UTF-8-Kodierung, Zeitdarstellung, Behandlung von null und Zahlenformate fest. «Wir hashen das JSON» ist keine Spezifikation, weil die Reihenfolge gewöhnlicher JSON-Objekte keine Sicherheitseigenschaft ist.

Ein konzeptioneller Eintrag könnte diese Felder verwenden:

{
  "journal_sequence": 8131,
  "event_id": "01JNRQ3M8W7P0Q4R6S9T1V2X3Y",
  "previous_hash": "sha256:9c7d...",
  "record_hash": "sha256:04b1...",
  "payload": {"event_type": "call.result_received"}
}

Eine gültige Kette zeigt, dass die aufbewahrten Einträge ohne unbemerkte Änderung miteinander verbunden sind, sofern der Prüfer den erwarteten Kettenanker besitzt. Sie beweist keine Vollständigkeit, wenn ein Angreifer den Recorder kontrolliert und verhindern kann, dass dieser einen Datensatz schreibt. Stellen Sie Hash-Verkettung nicht als Magie dar. Sie macht Änderungen sichtbar, kann aber kein Ereignis aufzeichnen, das der Recorder nie beobachtet hat.

Sallyport erstellt seine Sessions- und Activity-Journale aus einem einzigen verschlüsselten, hashverketteten Audit-Log. Der Befehl sp audit verify prüft die Kette offline über den Chiffretext, ohne Tresorschlüssel. So bleiben die Sitzungsansicht und die Ansicht einzelner Aufrufe an eine geordnete Quelle gebunden, statt dass Ermittler zwei getrennte Logs abgleichen müssen.

Erstellen Sie eine Zeitleiste, die Unsicherheit bewahrt

Datensätze ohne Entschlüsselung prüfen
Prüfen Sie die Audit-Kette offline über den Chiffretext mit sp audit verify, ohne Tresorschlüssel.

Eine Vorfallzeitleiste sollte Fakten, Beobachtungen und ungeklärte Ergebnisse getrennt zeigen. Eine glatte Darstellung, die Unbekanntes in sichere Verben verwandelt, kann während einer angespannten Prüfung nützlich wirken. Sie erzeugt aber einen falschen Datensatz, dem spätere Belege widersprechen können.

Nehmen wir an, ein Agentenprozess erhielt um 09:00:00 eine Freigabe. Um 09:03:14 gab er einen SSH-Befehl aus. Um 09:03:16 verlor der Client die Verbindung. Um 09:03:18 fragte der Agent das Zielsystem per HTTP ab und fand eine geänderte Konfiguration. Diese Belege lassen mehrere Erklärungen zu: Der SSH-Befehl wurde abgeschlossen, ein anderer Akteur änderte den Zustand oder eine zuvor eingereihte Aufgabe wurde wirksam. Die Zeitleiste muss angeben, welche Schlussfolgerung die Belege stützen und welche nicht.

Verwenden Sie in Vorfallsnotizen diese Form:

ReihenfolgeZeitBelegGestützte Aussage
44409:03:14.120Zcall.dispatchedDas Gateway übergab den SSH-Befehl an den Helfer.
44509:03:16.202ZVerbindungsabbruchDas Gateway erhielt keinen Exit-Status.
44609:03:18.810ZHTTP-Antwort der AbfrageDie abgefragte Konfiguration unterschied sich zu diesem Zeitpunkt.
44709:03:19.001Zcall.result_returnedDer Agent erhielt das Abfrageergebnis.

Schreiben Sie nicht «Der SSH-Befehl änderte die Konfiguration», wenn Sie keinen direkten Beleg haben, der den Befehl mit der entfernten Wirkung verknüpft. Entfernte Audit-Datensätze, eine eindeutige Operations-ID oder eine Antwort mit einer dauerhaften serverseitigen Anfrage-ID können diese Verbindung herstellen. Ein naher Zeitstempel kann das nicht.

Ermittler müssen außerdem wissen, was der Agent bei späteren Entscheidungen gesehen hat. Deshalb verdient result_returned ein eigenes Ereignis. Wenn die entfernte Antwort eintraf, der Agent aber vor ihrem Empfang die Verbindung verlor, folgte eine spätere Agentenaktion nicht dieser Antwort. Wenn die Antwort den Agenten erreichte, kann sie einen gefährlichen Verhaltenszweig erklären.

Zeigen Sie in der Vorfallsansicht sowohl eine Sitzungsspur als auch eine Aufrufspur. Die Sitzungsspur zeigt Öffnungs-, Freigabe-, Widerrufs-, Sperr- und Abschlussereignisse. Die Aufrufspur zeigt Annahme, Autorisierung, Weiterleitung und Ergebnis. Eine flache Liste bleibt zur Prüfung verfügbar, aber die beiden Ansichten beantworten unterschiedliche Fragen, ohne sie zu vermischen.

Der Umgang mit Geheimnissen muss auch die Vorfallsprüfung überstehen

Aktionen über ein Gateway leiten
Der mitgelieferte sp mcp-Shim leitet HTTP- und SSH-Aktionen über Sallyport und nicht über vom Agenten verwaltete Zugangsdaten.

Audit-Trails versagen oft genau dann, wenn sie am nützlichsten wären, weil jemand «nur für diese eine Untersuchung» vollständige Header, Shell-Umgebungen und Antworttexte protokollieren möchte. Diese Entscheidung kann aus einem begrenzten Agentenvorfall den Verlust von Zugangsdaten machen.

Erfassen Sie die Identität der Aktion ohne geheimes Material. Für HTTP speichern Sie Methode, normalisierten Host und Pfad, Referenz oder Bezeichnung der Zugangsdaten, sichere Headernamen, Anfrage-Hash, Antwortstatus, sofern vorhanden die Provider-Anfrage-ID und eine sorgfältig gewählte Antwortzusammenfassung. Protokollieren Sie niemals einen Authorization-Header, einen rohen API-Schlüssel, einen privaten Schlüssel oder einen vollständigen Umgebungsdump. Befehle selbst können Geheimnisse enthalten. Wenn Ihr Ablauf beliebigen Shell-Text erlaubt, verwenden Sie für eng begrenzte Prüfungen einen geschützten Beweisspeicher oder speichern Sie nur eine redigierte Form mit Hash. Tun Sie nicht so, als sei ein Befehlsjournal harmlos, nur weil es keine Passwörter enthält.

Sallyport bewahrt API- und SSH-Zugangsdaten in seinem verschlüsselten Tresor auf und führt die externe Aktion aus, ohne diese Zugangsdaten an den Agenten weiterzugeben. Das beseitigt einen häufigen Grund dafür, dass Agententranskript und Logs zu einer Geheimnisablage werden. Ziel, Anfragekörper, Befehlsargumente und Antwort können aber weiterhin vertraulich sein.

Kontrollieren Sie den Zugriff auf Rohdaten getrennt von der Prüfung. Ein Incident Responder kann eine Kettenprüfung ohne Berechtigung zum Lesen verschlüsselter Aufrufdetails benötigen. Ein Sicherheitsprüfer benötigt vielleicht Sitzungs- und Zielmetadaten, aber keine Nutzdaten. Diese Trennung macht die Reaktion auf Vorfälle weniger abhängig davon, ein vollständiges Journal in Chats, Tickets oder Tabellen zu kopieren.

Fügen Sie beim Export von Belegen die Schemaversion, Exportzeit, den Bereich der Journal-Sequenzen, das Prüfergebnis und die verwendeten Redaktionsregeln hinzu. Bewahren Sie das ursprüngliche geschützte Journal unter seinen normalen Kontrollen auf. Ein Export ist eine Arbeitskopie und kein Ersatz für die Quelle.

Testen Sie den Datensatz mit einem bewusst unordentlichen Lauf

Eine Demo mit dem erfolgreichen Standardfall sagt fast nichts über die Rekonstruktion eines Vorfalls aus. Testen Sie die Bedingungen, die Reihenfolgen unklar machen: parallele Aufrufe, verzögerte Antworten, Uhrenänderungen, Prozessenden, Ablehnungen, Widerrufe sowie eine Zeitüberschreitung mit anschließender Wiederholung.

Führen Sie eine kontrollierte Übung mit zwei erlaubten externen Zielen durch. Lassen Sie den ersten Aufruf vor seiner Rückgabe warten. Starten Sie einen zweiten Aufruf, nachdem der erste weitergeleitet wurde. Unterbrechen Sie einen dritten Aufruf nach der Weiterleitung. Widerrufen Sie anschließend die Sitzung und prüfen Sie, dass spätere Aufrufe abgelehnt werden. Exportieren Sie das Journal und übergeben Sie es einem Kollegen, der das Szenario nicht erstellt hat.

Bitten Sie diese Person, allein anhand des Exports fünf Fragen zu beantworten:

  • Welcher Prozess erhielt die Berechtigung, und wann endete sie?
  • In welcher Reihenfolge nahm das Gateway die Aufrufe dieser Sitzung an?
  • Welche Aufrufe erreichten die Weiterleitungsgrenze?
  • Welches Ergebnis erhielt der Agent vor jedem späteren Aufruf?
  • Welche Ergebnisse bleiben unbekannt und sind weder fehlgeschlagen noch erfolgreich?

Wenn die Person fragen muss, was ein Feld bedeutet, verbessern Sie Schema oder Exportdokumentation. Wenn sie aus einer Zeitüberschreitung auf eine entfernte Wirkung schließt, verbessern Sie die Ergebnisbezeichnungen. Wenn sie eine Wiederholung nicht von einer neuen Operation unterscheiden kann, ergänzen Sie die Beziehung und die Operationskennung.

Bewahren Sie die Übungsartefakte auf. Sie werden zu Regressionstests, wenn Sie eine Clientbibliothek ändern, Parallelität einführen, die Aufbewahrung anpassen oder einen neuen Kanal ergänzen. Fehler in der Reihenfolge entstehen oft durch scheinbar harmlose Refactorings, weil Entwickler darauf achten, ob Aktionen weiterhin funktionieren, während sich der Festschreibungszeitpunkt des Beweispfads unbemerkt verändert.

Der Vorfall wird nicht auf ein saubereres Logging-Design warten. Vergeben Sie die Sitzungssequenz bei der Annahme des Aufrufs, schreiben Sie Lebenszyklusereignisse über einen geordneten Writer fest, bewahren Sie sowohl Uhrzeit als auch monotone Zeit auf und lassen Sie unbekannte Ergebnisse unbekannt bleiben. So erhalten Ermittler eine verteidigbare Sequenz statt einer Zeitleiste, deren Lücken sie erklären müssen.

FAQ

Reicht ein Zeitstempel aus, um einen Vorfall mit einem KI-Agenten zu rekonstruieren?

Ein Zeitstempel hält fest, was eine Uhr an einer bestimmten Ereignisgrenze angezeigt hat. Eine Ereignisfolge zeigt die Reihenfolge, in der Ihr Recorder Ereignisse angenommen oder festgeschrieben hat. Bewahren Sie beides auf: Die Uhrzeit macht die Folge verständlich, während ein Sequenzfeld Gleichstände, Uhrkorrekturen und parallele Arbeit auflöst.

Was sollte als Agentensitzung gelten?

Verwenden Sie eine Sitzung pro Lauf eines Agentenprozesses, nicht pro Repository, Person oder Kalendertag. Eine Prozessgrenze ermöglicht es Ermittlern festzustellen, welche ausführbare Datei eine Freigabe erhielt, wann diese Berechtigung endete und welche Aufrufe zum selben Lauf gehören. Eine langlebige Sitzung verbirgt zu viele voneinander unabhängige Aktivitäten.

Welche Felder braucht ein Audit-Datensatz für eine Agentenaktion?

Speichern Sie mindestens eine Sitzungs-ID, eine monotone Aufrufsequenz, eine dauerhafte Ereignis-ID, den Zeitpunkt des Anforderungsstarts, der Weiterleitung, des Ergebniseingangs und der Ergebnisrückgabe sowie Kanal, Ziel und Ergebnis. Speichern Sie außerdem eine sichere Zusammenfassung von Anfrage und Ergebnis, aber keine Zugangsdaten und keine unnötigen vertraulichen Antwortdaten.

Entspricht die Reihenfolge der Anfragen der Reihenfolge, in der eine entfernte API sie verarbeitet hat?

Nein. Eine API-Anfrage kann beim entfernten Dienst später eintreffen als eine Anfrage, die Ihr Agent später gesendet hat. Das gilt besonders bei Verbindungen, Wiederholungen, Warteschlangen oder verschiedenen Protokollen. Bewahren Sie sowohl die lokale Weiterleitungsreihenfolge als auch alle verfügbaren Nachweise über den Eingang oder Abschluss auf der Gegenseite auf.

Wie sollten Audit-Logs mit Wiederholungen und Zeitüberschreitungen umgehen?

Eine Wiederholung braucht eine eigene Aufruf-ID und eine eigene Sequenzposition sowie einen Verweis auf den früheren Versuch. Wenn Sie den ersten Versuch überschreiben, kann ein Ermittler nicht erkennen, ob die erste Anfrage vor der Zustellung scheiterte, nach der Zustellung auslief oder vor der Wiederholung eine Wirkung hatte.

Sollten Audit-Logs die Uhrzeit oder monotone Zeit verwenden?

Verwenden Sie einen Zeitstempel für die menschliche Korrelation und eine monotone Zeitangabe oder eine dauerhafte Sequenz für die lokale Reihenfolge. Eine Uhrzeit kann sich ändern, wenn das System die Zeit synchronisiert, aus dem Ruhezustand zurückkehrt oder manuell korrigiert wird. Monotone Zeit kann keine Kalenderzeit angeben, bewahrt aber die verstrichene Reihenfolge während der Lebensdauer eines Prozesses.

Kann ein hashverkettetes Audit-Log beweisen, dass keine Aktionen fehlen?

Eine Hash-Kette kann zeigen, dass eine gespeicherte Folge nicht unbemerkt verändert wurde, sofern Ermittler sie gegen den erwarteten Kettenzustand prüfen. Sie kann nicht beweisen, dass ein kompromittierter Recorder kein Ereignis unterschlagen hat, bevor es aufgezeichnet wurde. Behandeln Sie Manipulationsnachweis und Vollständigkeit als getrennte Eigenschaften.

Kann ein Audit-Datensatz nach dem Schreiben korrigiert werden?

Schreiben Sie das alte Ereignis nicht um. Hängen Sie ein Korrekturereignis an, das die ursprüngliche Ereignis-ID nennt, das geänderte Feld und den Grund der Änderung beschreibt sowie angibt, wer und wann die Korrektur vorgenommen hat. Das Löschen oder Bearbeiten des Originals zerstört die Historie, die eine Untersuchung braucht.

Wie lange sollten Teams Aktivitäts-Logs von KI-Agenten aufbewahren?

Bewahren Sie Rohdaten so lange auf, wie es Ihre Anforderungen an Incident Response, Recht und Betrieb verlangen. Wenn vollständige Nutzdaten vertrauliche Informationen enthalten, können Sie anschließend einen geprüften Export oder eine Zusammenfassung aufbewahren. Aufbewahrung ohne Zugriffskontrolle schafft einen weiteren Angriffsweg. Legen Sie Löschregeln vor einem Vorfall fest, nicht während alle über das Aufräumen eines Datenträgers diskutieren.

Wie kann ich testen, ob unser Audit-Trail für einen Vorfall geeignet ist?

Beginnen Sie mit einem kontrollierten Agentenlauf und erzeugen Sie zwei überlappende externe Aufrufe, eine verzögerte Antwort und eine Wiederholung. Bitten Sie anschließend jemanden, der den Test nicht erstellt hat, die Reihenfolge allein anhand des Journalexports zu rekonstruieren. Wenn diese Person mündliche Erklärungen braucht, um den Ablauf zu verstehen, ist Ihr Datensatz unvollständig.

Sallyport

Sallyport führt API-Aufrufe und SSH-Befehle für Ihren KI-Agenten aus. Die Schlüssel bleiben in einem lokalen Tresor auf Ihrem Mac; Sie geben jeden Lauf frei, und jede Aktion landet in einem versiegelten Journal.

© 2026 Sallyport · Open Source unter Apache-2.0 · Oleg Sotnikov