# Health-Checks für ein lokales Agenten-Aktions-Gateway

Ein lokales Aktions-Gateway ist erst dann gesund, wenn es die falsche Aktion ablehnen, die richtige kontrollierte Aktion ausführen und einen auch bei einer Prüfung belastbaren Nachweis hinterlassen kann. Ein grüner Prozessmonitor beweist davon fast nichts. Er zeigt nur, dass etwas eine PID hat. Ob der Vault gesperrt ist, ein Agent das Gateway erreicht, eingefügte Zugangsdaten noch funktionieren oder das Audit-Log den Aufruf aufgezeichnet hat, sagt er nicht.

Dieser Unterschied ist bei Sallyport wichtig, weil App, Vault-Sperre, Autorisierungsentscheidung, externe Aktion und verschlüsseltes Audit-Log getrennte Fehlerstellen sind. Wer sie als ein allgemeines «Health»-Signal behandelt, erhält die gefährlichste Art von Überwachung: Sie bleibt grün, obwohl die benötigte Kontrolle nicht mehr funktioniert.

Baue dafür eine kleine Abnahmesuite statt einer Sammlung von Portprüfungen. Die Suite sollte harmlose Canary-Ziele verwenden, nicht geheime Nachweise zurückgeben und einen gesperrten Vault korrekt einordnen. Wenn eine Person den Vault mit Touch ID entsperren muss, sollte die Überwachung diesen Zustand klar melden, statt ihn zu umgehen.

## Eine laufende App ist nur die erste Voraussetzung

Ein Verfügbarkeitscheck sollte eine eng begrenzte Frage beantworten: Kann der lokale Mac die Gateway-App starten und weiter ausführen? Er sollte nicht so tun, als würde ein laufender Prozess beweisen, dass externe Aktionen funktionieren.

Bei einer Menüleisten-App beginnst du mit einer lokalen Prüfung, die ein Supervisor ohne Zugangsdaten ausführen kann. Der genaue Prozessname und der Installationsort können sich je nach Version ändern. Halte diese Werte deshalb in einer einzigen lokalen Konfigurationsdatei, statt sie über mehrere Skripte zu verteilen. Ein einfacher Shell-Check kann so aussehen:

```sh
#!/bin/sh
set -eu

APP_NAME="Sallyport"

if ! pgrep -x "$APP_NAME" >/dev/null 2>&1; then
  open -a "$APP_NAME"
  sleep 2
fi

if pgrep -x "$APP_NAME" >/dev/null 2>&1; then
  printf 'app=ready\n'
  exit 0
fi

printf 'app=unavailable\n' >&2
exit 2
```

Die Aussage dieses Checks ist bewusst bescheiden. `open -a` bittet macOS, eine Anwendung zu starten, und `pgrep` prüft danach, ob ein Prozess vorhanden ist. Das beweist nicht, dass die App vollständig initialisiert wurde, der Vault auf eine Anfrage antworten kann oder der MCP-Shim einen Client akzeptiert. Apple beschreibt Launch Services als Systemschnittstelle zum Starten und Aktivieren von Anwendungen. Deshalb ist der Start über das Betriebssystem besser, als einen Bundle-Pfad fest einzuprogrammieren.

Halte die Ausgabe strukturiert und unspektakulär. `app=ready` reicht für einen Scheduler. Schreibe keine `ps`-Ausgabe in ein zentrales Log, wo Befehlsargumente, Benutzernamen oder Details zu anderen Prozessen dauerhaft für Unordnung sorgen.

Ein Prozess kann existieren und trotzdem festhängen. Er kann auch fehlen, weil der Mac schläft, niemand angemeldet ist oder nach einem Update neu startet. Deine Alarmregel braucht für solche erwartbaren Zustände eine Kulanzzeit. Ein Health-Check, der bei jedem Zuklappen eines Laptops jemanden alarmiert, wird irgendwann deaktiviert und hilft dann auch bei einem echten Fehler nicht mehr.

