# Wie Agent-Freigabeaufforderungen Freigaben für den falschen Lauf verhindern

Eine Freigabewarteschlange für autonome Agenten ist kein Stapel von Berechtigungsschaltflächen. Sie ist ein laufendes System zur Zuordnung. Wenn zwei oder mehr Agent-Läufe dieselben Zugangsdaten anfordern, dieselbe API aufrufen oder dieselbe SSH-Verbindung öffnen können, muss ein Prüfer vor der Freigabe eine enge Frage beantworten können: *Welcher laufende Prozess bittet mich, genau diese Aktion zu autorisieren?*

Die meisten Freigabeoberflächen scheitern, weil jede Karte so aussieht, als stamme sie von einem einzigen generischen Akteur namens «der Agent». Bei einer Demo mit nur einem Terminalfenster ist diese Bezeichnung harmlos. Gefährlich wird sie, wenn ein Coding-Agent einen Produktionsvorfall behebt, während ein anderer Agent einen Release vorbereitet, beide denselben Client verwenden und beide Zugriff auf denselben Dienst verlangen. Der Prüfer sieht ein vertrautes Ziel, erkennt die Aufgabe grob wieder und gibt die richtige Aktion für den falschen Lauf frei.

## Eine Freigabe ist eine Zuordnungsentscheidung

Ein Prüfer gibt keinen HTTP-Request isoliert frei. Er gibt ihn frei, *weil er zu einer bestimmten Arbeit gehört*, die seiner Erwartung nach gerade stattfindet. Kann die Oberfläche diese Verbindung nicht bewahren, wird die Freigabeschaltfläche zu einer Vermutung, die als menschliche Kontrolle verkleidet ist.

Behandle jede Freigabe als Aussage mit fünf Teilen:

1. Ein bestimmtes ausführbares Programm oder ein bestimmter Agent-Prozess hat sie ausgelöst.
2. Eine bestimmte Sitzung dieses Prozesses ist noch aktiv.
3. Diese Sitzung gehört zu einer benannten Aufgabe oder einem Arbeitselement.
4. Sie möchte eine konkrete externe Aktion ausführen.
5. Der Prüfer autorisiert dieses Tupel oder lehnt es ab.

Der fünfte Punkt ist wichtiger, als es zunächst klingt. «Zugriff auf die Deployment-API freigeben» ist keine vollständige Aussage. Ein Prüfer kann dem Release-Lauf erlauben wollen, einen Build-Eintrag zu lesen, aber einem unabhängigen Debugging-Lauf nicht erlauben, eine Release-Einstellung zu ändern. Das Ziel allein kann die Bedeutung nicht tragen.

Diese Unterscheidung verschwimmt, weil derselbe Agent-Client oft beide Läufe erzeugt. Die Kommandozeile kann identisch sein. Die Codesignatur kann identisch sein. Der Repository-Pfad kann identisch sein. Der Agent kann sogar fast identische Anfragen erzeugen. Nichts davon macht zwei gleichzeitige Aufrufe zu demselben Sicherheitsobjekt.

Ich habe Teams erlebt, die der Aktionszusammenfassung mehr Wörter hinzufügten, obwohl das eigentliche Problem die fehlende Zuordnung war. Aus «POST /deployments» wurde «POST /deployments, um ein Staging-Deployment für Version 1.8.4 auszulösen». Das erklärt die Operation besser, lässt den Prüfer aber weiterhin mit zwei Karten zurück, die beide ein Staging-Deployment beanspruchen. Ein besserer Satz kann eine fehlende Sitzungsgrenze nicht reparieren.

Die Freigabeoberfläche muss die Identitätshierarchie sichtbar machen. Die Aktion ist das primäre Objekt. Der auslösende Prozess und die aktive Sitzung erklären, warum diese Aktion erschienen ist. Die Aufgabenbezeichnung hilft dem Prüfer, die Absicht zu erkennen, ersetzt aber keine der technischen Kennungen.

## Ein signierter Prozess ist keine laufende Sitzung

Eine Codesignatur kann einem System sagen, wer den Code signiert hat. Sie sagt einem Prüfer aber nicht, welcher Aufruf dieses Codes eine ausstehende Anfrage erzeugt hat. Die Dokumentation zur Codesignatur von Apple zieht dieselbe Grenze mit anderen Begriffen: Code Requirements legen die Codeidentität fest, während eine Designated Requirement beschreibt, was über verschiedene Versionen hinweg als derselbe Code gilt. Das liefert nützliche Hinweise über den Aufrufer, ersetzt aber keine Laufkennung.