Das sinnvolle Verfügbarkeitssignal ist daher lokal und begrenzt: Die App wurde gestartet, blieb nach einer kurzen Einpendelzeit vorhanden und ein MCP-Client kann eine Sitzung beginnen. Der letzte Teil gehört in einen eigenen Check, weil er eine andere Grenze prüft.

## Der Vault-Zustand muss ein eigener Ergebniswert sein

Ein gesperrter Vault ist gesund, wenn er Aktionen ablehnt. Diesen Zustand als Ausfall zu bezeichnen, verwechselt Sicherheitsverhalten mit einem Dienstausfall.

Sallyports Vault-Sperre ist absolut: Solange der Vault gesperrt ist, wird jede Aktion abgelehnt. Auf unterstützter macOS-Hardware verwendet die Vault-Sperre Secure Enclave und Touch ID. Ein Check muss diese Regel bewahren. Schreibe kein Skript, das Passwörter in eine Benutzeroberfläche eingibt, ein biometrisches Umgehungstoken speichert oder eine entsperrte Desktop-Sitzung als Beweis dafür behandelt, dass der Vault entsperrt werden sollte.

Verwende vier Ergebniszustände statt eines Wahrheitswerts:

- `ready`: Die App ist verfügbar, der Vault ist entsperrt und kontrollierte Checks dürfen laufen.
- `locked`: Die App ist verfügbar, aber der Vault lehnt Aktionen korrekt ab.
- `denied-unexpectedly`: Der Vault ist entsperrt, trotzdem wurde die vorgesehene Canary-Aktion abgelehnt.
- `unavailable`: Die App oder ihr lokaler MCP-Pfad kann nicht antworten.

Diese Begriffe verhindern einen häufigen Betriebsfehler. Teams planen oft nachts einen Check mit Zugangsdaten, sehen nach dem Sperren des Bildschirms Fehler und schwächen das System so lange, bis es sich selbst entsperren kann. Sie haben die Überwachung nicht repariert. Sie haben die menschliche Entscheidung entfernt, die der Vault ausdrücklich voraussetzt.

Das praktische Muster besteht aus zwei Teilen. Ein unbeaufsichtigter Job protokolliert die App-Verfügbarkeit und die Ablehnung durch den gesperrten Vault. Eine Person oder eine kontrollierte Arbeitsplatzsitzung mit bereits erteilter menschlicher Freigabe startet die Checks mit Zugangsdaten nach dem Entsperren. Halte den Grund in der Ausgabe des Laufs fest:

```json
{
  "run_id": "hc-2026-07-22T141501Z-8f29",
  "app": "ready",
  "vault": "locked",
  "http": "skipped",
  "ssh": "skipped",
  "audit": "verified",
  "reason": "credentialed checks require an unlocked vault"
}
```

Die Lauf-ID ist kein Geheimnis. Sie gibt den Verantwortlichen einen stabilen Wert, den sie später mit dem Aktivitätsdatensatz vergleichen können. Verwende keinen Benutzernamen, keine Seriennummer des Geräts, keine Endpunkt-URL und keine Bezeichnung einer Zugangsdaten als Lauf-ID.

Die Autorisierung pro Sitzung und die Freigabe pro Aufruf brauchen ebenfalls eine eigene Behandlung. Ein neuer Agent-Prozess kann eine Sitzungsfreigabe benötigen, und eine Zugangsdaten kann für jede Verwendung eine Freigabe verlangen. Das ist erwartetes Verhalten und kein flakey Test. Dein Runner sollte angeben, ob er für eine bereits freigegebene Sitzung ausgelegt ist oder ob eine Person jeden Aufruf freigibt. Ein stiller Timeout sagt der nächsten untersuchenden Person nichts.

## Verwende Canary-Ziele, die das Einfügen von Zugangsdaten nachweisen

Ein HTTP-Check sollte einen Endpunkt aufrufen, der für die Prüfung einer bestimmten Canary-Zugangsdaten vorgesehen ist und ein festes, nicht geheimes Ergebnis zurückgibt. Der Aufruf einer öffentlichen URL beweist nur, dass das Netzwerk funktioniert. Er zeigt nicht, ob das Gateway die vorgesehene Zugangsdaten ausgewählt, in den richtigen Header eingefügt oder vom Agenten ferngehalten hat.

Richte einen kleinen Dienst ein, der genau einen Pfad, eine Methode und eine Form von Zugangsdaten akzeptiert. Speichere das erwartete Canary-Geheimnis auf der Serverseite. Speichere dasselbe Canary-Geheimnis im Vault des Gateways. Der Client, der die Aktion auslöst, darf das Geheimnis nie erhalten, und der Dienst darf es nie zurückgeben.

Der Antwortvertrag kann so klein sein:

```json
{
  "check": "agent-gateway-http",
  "result": "ok",
  "request_id": "7d7a0f3c"
}
```

Der Dienst sollte `401` zurückgeben, wenn die Zugangsdaten fehlen oder falsch sind, `405` bei der falschen Methode und nur dann `200`, wenn die erwartete Zugangsdaten angekommen ist. Erzeuge `request_id` auf dem Dienst und halte den Wert opak. Leite ihn nicht aus dem Authorization-Header oder irgendeinem Teil der eingehenden Anfrage ab.

Verwende eine eigene Route wie `/agent-gateway-canary`. Hänge den Check nicht an einen bestehenden Produktionsendpunkt. Produktionsendpunkte sammeln mit der Zeit Verhalten an: Rate Limits, Weiterleitungen, Inhaltsverhandlung, Caching-Regeln, Abrechnungseffekte und Berechtigungsänderungen. Eine Canary-Route kann bewusst langweilig bleiben.

RFC 9110 definiert die Semantik von Request-Methoden und klassifiziert GET, HEAD, OPTIONS und TRACE als sichere Methoden. In HTTP bedeutet sicher jedoch, dass die angeforderte Aktion den vorgesehenen Zustand der Ressource nicht verändern sollte. Das heißt nicht, dass der Aufruf für dein Konto, deine Logs, Kontingente oder nachgelagerte Prozesse harmlos ist. Eine API kann einen GET protokollieren, einen Request berechnen oder durch eine schlechte Implementierung einen Seiteneffekt auslösen. Baue eine Route, deren Verhalten auf dem Server du prüfen kannst, statt einem vertrauten Verb zu vertrauen.

Eine häufige schlechte Empfehlung lautet, `curl` mit einem Produktions-API-Token als Health-Check zu verwenden. Das ist beliebt, weil es nur eine Zeile braucht. Es ist falsch, weil Shell-Historie, Prozessinspektion, CI-Logs und Fehlermeldungen zu viele Stellen schaffen, an denen ein Bearer-Token auftauchen kann. Außerdem umgeht es das Verhalten, das du eigentlich testen musst, wenn das Gateway die Zugangsdaten normalerweise selbst einfügt.

Dein Runner sollte das Gateway über denselben MCP-Pfad aufrufen, den ein Agent verwendet. Erfinde keinen zusätzlichen HTTP-Client als Hintertür für den Check. Halte den transportspezifischen Aufruf hinter einem lokalen Adapter verborgen, weil sich Toolnamen und Anfrageformen ändern können. Der Adapter nimmt eine logische Aktion entgegen, bittet das MCP-verbundene Gateway um ihre Ausführung und gibt nur das normalisierte Ergebnis aus.

```json
{
  "action": "http_canary",
  "target": "canary-api",
  "method": "POST",
  "path": "/agent-gateway-canary",
  "expected_status": 200,
  "expected_check": "agent-gateway-http"
}
```