Das ist wichtig, wenn eine Freigabeaufforderung etwa so beginnt:

```text
Request from: Acme Agent CLI
Signed by: Example Engineering, Team ABCD1234
```

Das ist ein guter Anfang. Der Prüfer erkennt, ob ein erwarteter Client Zugriff angefordert hat. Die Anzeige beantwortet aber nicht, ob es sich um den vor fünf Minuten gestarteten Release-Assistenten, den seit heute Morgen geöffneten Test-Assistenten oder einen kopierten Shell-Befehl in einem zweiten Terminal handelt.

Prozess- und Sitzungsidentität beantworten unterschiedliche Fragen:

| Feld | Beantwortete Frage | Was es nicht beantwortet |
|---|---|---|
| Codesignatur | Wer hat dieses ausführbare Programm erstellt? | Welcher Aufruf ist es? |
| Pfad des Programms | Welcher installierte Client hat es gestartet? | Welche Aufgabe führt er aus? |
| Prozess-ID | Welcher lokale Prozess besitzt derzeit die Verbindung? | Kann ein Mensch ihn nach Neustarts wiedererkennen? |
| Sitzungs-ID | Welcher begrenzte Lauf hat diese Anfrage gestellt? | Ist die angeforderte Aktion sinnvoll? |
| Aufgabenbezeichnung | Was sollte dieser Lauf laut Benutzer tun? | Ist die Bezeichnung wahr oder als Beleg ausreichend? |

Verbirg die ersten beiden Zeilen nicht, nur weil du die vierte hinzufügst. Der Prüfer braucht die Prozessautorität, um einen unerwarteten Client zu erkennen. Er braucht die Sitzungs-ID, um gleichzeitig laufende erwartete Clients zu unterscheiden. Er braucht die Aufgabenbezeichnung, um eine technische Kennung mit einem verständlichen Arbeitsmodell zu verbinden.

Die praktische Regel ist einfach: Zeige die Prozessidentität als Herkunft und die Sitzungsidentität als Einheit, die freigegeben wird.

Unter macOS ist eine Codesignatur allein als Freigabebezeichnung besonders schwach. Apple weist ausdrücklich darauf hin, dass Signaturkennungen von mehreren Signierern beansprucht werden können, und empfiehlt, eine Kennungsprüfung mit der Validierungskategorie und bei Code von Drittanbietern mit einer Teamkennung zu verbinden. Eine Karte, die nur einen freundlichen Bundle-Namen oder nur eine beanspruchte Kennung anzeigt, liefert dem Prüfer weniger Informationen, als die Plattform bereitstellen kann.

Zeige rohe Requirement-Sprache nicht als Hauptbezeichnung. Sie ist präzise, aber die meisten Prüfer können sie nicht schnell genug lesen. Formuliere die Signaturautorität in verständlicher Sprache, stelle die technische Requirement in den Details bereit und verbinde sie mit einem erkennbaren Programmnamen. Platziere die Sitzungskennung anschließend so, dass sie ohne Aufklappen sichtbar ist.

## Jeder Lauf braucht eine Sitzungsidentität, die die Warteschlange überlebt

Eine Sitzungs-ID muss vor dem ersten geschützten Aufruf entstehen, während des gesamten Laufs stabil bleiben und aus der Autorisierungsmenge verschwinden, sobald der Lauf endet. Alles Schwächere erzeugt unter Last Mehrdeutigkeiten.

Erzeuge bei der Verbindungs- oder Prozessregistrierung eine undurchsichtige ID mit hoher Entropie. Speichere den vollständigen Wert im Audit-Eintrag, zeige in der Aufforderung aber ein kurzes, eindeutiges Präfix. Die Anzeigeform sollte lang genug sein, damit zwei aktive Sitzungen es nur sehr wahrscheinlich nicht gemeinsam verwenden. Falls doch eine Kollision auftritt, muss die Oberfläche sie unübersehbar machen. Leite die ID nicht allein aus der aktuellen Uhrzeit, einer Warteschlangenposition, einem Repository-Namen oder der Prozess-ID ab.

Ein sinnvoller interner Eintrag sieht so aus:

```json
{
  "session_id": "ses_7TQ4N8M2KDXP6R9V",
  "display_id": "7TQ4N8M2",
  "process": {
    "pid": 84172,
    "executable": "/usr/local/bin/agent-cli",
    "signing_authority": "Example Engineering (Team ABCD1234)"
  },
  "task": {
    "label": "Prepare the staging release notes",
    "workspace": "/Users/maya/work/app"
  },
  "started_at": "2026-07-22T16:42:11Z"
}
```

Die Aufgabenbezeichnung sollte aus einer für Menschen sichtbaren Anweisung oder einem bewusst vergebenen Sitzungstitel stammen, nicht aus einem vom Modell erzeugten Satz, der sich bei jedem Tool-Aufruf ändert. Ein Modell kann die Bezeichnung vorschlagen, aber das System sollte sie beim Sitzungsstart einfrieren. Wenn eine Sitzung von «Staging-Release-Notizen vorbereiten» zu «Produktions-Webhook-Zugangsdaten rotieren» wechselt, verdient der Prüfer eine ausdrückliche Aufgabenänderung oder eine neue Sitzung. Wird die Bezeichnung stillschweigend umgeschrieben, wird die Historie schwerer lesbar und der Lauf kann sich die Legitimität einer früheren, sichereren Aufgabe leihen.

Verwende einen Lebenszyklus mit klaren Grenzen:

- Erzeuge die Sitzung vor jeder Aktion mit Zugangsdaten.
- Verknüpfe jede Anfrage, Freigabe, Ablehnung, Stornierung und jedes Ergebnis mit dieser Sitzung.
- Schließe die Sitzung, wenn der auslösende Prozess endet oder seine gültige Verbindung verliert.
- Widerrufe die Sitzung sofort, wenn der Prüfer «Widerrufen» auswählt.
- Lehne ausstehende Freigaben nach dem Schließen oder Widerrufen ab, auch wenn eine Karte noch kurz sichtbar bleibt.

Der letzte Punkt verhindert ein subtiler, aber häufiger Wettlauf. Ein Prüfer sieht eine Karte von Lauf A. Lauf A endet. Ein neuer Lauf B beginnt, fordert eine ähnliche Aktion an, und die alte Karte nimmt weiterhin Eingaben an. Verknüpft der Freigabedienst den Klick mit «der neuesten Anfrage für diese Zugangsdaten», hat der Prüfer B freigegeben, während er A betrachtet. Binde die Karte an genau eine unveränderliche Anfrage-ID und eine Sitzungs-ID. Sobald eine davon ungültig wird, darf die einzige sichere Schaltfläche «Ausblenden» sein.

Vermeide Bezeichnungen wie «Sitzung 1», «Agent-Lauf» oder «Aktuelle Aufgabe». Sie funktionieren, bis der zweite Lauf beginnt. Eine Bezeichnung darf freundlich sein, aber die Oberfläche braucht eine Kennung, die auch nach einem Prozessneustart, dem Ruhezustand eines Laptops oder einer Untersuchung Tage später verständlich bleibt.

## Die richtigen Fakten in die ersten zwei Zeilen

Die ersten beiden Zeilen einer Freigabeaufforderung sollten den Prüfer eine Anfrage von allen anderen ausstehenden Anfragen unterscheiden lassen, ohne Details öffnen zu müssen. Stelle zuerst die angeforderte Aktion dar und nenne direkt darunter den auslösenden Prozess und die Sitzung.

Eine brauchbare Karte hat diese Form:

```text
Allow POST to api.example.internal/v1/releases?
agent-cli, signed by Example Engineering, session 7TQ4N8M2
Task: Prepare the staging release notes

Creates a release record named "2026.07.22-rc3"
Credential: release-service-write
[Review request]                         [Deny] [Allow]
```

Die Aktionszeile sagt, was wo geschieht. Die Zuordnungszeile sagt, wer die Anfrage gestellt hat. Die Aufgabenzeile zeigt, welcher Arbeit der Prüfer die Anfrage zuordnen soll. Die Vorschau liefert genügend Informationen für eine erste Einschätzung. Diese Reihenfolge ist beabsichtigt.