Der Adapter muss bei Fehlern redigieren. Er darf `http_status=401`, `transport_error=timeout` oder `response_schema=invalid` melden. Er darf jedoch keine ausgehenden Header, keinen Request-Body, keine vollständige URL mit Abfrageparametern und keine rohe Antwort ausgeben, sofern du diese Daten nicht zuvor als sicher geprüft hast.

## Ein erfolgreicher HTTP-Aufruf muss die vorgesehene Aktion beweisen

Ein `200` allein ist ein schwacher Nachweis. Der Check muss die Antwort des Dienstes, die Methode und die Identität des Ziels prüfen, damit eine Weiterleitung, eine Proxy-Seite oder ein veraltetes Testobjekt nicht zu einem falschen Erfolg führt.

Die Canary-Antwort sollte den Test identifizieren, ohne eine Zugangsdaten zu identifizieren. Vergleiche einige exakte Felder:

```sh
status=200
check=agent-gateway-http
result=ok
request_id=7d7a0f3c
```

Der Checker sollte jede syntaktisch gültige `request_id` akzeptieren und sie zusammen mit der Lauf-ID speichern. Er sollte ein fehlendes Feld, einen Erfolgsstatus im Inhalt bei einem Status außerhalb von 2xx und einen unerwarteten Inhaltstyp ablehnen. Ein Captive Portal, eine Fehlerseite eines Unternehmensproxys oder ein falsch gesetzter DNS-Eintrag liefert oft eine gültige HTTP-Antwort. Das ist ein erfolgreicher Transport, aber keine erfolgreiche Aktion.

Die curl-Dokumentation weist auf einen ähnlichen Punkt hin: Ohne `--fail` oder `--fail-with-body` behandelt curl einen HTTP-Status wie 404 oder 401 nicht als Befehlsfehler. Für ein allgemeines Übertragungsprogramm ist dieses Verhalten korrekt. Es führt jedoch zu Problemen, wenn ein Monitor nur den Exit-Status von curl betrachtet. Wenn dein Adapter curl intern verwendet, erfasse sowohl das Prozessergebnis als auch den HTTP-Status und entscheide anhand deines ausdrücklichen Vertrags über den Erfolg.

Lasse einen Check Weiterleitungen nicht automatisch folgen, außer sie gehören ausdrücklich zum vorgesehenen Endpunktdesign. Eine Weiterleitung kann den Canary-Aufruf auf eine Anmeldeseite schicken, die `200` zurückgibt, oder auf einen anderen Host, den du nicht kontaktieren wolltest. Lege den HTTPS-Ursprung in der Konfiguration fest, prüfe das Zertifikat über den normalen Client-Stack und protokolliere die Identität des letzten Peers nur dann, wenn daraus keine sensiblen Netzwerkdetails hervorgehen.

Timeouts brauchen eigene Bezeichnungen. Ein DNS-Fehler, eine TCP-Ablehnung, ein fehlgeschlagener TLS-Check, eine Gateway-Ablehnung, ein Upstream-`401`, ein Upstream-`500` und eine nicht passende Antwort haben unterschiedliche Verantwortliche. Wenn der Runner alle Fälle als `http=failed` bezeichnet, gehen die ersten zehn Minuten jedes Vorfalls dafür verloren, herauszufinden, an welcher Stelle die Anfrage angehalten wurde.

Ein brauchbarer Fehlerdatensatz sieht so aus:

```json
{
  "run_id": "hc-2026-07-22T141501Z-8f29",
  "check": "http_canary",
  "outcome": "failed",
  "stage": "upstream_response",
  "http_status": 401,
  "request_id": null,
  "secret_material": "redacted"
}
```

Die Zeile `secret_material` erinnert die lesende Person nur daran, dass Inhalte entfernt wurden. Sie beweist nicht, dass die Redigierung funktioniert hat. Beweise das mit Tests: Lass den Canary das Geheimnis absichtlich ablehnen, erfasse stdout und stderr des Runners und suche in diesen Dateien nach dem Testgeheimnis. Es darf nicht auftauchen. Wiederhole den Test mit fehlerhaftem JSON, einem Timeout, einem TLS-Fehler und einem Tool-Fehler auf Agentenseite. Gerade Fehlerpfade lassen Geheimnisse oft entweichen.

## SSH braucht ein abgeschirmtes Ziel, keine Login-Shell

Ein SSH-Health-Check sollte Authentifizierung und Befehlsausführung gegen ein eigenes Konto nachweisen, dessen Server keine beliebigen Befehle ausführt. Eine erfolgreiche Verbindung zu einem allgemeinen Administrationshost beweist in die falsche Richtung zu viel: Die Zugangsdaten für den Health-Check erhalten dabei eine brauchbare Shell.

Erstelle auf einem kontrollierten Testhost ein eigenes Konto wie `gateway-health`. Gib ihm in `authorized_keys` oder über eine gleichwertige serverseitige Einschränkung einen erzwungenen Befehl. Dieser Befehl sollte den ursprünglichen Befehl ignorieren, einen Zeitstempel und eine opake Lauf-ID in eine lokale Audit-Datei schreiben und anschließend eine konstante Antwort zurückgeben.

Ein beispielhafter Eintrag in `authorized_keys` sieht so aus:

```text
command="/usr/local/libexec/gateway-health",no-port-forwarding,no-agent-forwarding,no-X11-forwarding,no-pty ssh-ed25519 AAAA... gateway-health
```

Der öffentliche Schlüssel gehört zur Canary-Identität des Gateways. Der private Schlüssel bleibt im Vault. Der Text `AAAA...` ist hier absichtlich unvollständig, weil du dein eigenes Schlüsselmaterial erzeugen musst, statt ein Beispiel in eine Produktionsdatei zu kopieren.

Der Serverbefehl sollte `$SSH_ORIGINAL_COMMAND`, Umgebungsvariablen und Authentifizierungsdetails nicht ausgeben. Er kann ein festes Format zurückgeben:

```json
{"check":"agent-gateway-ssh","result":"ok","receipt":"c2b91a"}
```

Wenn du für die Zuordnung eine Lauf-ID brauchst, übergib einen opaken Token im gesendeten Befehl und lasse den erzwungenen Befehl ein enges Format prüfen, etwa eine festgelegte Anzahl hexadezimaler Zeichen. Akzeptiere niemals eine beliebige Zeichenfolge und schreibe sie in einen Shell-Befehl, einen Dateinamen oder eine Logzeile. Noch besser ist es, wenn der Server den Beleg selbst erzeugt und die Datensätze bei der Untersuchung über ein Zeitfenster zusammengeführt werden.

Der Check sollte fehlschlagen, wenn der Server eine interaktive Shell, Portweiterleitung, ein TTY oder einen anderen Befehl als den erzwungenen zulässt. Das sind Konfigurationsrückschritte. Sie verdienen eine andere Schwere als ein gewöhnlicher Netzwerk-Timeout, weil sie die Gefährdung der Canary-Zugangsdaten verändern.

Verwende nicht die SSH-Identität, die für Deployments eingesetzt wird. Die Wiederverwendung macht die Einrichtung einfacher, verwandelt einen Fehler der Überwachung aber in ein weitreichendes Zugriffsproblem. Eine Health-Zugangsdaten sollte genau eine Aufgabe, ein Zielkonto und keine weiteren Berechtigungen haben, außer den Beleg zu erzeugen.

Sallyport sendet SSH über seinen zustandslosen `sp-ssh`-Helfer. Dein Test sollte deshalb über den normalen Gateway-Aktionspfad laufen, statt einen lokalen privaten Schlüssel mit OpenSSH aufzurufen. Andernfalls hast du nur den Host und das Konto geprüft. Die Zugangsdaten-Grenze, deren Funktion nachgewiesen werden muss, hast du übersprungen.

## Die Audit-Prüfung ist eine eigene Aussage