Beginne nicht mit «Freigabe angefordert» oder «Agent möchte ein Geheimnis verwenden». Keine der beiden Formulierungen hilft beim Sortieren einer vollen Warteschlange. Beginne auch nicht mit dem Namen der Zugangsdaten. Zugangsdaten sind Implementierungsdetails. Ein Prüfer weiß meist schon, ob eine Anfrage zum richtigen Release-Lauf gehört, bevor er weiß, ob `release-service-write` der passende gespeicherte Schlüssel ist.

Für SSH sollte die entsprechende Aufforderung den entfernten Host und die Befehlsart nennen, nicht nur «SSH-Zugriff». Zum Beispiel:

```text
Allow SSH command on build-staging-03.example.internal?
agent-cli, signed by Example Engineering, session 7TQ4N8M2
Task: Verify the staging migration

Runs: /usr/local/bin/check-migration --database app_staging
Credential: deploy-ssh
[Review command]                         [Deny] [Allow]
```

Kann das System keine sichere, lesbare Vorschau erzeugen, sollte es das sagen. «Befehlsargumente nicht verfügbar» ist besser, als einen freundlichen Satz zu erfinden, der Shell-Erweiterungen, ein indirektes Skript oder ungeprüfte Eingaben verbirgt. Der Prüfer kann dann den exakten Befehl öffnen oder die Anfrage ablehnen.

Eine gute Aufforderung zwingt den Prüfer nicht, den auslösenden Lauf aus einem Zeitstempel abzuleiten. Die Uhrzeit gehört in die Details und den Aktivitätsverlauf. Zwei Agenten können Anfragen innerhalb derselben Sekunde stellen, und Menschen ordnen Karten nicht zuverlässig anhand von Zeitstempeln einem Terminal zu. Verwende die Uhrzeit als zusätzliche Information, niemals als Bezeichnung, die die Zuordnung trägt.

Platziere die Sitzungs-ID außerdem nicht in einer blassen Fußzeile. Die Kennung ist kein diagnostischer Ballast. In einer parallelen Warteschlange verhindert sie, dass ein Prüfer zwei fast identische Karten als austauschbar behandelt.

## Eine Warteschlange braucht Gruppierung ohne falsche Zusammenfassung

Parallele Arbeit erzeugt ein visuelles Sortierproblem. Karten nach Sitzung zu gruppieren kann helfen, wird aber gefährlich, wenn die Oberfläche wichtige Unterschiede zwischen Anfragen zusammenfallen lässt.

Der Prüfer sollte alle ausstehenden Aktionen einer Sitzung gemeinsam sehen können, während für Aktionen mit unterschiedlichen Folgen jeweils eine eigene Freigabeentscheidung erhalten bleibt. Ein Release-Assistent, der drei schreibgeschützte API-Aufrufe benötigt, kann sie sinnvoll kompakt gruppieren. Eine Sitzung, die ein Problem lesen, einen Deployment-Eintrag schreiben und eine entfernte Migration ausführen möchte, sollte drei getrennte Entscheidungen anzeigen, weil die Folgen unterschiedlich sind.

Das falsche Muster ist ein globales Banner:

```text
agent-cli requests access to 5 services
[Allow all]
```

Diese Schaltfläche fordert den Prüfer auf, eine Sammlung freizugeben, bevor er jede Anfrage einem Lauf zugeordnet oder ihre Folgen geprüft hat. Außerdem fördert sie Ermüdung. Je häufiger ein Prüfer das Banner sieht, desto eher entwickelt er die Gewohnheit, es einfach zu leeren, um weiterarbeiten zu können.

Eine bessere Warteschlange verwendet Sitzungsüberschriften als Kontext, nicht als umfassende Autorisierung:

```text
Session 7TQ4N8M2 · agent-cli · Prepare the staging release notes
2 pending requests

  GET api.example.internal/v1/builds/rc3             [Allow]
  POST api.example.internal/v1/releases              [Review]

Session C5J1W6PA · agent-cli · Investigate test failure #1842
1 pending request

  SSH build-staging-03.example.internal              [Review]
```

Der Prüfer kann visuell nach Lauf sortieren, aber jede Zeile stellt weiterhin eine eigene Behauptung auf. Unterstützt das System einen Autorisierungsstatus pro Sitzung, zeige ihn in der Überschrift mit klarem Umfang an: «Diese Sitzung ist autorisiert, bis sie endet.» Lass diesen Status nicht wie eine Freigabe für jede einzelne Aktion aussehen. Eine Sitzungsautorisierung erlaubt dem Lauf, Aktionen anzufordern. Sie macht unerwartete Aktionen nicht automatisch erwartbar.