Eine erfolgreiche Canary-Aktion und ein gültiger Audit-Trail sind zwei verschiedene Aussagen. Prüfe beide.

Der Aktivitätsdatensatz zeigt, dass das Gateway eine einzelne Aktion aufgezeichnet hat. Der Sitzungsdatensatz informiert über den Agentenlauf und bietet eine Möglichkeit, diesen Lauf zu widerrufen. Keiner von beiden ersetzt die Prüfung der entfernten Wirkung, denn eine Anfrage kann vor einem Upstream-Fehler protokolliert werden. Umgekehrt kann ein entferntes System eine Anfrage erhalten, während der lokale Protokollierungspfad im falschen Moment ausfällt. Du brauchst Korrelation statt Wunschdenken.

Sammle für jede erfolgreiche HTTP- oder SSH-Aktion drei nicht geheime Nachweise:

- die vom Runner erzeugte Health-Lauf-ID;
- den opaken Beleg oder die Request-ID des Canary-Dienstes;
- den lokalen Aktionszeitpunkt in UTC.

Prüfe anschließend das Aktivitätsjournal auf sicher speicherbare Metadaten der Aktion, etwa Kanal, Aktionsergebnis, Zielalias und Zeit. Erwarte dort keine Zugangsdaten im Klartext. Das sollte auch nicht so sein. Verlange auch nicht, dass das Journal den Inhalt der entfernten Antwort reproduziert. Der Beleg gehört zum entfernten Canary-System und nicht in den Secret Store des Gateways.

Sallyport erzeugt seine Sessions- und Aktivitätsjournale aus einem schreibgeschützten, verschlüsselten und hashverketteten Audit-Log. Führe die Offline-Integritätsprüfung als unabhängigen Teil der Suite aus:

```sh
sp audit verify
```

Ein erfolgreicher Befehl sollte als `audit=verified` aufgezeichnet werden. Ein Ergebnis ungleich null ist so lange ein Integritätsvorfall, bis das Gegenteil bewiesen ist. Diese Prüfung benötigt den Vault-Schlüssel nicht und eignet sich deshalb für einen unbeaufsichtigten lokalen Check, auch wenn der Vault gesperrt ist.

Reduziere die Audit-Prüfung nicht auf «Eine Logdatei existiert». Das Vorhandensein einer Datei erkennt fast nichts. Eine abgeschnittene Datei, ersetzte Einträge, eine beschädigte Kette oder ein Writer, der nach dem Start nicht weitergeschrieben hat, können alle neben einem im Finder normal aussehenden Pfad bestehen.

Ein weiterer leicht zu übersehender Fehler ist, nur die Gültigkeit der Audit-Kette zu prüfen. Eine Kette kann gültig sein und trotzdem den erwarteten Eintrag nicht enthalten, wenn das Gateway die Aktion nie versucht hat. Kombiniere die Kettenprüfung nach jeder Canary-Aktion mit einer Prüfung auf das Vorhandensein des Ereignisses. Lege für die lokale Projektion ein sinnvolles Zeitfenster fest und melde eine Verzögerung getrennt von einem fehlenden Ereignis. Eine verzögerte Aktualisierung des Journals kann eine Untersuchung erfordern, ist aber nicht dasselbe wie ein fehlgeschriebener Eintrag.

## Halte den Runner außerhalb der von ihm geprüften Vertrauensgrenze

Der Health-Runner sollte Aktionen koordinieren und Nachweise bewerten. Er sollte keine Zugangsdaten besitzen, Vault-Dateien auswerten oder zustandsbehaftete Anwendungsdaten mit Geheimnissen lesen.

Ein praktischer Aufbau hat vier Komponenten:

1. Ein lokaler Scheduler startet einen kleinen Runner unter einem eigenen macOS-Konto.
2. Der Runner prüft, ob die App vorhanden ist, und ruft einen lokalen MCP-Adapter auf.
3. Der Adapter fordert benannte Canary-Aktionen über das Gateway an und gibt redigierte strukturierte Ergebnisse zurück.
4. Der Runner prüft die Audit-Integrität und schreibt einen kurzen Bericht in ein geschütztes lokales Verzeichnis.

Das eigene Konto sollte keinen Zugriff auf die Datendateien des Vaults haben. Apple legt nicht sandboxte macOS-Anwendungsdaten unter dem Verzeichnis `~/Library/Application Support` des aktuellen Benutzers ab. Ein Monitor sollte jedoch nicht voraussetzen, dass er diese Dateien untersuchen kann oder soll. Der Check braucht Verhalten, keine Kopie des Vault-Inhalts.

Halte die Konfiguration deklarativ und frei von Geheimnissen. Dieses Beispiel liefert dem Runner genug Informationen, um Ergebnisse zu prüfen, ohne Zugangsdaten offenzulegen:

```yaml
checks:
  http_canary:
    target_alias: canary-api
    expected_status: 200
    expected_check: agent-gateway-http
    timeout_seconds: 10
  ssh_canary:
    target_alias: canary-ssh
    expected_check: agent-gateway-ssh
    timeout_seconds: 10
  audit:
    command: sp audit verify
    timeout_seconds: 15
```

Zielaliases sind wichtig. Ein Alias ist weniger sensibel als eine vollständige URL oder ein Hostname und zwingt dich, die Zielauswahl in der Gateway-Konfiguration ausdrücklich festzulegen. Wenn ein Operator einen Alias ändert, sollte der Aktionstest zeigen, dass vor dem stillen Test eines anderen Ziels eine Konfigurationsprüfung erforderlich ist.

Gib dem Runner nicht die Berechtigung, einen neuen Agentenprozess freizugeben. Die Autorisierung pro Sitzung ist aus gutem Grund standardmäßig aktiviert. Der erste Aufruf eines neuen Agentenprozesses zeigt in der Freigabekarte seine Codesignatur-Instanz an, und die Freigabe gilt nur für diesen Lauf. Wenn du geplante Checks nach der Freigabe durch eine Person brauchst, richte einen dauerhaft laufenden, geprüften Health-Client ein. Wenn der Prozess endet, muss der nächste Lauf erneut nachfragen.

Das ist etwas weniger bequem als ein verstecktes, immer freigegebenes Automationskonto. Es verhindert aber auch, dass eine neue ausführbare Datei allein dadurch Berechtigungen erhält, dass sie die Befehlszeile des Health-Checks kopiert.

## Ein fehlgeschlagener Check braucht eine brauchbare Diagnose

Die meisten Fehler bei Gateway-Health-Checks sind gewöhnliche Konfigurationsabweichungen. Gefährlich wird, wie schnell Menschen darauf reagieren, indem sie Kontrollen schwächen, statt die fehlerhafte Grenze zu finden.

Betrachte eine realistische Abfolge. Die App läuft. Der Vault ist entsperrt. Der HTTP-Canary gibt `401` zurück. Der erste Impuls ist, das Canary-Token in eine Shell einzufügen und den Endpunkt direkt aufzurufen. Tu das nicht. Es beweist zwar, dass das Token funktioniert, umgeht aber den Vault und schafft einen neuen Weg für das Entweichen eines Geheimnisses.

Arbeite stattdessen die Nachweise in dieser Reihenfolge durch:

1. Bestätige, dass der lokale MCP-Adapter das Gateway erreicht und ein Aktionsergebnis erhalten hat, statt vor der Übermittlung in einen Timeout zu laufen.
2. Bestätige, dass der Zielalias weiterhin die vorgesehene gespeicherte Zugangsdaten und die richtige Endpunktkonfiguration auswählt.
3. Prüfe die Logs des Canary-Dienstes auf opake Request-ID, Methode, Route und Ablehnungsgrund. Protokolliere nicht den empfangenen Authorization-Wert.
4. Suche im Aktivitätsjournal nach dem passenden Aktionsversuch und prüfe die Audit-Kette mit `sp audit verify`.
5. Tausche die Canary-Zugangsdaten aus, wenn die Konfigurationsprüfung zeigt, dass sich der erwartete Wert geändert hat oder offengelegt worden sein könnte.