Auch die Reihenfolge beeinflusst Fehler. Eine rein chronologische Warteschlange kann Anfragen von fünf Läufen so stark vermischen, dass der Prüfer den Kontext keines Laufs halten kann. Eine rein sitzungsgruppierte Warteschlange kann eine dringende Anfrage hinter einer lauten Sitzung verbergen. Biete beide Ansichten an: standardmäßig eine gruppierte Ansicht für die Zuordnung und eine zeitlich sortierte Ansicht für die Reaktion auf Vorfälle. Das Sitzungskennzeichen muss in beiden Ansichten sichtbar bleiben.

Führe Karten nicht allein deshalb zusammen, weil sie dasselbe Ziel und dieselben Zugangsdaten verwenden. Zwei getrennte Läufe, die an denselben Endpunkt schreiben, erzeugen genau die Mehrdeutigkeit, die die Warteschlange lösen soll. Ähnlichkeit ist ein Grund, die Laufidentität stärker hervorzuheben, nicht die Freigaben zusammenzufassen.

## Die Freigabe muss an genau die geprüfte Anfrage gebunden sein

Eine Aufforderung kann den richtigen Lauf identifizieren und trotzdem die falsche Anfrage autorisieren, wenn die Freigabe für eine veränderliche Vorlage statt für eine unveränderliche Aktion gilt. Der Prüfer muss eine konkrete Darstellung der Anfrage freigeben, nicht eine zukünftige Anfrage, die zufällig dieselbe Route, denselben Befehl oder dieselben Zugangsdaten wiederverwendet.

Erzeuge den kanonischen Aktionseintrag, bevor die Karte erscheint. Für HTTP sollte er mindestens Methode, normalisierten Ursprung und Pfad, ausgewählte Header nach Namen, Alias der Zugangsdaten und einen Digest des Bodys enthalten. Für SSH gehören die normalisierte Hostidentität, das angeforderte Konto, der Port, die Befehlsbytes und der Alias der Zugangsdaten hinein. Speichere das vollständige geschützte Material in der vertrauenswürdigen Komponente. Der Agent sollte es nicht erhalten, nur weil der Prüfer eine Aufforderung sehen muss.

Binde die Freigabe anschließend an den kanonischen Eintrag:

```json
{
  "approval_id": "apr_K9H2D7LQ",
  "session_id": "ses_7TQ4N8M2KDXP6R9V",
  "action_digest": "sha256:2a13c4e0...",
  "expires_at": "2026-07-22T16:47:11Z",
  "decision": "allow_once"
}
```

Berechne vor der Ausführung den Digest aus der Aktion neu, die den Rechner tatsächlich verlässt. Weicht er ab, lehne die Freigabe ab und erstelle eine neue Karte. Behandle eine veränderte Anfrage nicht stillschweigend als «nahe genug». Ein geänderter URL-Parameter kann eine Zahlung umleiten, ein geänderter Header den Kontoumfang verändern und ein geändertes Shell-Argument aus einem Prüfungsbefehl einen Schreibbefehl machen.

Hier scheitern viele ansonsten durchdachte Systeme. Sie zeigen eine prüfbare Zusammenfassung, geben «Zugangsdaten X für Endpunkt Y verwenden» frei und lassen den Agenten anschließend unter dieser weitreichenden Freigabe eine zweite Anfrage stellen. Der Prüfer hat die zweite Anfrage nicht geprüft. Das System hat eine einzelne ausdrückliche Entscheidung in eine unsichtbare Richtlinie verwandelt.

Verwende für eine ausstehende Freigabe eine kurze Ablaufzeit. Es geht nicht darum, einen Prüfer zu bestrafen, der eine Kaffeepause macht. Eine alte Entscheidung soll nicht angewendet werden können, nachdem sich der umgebende Kontext verändert hat. Benötigt der Agent die Aktion später weiterhin, kann er mit denselben Prozess- und Sitzungsdaten eine neue Anfrage stellen. Der Prüfer sieht dann, ob sie noch dazugehört.

Material von NIST zur menschlichen Beteiligung an automatisierten Entscheidungen warnt vor Automatisierungsverzerrung und reibungsarmen Freigabeschleifen, die eine Ermüdung durch Warnungen normalisieren. Die praktische Konsequenz ist eindeutig: Freigaben lassen sich nicht dadurch sinnvoll machen, dass sie sich leicht anklicken lassen. Die Oberfläche muss die Entscheidung klein genug zum Prüfen und spezifisch genug für Verantwortlichkeit machen.