Diese Reihenfolge trennt vier Fehler, die sonst gleich aussehen: eine falsche Zielzuordnung, ein widerrufenes oder ausgetauschtes Geheimnis, einen Fehler beim Einfügen durch das Gateway und eine Änderung an der Konfiguration des Upstream-Dienstes. Sie vermeidet außerdem den bekannten selbst verursachten Vorfall, bei dem ein Operator ein Geheimnis «testet» und es anschließend in der Shell-Historie, einem Scrollback-Puffer oder einem Support-Bundle wiederfindet.

Ordne die Schwere danach ein, welche Kontrolle ausgefallen ist. Eine nicht verfügbare App ist ein Verfügbarkeitsproblem. Ein gesperrter Vault, der eine Aktion ablehnt, ist informativ, sofern kein geplanter freigegebener Check erwartet wurde. Eine erfolgreiche Canary-Aktion bei gleichzeitig als gesperrt gemeldetem Vault ist ein Sicherheitsvorfall. Eine beschädigte Audit-Kette ist ebenfalls ein Sicherheitsvorfall, auch wenn beide Canary-Ziele weiterhin Erfolg melden.

Verstecke diese Kategorien nicht hinter einem einzigen roten oder grünen Symbol. Wer `vault=locked`, `audit=verified` und `http=skipped` sieht, weiß genau, was zu tun ist. Wer `health=warning` sieht, beginnt zu raten.

## Der kleinste sinnvolle Zeitplan hat zwei Spuren

Führe nicht geheime Checks häufig aus und danach die Canary-Aktionen mit Zugangsdaten sparsam und bewusst. Die beiden Spuren erzeugen weniger Rauschen und liefern bessere Nachweise.

Die unbeaufsichtigte Spur kann immer dann laufen, wenn der Mac voraussichtlich aktiv ist. Sie prüft, ob die App vorhanden ist, ob ein gesperrter Vault eine Aktion ablehnt, ob der MCP-Pfad eine klassifizierte Antwort liefern kann und ob `sp audit verify` erfolgreich ist. Keiner dieser Checks sollte das Extrahieren einer Zugangsdaten oder das Entsperren des Vaults erfordern.

Die Spur mit Zugangsdaten läuft, nachdem eine Person den Vault entsperrt und bei Bedarf die Health-Client-Sitzung freigegeben hat. Sie führt eine HTTP-Canary-Aktion und eine SSH-Canary-Aktion aus, bestätigt die entfernten Belege, prüft die entsprechenden lokalen Aktivitätseinträge und verifiziert die Audit-Kette erneut. Wähle ein moderates Intervall. Jede Aktion mit Zugangsdaten wird zu einem Audit-Ereignis und einem Ereignis beim entfernten Dienst. Ein Check jede Minute erzeugt daher Rauschen, ohne viel mehr Sicherheit zu geben.

Führe die Spur mit Zugangsdaten nach Änderungen an der Konfiguration von Zugangsdaten, Zielaliases, Agenten-Tools, macOS-Berechtigungen, Netzwerkregeln oder der Gateway-App aus. So werden die Änderungen geprüft, die die Aktionsausführung am ehesten beeinträchtigen. Außerdem erhält die prüfende Person einen klaren Vergleich zwischen vorher und nachher.

Der Maßstab ist einfach: Eine Health-Suite muss die Kontrollen nachweisen, auf die du dich verlassen willst. Wenn sie nur zeigen kann, dass sich ein App-Symbol noch in der Menüleiste befindet, nenne sie einen Verfügbarkeitscheck und belasse es dabei. Nenne das nicht den Beweis, dass autonome Agenten sicher handeln können.