## Die Detailansicht sollte Streitfälle klären, nicht erzeugen

Eine kompakte Freigabekarte kann nicht jedes Byte einer Anfrage enthalten. Sie braucht aber eine Detailansicht, die die Fragen eines sorgfältigen Prüfers beantwortet, wenn die Aktion unbekannt, kostspielig oder verdächtig ist.

Bei einer HTTP-Aktion sollten vollständige Methode und URL, standardmäßig geschwärzte Header, Body-Felder mit klarer Kennzeichnung von Geheimnissen, der Zugangsdaten-Alias, die Identität des auslösenden Prozesses, die Sitzungs-ID, die Aufgabenbezeichnung und der Erstellungszeitpunkt der Anfrage zu sehen sein. Ist der Body binär oder zu groß für die Darstellung, zeige Größe, Inhaltstyp und Digest. Tu nicht so, als könne eine einzeilige Zusammenfassung dies ersetzen.

Bei SSH sollten Host, Benutzer, Port, der Status der Hostprüfung, sofern verfügbar, der exakt auszuführende Befehl, das Arbeitsverzeichnis, falls relevant, und alle Umgebungswerte angezeigt werden, die das Verhalten beeinflussen. Eine Befehlsvorschau muss Anführungszeichen und Argumentgrenzen bewahren. Wird ein Array als lose verbundene Shell-Zeichenkette dargestellt, kann ein sicherer Befehl unsicher wirken oder, schlimmer noch, ein unsicherer Befehl harmlos aussehen.

Es gibt einen deutlichen Unterschied zwischen Schwärzung aus Sicherheitsgründen und dem Weglassen aus Bequemlichkeit. Schwärze Bearer-Token, private Schlüssel, Passwörter oder sensible Body-Werte in der Aufforderung. Schwärze Pfad, Zielkonto, entfernten Host, Befehl oder geänderte Felder nicht nur deshalb, weil die Karte dadurch länger wird. Gerade diese Fakten zeigen oft, ob die Anfrage zu diesem Lauf gehört.

Verwende in der Detailansicht einen stabilen Anfrage-Fingerabdruck. Ein Prüfer, der einem Kollegen schreibt, sollte sagen können: «Ich habe Anfrage `apr_K9H2D7LQ` aus Sitzung `7TQ4N8M2` abgelehnt», und der Kollege sollte genau einen Eintrag finden. Lass niemanden ein Ereignis als «die zweite Deployment-Aufforderung gegen 4:40 Uhr» beschreiben müssen. Das funktioniert, bis ein Vorfall Präzision verlangt.

Die Prüfoberfläche sollte außerdem sagen, was die Freigabe autorisiert und was nicht. Zum Beispiel:

```text
Allow once
This decision authorizes only this POST request with digest 2a13c4e0…
It does not authorize later calls from session 7TQ4N8M2.
```

Dieser Satz verdient seinen Platz. Er verhindert, dass ein Prüfer eine weitreichende Freigabe annimmt, und dass ein Implementierer den Umfang hinter derselben Schaltflächenbezeichnung später erweitert.

## Abbruch und Widerruf brauchen sichtbare Folgen

Ein Prüfer wird irgendwann die falsche Karte freigeben oder bemerken, dass ein Lauf vom vorgesehenen Weg abkommt. Die Wiederherstellung muss schnell, sichtbar und an dieselben Kennungen gebunden sein, die während der Freigabe verwendet wurden.

Die Oberfläche braucht getrennte Aktionen zum Ablehnen einer einzelnen Anfrage und zum Widerrufen einer einzelnen Sitzung. Ablehnen bedeutet: «Diese Aktion nicht ausführen.» Widerrufen bedeutet: «Dieser laufende Prozess hat seine Autorisierung verloren. Storniere seine ausstehenden Freigaben und lehne spätere Aktionen ab.» Die Folgen unterscheiden sich, daher dürfen beide Aktionen nicht hinter einer mehrdeutigen Schaltfläche «Stoppen» verborgen werden.

Wenn ein Prüfer eine Sitzung widerruft, muss die Bestätigung Prozess, Sitzungs-ID und Aufgabe nennen:

```text
Revoke session 7TQ4N8M2?
agent-cli is running “Prepare the staging release notes.”
Pending requests from this session will be cancelled. New protected actions
from this process will be denied until it starts a new session.
[Keep session] [Revoke session]
```

Wird eine Anfrage bereits ausgeführt, muss das ehrlich gemeldet werden. Ein Widerruf kann zukünftige privilegierte Aktionen verhindern, aber einen HTTP-Request, den ein entfernter Dienst bereits angenommen hat, nicht rückgängig machen oder einen bereits gestarteten entfernten Befehl nicht zwingend anhalten. Der Aktivitätseintrag sollte zeigen, ob die Aktion ausstand, gesendet, abgeschlossen, fehlgeschlagen oder storniert wurde. Schreibe nicht «widerrufen», wenn dadurch der Eindruck entsteht, der externe Effekt sei verschwunden.

Das ist ein weiterer Grund, die Sitzungs-ID auf jeder Karte anzuzeigen. Während eines stressigen Vorfalls braucht der Prüfer eine direkte Verbindung von einer verdächtigen Aufforderung zu der Kontrolle, die diesen Lauf stoppt. Sagt die Warteschlange nur «agent-cli», besteht das Risiko, den nützlichen Lauf zu beenden und den problematischen aktiv zu lassen.

Sitzungs- und Aktivitätsprotokoll sollten dieselben Kennungen verwenden. Ein Eintrag zeigt, dass die Prozesssitzung `7TQ4N8M2` begonnen, eine Autorisierung erhalten und widerrufen wurde. Der andere zeigt, welche einzelne Aktion sie vor und nach jeder Zustandsänderung versucht hat. Verwenden die Aufzeichnungen unverbundene Bezeichnungen, müssen Einsatzkräfte Verknüpfungen rekonstruieren, die das Produkt hätte sichtbar machen sollen.

## Teste die Freigabe für den falschen Lauf, bevor es Benutzer tun

Du kannst diesen Fehler ohne Red-Team und ohne Produktionsausfall testen. Führe zwei Instanzen desselben Agent-Clients im selben Workspace aus und bitte sie, ähnliche geschützte Aufrufe zu machen. Der Test ist nur erfolgreich, wenn ein Prüfer jede Anfrage in einer vollen Warteschlange korrekt identifizieren kann.

Verwende diese Übung:

1. Starte Lauf A mit der Aufgabenbezeichnung «Fehlgeschlagenen Staging-Build untersuchen».
2. Starte Lauf B mit der Aufgabenbezeichnung «Staging-Release-Eintrag veröffentlichen».
3. Lass beide Läufe innerhalb weniger Sekunden dieselben Zugangsdaten anfordern.
4. Lass ihre ersten Anfragen ähnlich sein, etwa zwei Aufrufe an denselben API-Ursprung.
5. Verändere eine Aktion so, dass ihre Freigabe für den anderen Lauf in einer Testumgebung eine sichtbare, unerwünschte Folge hätte.

Bitte anschließend eine Person, die die Oberfläche nicht gebaut hat, nur die Anfrage von Lauf B freizugeben. Sage nicht anhand der Position in der Warteschlange, welche Karte B ist. Beobachte, worauf sie sich stützt. Verlässt sie sich auf Zeitstempel, Kartenreihenfolge oder die Erinnerung daran, welches Terminal sie zuerst geöffnet hat, ist die Oberfläche gescheitert. Kann sie Prozessautorität, Sitzungs-ID, Aufgabe, Ziel und Aktion nennen, ohne einen separaten Bildschirm zu öffnen, hast du einen brauchbaren Ausgangspunkt.

Teste auch das Verhalten veralteter Freigaben. Erzeuge eine Karte für Lauf A, beende A, starte B und klicke auf die alte Karte. Das System muss den Klick ablehnen und erklären, dass die Anfrage nicht mehr aktiv ist. Wiederhole den Test, nachdem du einen Request-Body oder ein SSH-Argument nach der Prüfung geändert hast. Das System muss eine neue Freigabe verlangen, statt die alte auf die veränderte Aktion anzuwenden.

Teste kollidierende Namen. Zwei Aufgaben können «CI reparieren» heißen. Zwei Repositories können denselben Verzeichnisnamen haben. Zwei Branches können dieselbe Release-Nummer verwenden. Freundlicher Text hilft Menschen, aber das vollständige Design muss auch funktionieren, wenn der freundliche Text mehrdeutig ist.

Sallyports sitzungsbezogene Autorisierung bietet einen natürlichen Ort, um diese Grenze festzulegen: Der erste Aufruf eines neuen Agent-Prozesses identifiziert den Lauf für die Freigabe, während aufrufbezogene Schlüssel für jede Nutzung eine separate Freigabe verlangen können. Lass Sitzungsbezeichnung und Prozessautorität sichtbar, wenn diese Kontrollen erscheinen. Sonst fallen parallele Läufe wieder zu einem undeutlichen «Agenten» zusammen.

## Das Audit-Protokoll muss die Freigabeentscheidung reproduzieren können

Ein Audit-Protokoll ist nur dann nützlich, wenn es nachträglich beantworten kann, was der Prüfer gesehen hat und was das System ausgeführt hat. «Benutzer hat API-Zugriff freigegeben» reicht nicht. Die zentrale Frage bleibt offen: Zugriff für welchen Lauf, für welche Aktion und mit welchem angezeigten Kontext?

Für jede Entscheidung müssen unveränderliche Kennungen und Darstellungsfakten gespeichert werden:

```json
{
  "event": "approval_granted",
  "approval_id": "apr_K9H2D7LQ",
  "session_id": "ses_7TQ4N8M2KDXP6R9V",
  "process_identity": "agent-cli / Example Engineering (Team ABCD1234)",
  "task_label": "Prepare the staging release notes",
  "action_digest": "sha256:2a13c4e0...",
  "displayed_action": "POST api.example.internal/v1/releases",
  "decision_scope": "once",
  "recorded_at": "2026-07-22T16:44:03Z"
}
```

Speichere den kanonischen Aktionseintrag separat oder daneben, mit angemessener Verschlüsselung und Zugriffskontrolle. Der Audit-Eintrag sollte einem Ermittler zeigen, was auf der Karte stand. Der kanonische Eintrag sollte beweisen, welche Bytes und welches Ziel die vertrauenswürdige Komponente verwendet hat. Weichen beide voneinander ab, ist das ein Sicherheitsmangel und kein bloßes Protokollierungsdetail.

Eine verkettete Hash-Kette hilft, nachträgliche Änderungen an der Historie zu erkennen, repariert aber keinen vagen Ereignisinhalt. Du kannst kryptografisch beweisen, dass «Freigabe erteilt» nicht verändert wurde, und trotzdem nicht wissen, welche Anfrage sie erhalten hat. Integrität und Zuordnung lösen unterschiedliche Probleme. Du brauchst beides.

Sallyport-Projekte führen Sitzungs- und Einzelaufrufdaten gemeinsam in einem verschlüsselten, hashverketteten Audit-Protokoll. Der Befehl `sp audit verify` prüft die Kette offline über den Ciphertext. Das ist nützlich, weil Prüfer nachweisen können, dass das Protokoll nicht verändert wurde, ohne gespeicherte Geheimnisse beim Prüfen offenzulegen.

Der abschließende Designtest ist einfach. Wähle eine abgeschlossene Aktion und gehe rückwärts: Kann ein Ermittler Prozess, konkrete Sitzung, damals angezeigte Aufgabenbezeichnung, exakt geprüfte Anfrage, Umfang der Entscheidung und Ergebnis bestimmen? Gehe anschließend von einer Sitzung vorwärts: Sind jede ausstehende, abgelehnte, freigegebene, stornierte und ausgeführte Aktion in der richtigen Reihenfolge sichtbar? Erfordert eine der beiden Richtungen Vermutungen, lädt die Freigabewarteschlange weiterhin zum Fehler mit dem falschen Lauf ein.

Parallele Agenten werden Freigabewarteschlangen alltäglich machen. Die Lösung besteht nicht darin, Prüfer mit noch mehr Karten zu überladen oder ihnen eine umfassende «Alles erlauben»-Kontrolle zu geben. Gib jedem laufenden Prozess eine dauerhafte Sitzungsidentität, platziere sie neben der Aktion, wo Menschen tatsächlich hinschauen, und binde jeden Klick an die Anfrage, die der Prüfer geprüft hat. So bedeutet eine Freigabe auch dann etwas, wenn mehrere Agenten gleichzeitig aktiv sind.
