Beweisen Ihre Tests auf Geheimnislecks bei Agenten überhaupt etwas?
Tests auf Geheimnislecks bei Agenten sollten mehr beweisen als eine saubere Chat-Ausgabe. Erstellen Sie Canary-Prüfungen für Umgebungen, Argumente, Protokolle, Fehler und Abstürze.

Ein Agent muss ein Token nicht ausgeben, um es erhalten zu haben. Sobald ein Bearer-Token in seine Umgebung, Befehlszeile, Tool-Nutzdaten, sein Transkript, einen untergeordneten Prozess oder ein Absturzartefakt gelangt, ist die Grenze bereits verletzt. Eine höfliche Modellantwort macht diesen Fehler nicht rückgängig.
Die relevante Frage lautet nicht: «Hat der Agent das Geheimnis vermieden zu wiederholen?» Sie lautet: «Können wir echte Aktionen über ein Test-Gateway ausführen, jedes Artefakt sammeln, das auf der Agentenseite entstehen kann, und zeigen, dass keines davon eine eindeutige, funktionsfähige Zugangsdaten enthält?» Diese Aussage ist eng genug, um sie zu testen, und stark genug, um die Fehler zu finden, die später in der Produktion auftreten.
Verwenden Sie wegwerfbare Konten, Hosts und für jeden Lauf ein neues Canary. Speichern Sie das Geheimnis ausschließlich in der Gateway-Konfiguration. Lassen Sie den Agenten anschließend erfolgreiche HTTP- und SSH-Aktionen ausführen, lösen Sie absichtlich Fehler aus und prüfen Sie die Agentenseite so, als würden Sie mit einem Leck rechnen. Diese Haltung findet die unschönen Pfade.
Eine saubere Antwort beweist keine saubere Grenze
Ein Agent kann ein Geheimnis erhalten, ohne es je in natürlicher Sprache abzulegen. Häufig steckt dahinter eine Tool-Implementierung, die den Agenten auffordert, eine API selbst aufzurufen, und anschließend einen Authorization-Wert in die Tool-Eingabe schreibt. Ein anderer Fall ist ein Unterprozess, der API_TOKEN erbt, weil vor dem Start niemand seine Umgebung ersetzt hat. Ein dritter ist ein SSH-Helfer, der eine temporäre Identitätsdatei anlegt, die der Agent lesen kann.
Das sind unterschiedliche Fehler, haben aber dieselbe Folge: Der Agentenprozess verfügt über Material, mit dem er außerhalb des Gateways handeln kann. Danach beschreiben Freigabeaufforderungen und Prüfprotokolle nur noch einen Teil des Risikos. Der Agent kann das Geheimnis in ein Repository kopieren, an einen anderen Dienst senden oder in einem Transkript hinterlassen, das später jemand exportiert.
Halten Sie zwei Aussagen auseinander:
- Aktionsisolierung bedeutet, dass der Agent eine Operation anfordert und deren Ergebnis erhält, während eine andere Komponente die Zugangsdaten einfügt und die Netzwerk- oder SSH-Verbindung ausführt.
- Keine Übermittlung des Geheimnisses bedeutet, dass die Zugangsdaten und nutzbaren Ableitungen niemals in den Agentenprozess oder in Dateien gelangen, die der Agent lesen kann.
Teams testen oft die erste Aussage und setzen die zweite voraus. So kann ein Agent erfolgreich über ein Gateway eine Test-API aufrufen und trotzdem das Token in einem Debug-Feld oder einer geerbten Umgebungsvariablen erhalten.
Apples Dokumentation zu Process beschreibt die Vererbung eindeutig: Ein Unterprozess übernimmt seine Umgebung vom startenden Prozess, sofern dieser sie vor dem Start nicht verändert. Die APIs stellen dem Prozess außerdem Befehlsargumente und Umgebungsdaten zur Verfügung. Deshalb ist ein untergeordneter Prozess in diesem Test kein nebensächliches Implementierungsdetail, sondern ein weiterer Beobachtungspunkt.
Der Teststandard sollte so lauten:
Bei einem frischen Credential-Canary, der ausschließlich im Gateway gespeichert ist, kann ein Agent festgelegte HTTP- und SSH-Aktionen ausführen. Kein erreichbarer Agentenprozess, Transkript, Protokoll, Fehlerausgabe oder gesammeltes Diagnoseartefakt enthält jedoch das Canary oder eine identifizierbare Kodierung davon.
Versprechen Sie nicht, dass ein Blackbox-Test beweist, ein Geheimnis habe nie ein Byte Speicher im Gateway belegt. Das kann er nicht. Er bestätigt aber die Grenze, die für Nutzer zählt: Der Agent erhält über die von ihm kontrollierten Schnittstellen und Artefakte niemals nutzbare Zugangsdaten.
Eine Testzugangsdaten braucht Aufgabe und Fingerabdruck
Ein Test-Token sollte genau eine nützliche Funktion haben. Erstellen Sie für HTTP ein Testkonto, das nur einen Endpunkt wie GET /whoami oder POST /echo-action aufrufen kann und eine harmlose Konto-ID zurückgibt. Erstellen Sie für SSH ein eingeschränktes Konto auf einem wegwerfbaren Host und erlauben Sie wenige Befehle, die einen serverseitigen Ereigniseintrag schreiben.
Verwenden Sie kein Token wie test-token, nach dem Sie anschließend suchen. Kurze, vorhersehbare Markierungen erzeugen Fehlalarme und machen Prüfungen auf Kodierungen nutzlos. Erzeugen Sie für jeden Testlauf eine eigene Zeichenfolge. Beginnen Sie mit einem erkennbaren Präfix und fügen Sie Zufallsdaten an, damit Menschen einen Fehler erkennen können, ohne gewöhnliche Ausgabe mit einem Geheimnis zu verwechseln.
Zum Beispiel könnte ein Testgerüst ein Canary dieser Form erzeugen:
sallyport_probe_7M3jP4Fqk2rV9dN8xC5a
Diese Zeichenfolge ist der Zugangsdatenwert und keine Kennung, die an den Agenten ausgegeben wird. Verwenden Sie für Protokolle eine separate öffentliche Bezeichnung wie run-2026-07-22-ssh-04. Die Bezeichnung darf in Transkripten erscheinen, das Canary nicht.
Verwenden Sie für jeden Kanal und jeden Fehlerpfad eigene Canarys. Wenn Sie dasselbe HTTP-Token in jedem Test wiederverwenden, werden einzelne Lecks zu einer unübersichtlichen Menge veralteter Treffer. Außerdem lässt sich schwer feststellen, ob ein späteres Artefakt aus dem aktuellen Lauf oder einer früheren, unvollständigen Bereinigung stammt.
Ein praxistaugliches Fixture besteht aus vier Teilen:
- Einem HTTP-Testkonto, dessen Server nach erfolgreicher Authentifizierung eine feste, nicht geheime Antwort zurückgibt.
- Einem SSH-Testkonto, dessen erzwungener Befehl eine Aktions-ID protokolliert und eine feste Meldung zurückgibt.
- Einem Gateway-Eintrag mit dem frischen Canary, ohne zugängliche Kopie für den Agenten.
- Einem Manifest außerhalb des Artefaktverzeichnisses, das die Laufkennung den in diesem Lauf verwendeten Canarys zuordnet.
Das Manifest enthält sensibles Testmaterial. Speichern Sie es so, dass der Agent es nicht lesen kann, und löschen Sie die Canarys nach dem Lauf. Das Testkonto sollte diese Zugangsdaten nach der Bereinigung ablehnen, selbst wenn ein Fehler eine Kopie in einem lokalen Archiv hinterlassen hat.
Sallyport kann HTTP- und SSH-Testzugangsdaten im Gateway halten, während der Agent Aktionsresultate statt dieser Zugangsdaten erhält.
Der serverseitige Eintrag ist wichtig. Er beweist, dass eine Authentifizierung stattgefunden hat, und verhindert, dass ein fehlerhafter Test besteht, weil die Aktion nie ausgeführt wurde. Eine Antwort wie authenticated action accepted for run-2026-07-22-ssh-04 liefert dem Agenten genug Erfolgsnachweis, ohne seine Authentifizierungseingabe zu wiederholen.
Die Erfassung beim Start findet das Leck vor dem ersten Tool-Aufruf
Erfassen Sie die anfänglichen Argumente und die Umgebung des Agenten an der Startgrenze. Dieser Test findet Geheimnisse, die über Shell-Skripte, CI-Konfigurationen, Editor-Integrationen, Wrapper und bequeme Starter übergeben werden. Er findet auch einen typischen Fehler nach dem Einführen eines Gateways: Der alte Export von API_TOKEN bleibt bestehen, weil der neue Weg scheinbar funktioniert.
Starten Sie den Agenten über einen Wrapper, den Sie kontrollieren. Der Wrapper schreibt eine exakte Momentaufnahme seines Argumentvektors und seiner Umgebung in ein geschütztes Testverzeichnis und ersetzt sich anschließend durch die ausführbare Agentendatei. Das Ersetzen des Prozesses ist wichtig, weil dadurch die Werte erfasst werden, die tatsächlich an den Agentenstart übergeben wurden, statt sie nach dem Start mehrerer Schichten zu rekonstruieren.
Dieser kleine Python-Wrapper reicht für ein lokales Testgerüst:
#!/usr/bin/env python3
import json
import os
import pathlib
import sys
out = pathlib.Path(os.environ["PROBE_LAUNCH_RECORD"])
out.parent.mkdir(parents=True, exist_ok=True)
record = {
"argv": sys.argv[1:],
"environment": dict(os.environ),
}
out.write_text(json.dumps(record, sort_keys=True), encoding="utf-8")
os.execvp(sys.argv[1], sys.argv[1:])
Starten Sie ihn mit einer absichtlich sparsamen Umgebung. Übergeben Sie nur, was der Agent braucht, um seine ausführbare Datei, sein temporäres Verzeichnis, den MCP-Endpunkt oder den Stdio-Shim und den Pfad für den Wrapper-Eintrag zu finden. Übernehmen Sie nicht aus Gewohnheit die vollständige Shell-Umgebung des Entwicklers. Sie bringt unabhängige Zugangsdaten, Cloud-Konfigurationen, Token für Paketregistries und alte SSH-Einstellungen in den Test und kann ihn aus dem falschen Grund scheitern lassen.
Der erwartete Start-Eintrag hat diese Form:
{
"argv": ["agent-command", "run", "tests/agent-task.txt"],
"environment": {
"HOME": "/private/tmp/agent-home",
"PATH": "/usr/bin:/bin",
"PROBE_LAUNCH_RECORD": "/private/tmp/probe/launch.json"
}
}
Die genauen Pfade sind unwichtig. Entscheidend ist, dass der Eintrag weder das HTTP- oder SSH-Canary noch dessen Base64-, URL- oder JSON-Form enthält und auch nicht den Namen einer Datei mit einem privaten Schlüssel.
Maskieren Sie diesen Eintrag nicht, bevor der Scanner ihn sieht. Maskierung gehört in Berichte für Menschen. Der Rohdatensatz ist der Beleg. Wenn ein Release-Test nur eine bereinigte Version aufzeichnet, kann er beweisen, dass die Maskierung funktioniert, und gleichzeitig das Leck verbergen, das Sie finden wollten.
Eine Startmomentaufnahme zeigt nur, womit der Prozess begonnen hat. Sie zeigt nicht, ob ein späterer Tool-Aufruf ein Geheimnis in die Umgebung eines Unterprozesses oder eine temporäre Datei schreibt. Deshalb erzwingen die nächsten Tests Arbeit nach dem Start.
Untergeordnete Prozesse gehören zur Agentengrenze
Agenten starten häufig Formatter, Paketmanager, Testläufe, Git-Befehle, SSH-Clients und Skripte. Wenn der Agent einen Unterprozess starten kann, kann dieser seine Umgebung und Argumente auf die Festplatte schreiben, als Ausgabe zurückgeben oder an eine Netzwerkanfrage übergeben. Behandeln Sie jeden Unterprozess als vom Agenten erreichbar, solange es keinen belastbaren technischen Grund dagegen gibt.
Geben Sie dem Agenten eine harmlose Aufgabe, die nach einer Gateway-Aktion ein Prüfprogramm ausführt. Das Programm gibt seine eigenen Argumente und seine Umgebung in maschinenlesbarer Form aus. Als Nachfahre der Agentenlaufzeit beobachtet es die Werte, die diese Laufzeit zu diesem Zeitpunkt weitergibt.
Lassen Sie das Prüfprogramm in ein kontrolliertes Verzeichnis schreiben, statt einen riesigen Umgebungsdump in die Modellunterhaltung zurückzugeben. Sie testen auf ein Leck und laden es nicht absichtlich in das Transkript ein.
#!/usr/bin/env python3
import json
import os
import pathlib
import sys
path = pathlib.Path(os.environ["PROBE_CHILD_RECORD"])
path.parent.mkdir(parents=True, exist_ok=True)
path.write_text(
json.dumps(
{"argv": sys.argv, "environment": dict(os.environ)},
sort_keys=True,
),
encoding="utf-8",
)
print("child probe completed")
Lassen Sie den Agenten zuerst eine authentifizierte Aktion ausführen und anschließend das Prüfprogramm mit einem langweiligen Argument wie after-http-action starten. Wiederholen Sie die Sequenz nach SSH. Wenn die Gateway-Implementierung ein Zugangsdaten in eine Umgebungsvariable einfügt und dieser Helfer ein Nachfahre des Agenten wird, findet dieser Test das Leck.
Prüfen Sie Pfade in Argumenten gesondert. Entwickler wissen, dass Umgebungsvariablen leaken, aber Befehlsargumente sind oft gefährlicher, weil Prozessinspektion, Shell-Verlauf, Fehlerformatierung und Diagnosewerkzeuge sie aufzeichnen können. Apple dokumentiert, dass ein Prozess über CommandLine.arguments auf seine Argumente zugreifen kann und ProcessInfo sowohl Argumente als auch Umgebung bereitstellt. Zugangsdaten in argv sind damit für Code im Prozess unmittelbar sichtbar.
Akzeptieren Sie ein Argument wie --token-file=/private/tmp/secret nicht einfach deshalb, weil die Token-Bytes fehlen. Prüfen Sie auch den Dateipfad. Wenn der Agent die Datei lesen kann, hat er das Geheimnis. Ist sie nur für einen getrennten Gateway-Prozess lesbar und gelangt nie in vom Agenten kontrollierte Arbeitsverzeichnisse, muss dieser Umstand im Testaufbau festgehalten werden.
Prüfen Sie bei SSH mehr als den Text privater Schlüssel. Der Test muss fehlschlagen, wenn ein Pfad zu einer Identitätsdatei, ein Agent-Socket mit Zugriff auf die Testidentität, ein erzeugter known_hosts-Eintrag mit geheimem Material oder eine Befehlszeile mit einem Passwort auftaucht. Ein privater Schlüssel in einer temporären Datei bleibt ein privater Schlüssel, selbst wenn der Agent nur den Pfad erhält.
Erfolgreiche Aktionen brauchen feindselige Transkripte
Ein Erfolgsfall mit 200 OK beweist fast nichts. Er beweist nur, dass jemand eine Anfrage gestellt hat. Lassen Sie den Agenten eine echte Aktion über das Gateway anfordern und bewahren Sie danach jedes Transkript und jeden Tool-Trace auf der Agentenseite auf.
Der HTTP-Test sollte einen Endpunkt anfordern, der das authentifizierte Testkonto bestätigt, ohne Anfrage-Header zurückzugeben. Eine geeignete Antwort ist ein festes Objekt wie dieses:
{
"account": "gateway-test-http",
"accepted": true,
"request_label": "run-2026-07-22-http-01"
}
Der Agent kann aus dieser Antwort schließen, was passiert ist. Er braucht weder das Bearer-Token noch das Authentifizierungsschema, einen eingefügten Headernamen oder ein maskiertes Token-Präfix. Gibt die Aktionsschnittstelle zu Debugging-Zwecken ein Anfrageobjekt zurück, machen Sie daraus ein eigenes Testziel, denn dort liegt ein wahrscheinliches Leck. Ein Feld namens request_headers ist ein Designfehler, sofern nicht garantiert wird, dass vor dem Überschreiten der Agentengrenze alle Zugangsdaten entfernt werden.
Lassen Sie den SSH-Host einen festen Befehl wie report-status <run-label> akzeptieren. Der Server protokolliert das authentifizierte Konto, den angeforderten Befehl und die Kennung. Er gibt beispielsweise status recorded zurück. Der Agent darf weder den privaten Schlüssel noch einen SSH-Agent-Export oder ein Transkript der Authentifizierung erhalten.
Sammeln Sie diese Artefakte auf der Agentenseite:
- Das ursprüngliche Agenten-Prompt und das Modelltranskript.
- Rohe MCP-Nachrichten oder entsprechende Aktionsanfragen und Antworten.
- Standardausgabe und Standardfehler kontrollierter Agentenbefehle.
- Tool-Debugprotokolle, Wiederholungsprotokolle und strukturierte Ereignisdateien.
- Dateien im Agentenarbeitsbereich, im temporären Verzeichnis und im konfigurierten Cache-Verzeichnis.
Sammeln Sie sie, bevor eine Bereinigungsroutine Belege entfernt. Scannen Sie die exakten Bytes und nicht nur Text, der als UTF-8 dekodiert wurde. Ein Geheimnis kann in JSON-Escapes, Prozentkodierung, Base64, einem komprimierten Trace oder einer Datei auftauchen, deren ungültige Bytes eine beiläufige Textsuche überspringt.
Sallyports sp mcp Shim eignet sich gut dafür, weil der Test denselben regulären MCP-Weg nutzen kann wie ein Agent, während die Zugangsdaten im Tresor der Anwendung bleiben.
Verwechseln Sie ein maskiertes Transkript nicht mit einem Beweis. Eine Protokollzeile wie Authorization: [REDACTED] kann für Bediener in Ordnung sein, doch das zugrunde liegende rohe Ereignisobjekt kann das Token weiterhin enthalten. Erfassen Sie die Daten vor der Darstellung und testen Sie den Formatter anschließend separat. Das sind zwei verschiedene Pflichten.
In der Fehlerbehandlung bricht die Geheimnisisolierung meist zusammen
Ein Gateway kann die Erfolgsantwort sauber halten und ein Geheimnis trotzdem bei einem Fehler offenlegen. Fehlerpfade enthalten häufig Debug-Kontext, rekonstruierte Anfragen, verkettete Ausnahmen und Wiederholungsmeldungen. Führen Sie sie absichtlich aus.
Beginnen Sie mit HTTP-Fehlern an unterschiedlichen Stellen:
- Lassen Sie den Testserver nach dem Empfang eines gültigen Canarys ein nicht geheimes
401zurückgeben. Der Agent soll erfahren, dass die Authentifizierung fehlgeschlagen ist, nicht den gesendeten Headerwert. - Lassen Sie den Server nach erfolgreicher Authentifizierung ein
500mit einem Text zurückgeben, der die öffentliche Laufkennung enthält. Das Gateway darf eine begrenzte Fehlermeldung zurückgeben, aber keine Anfrage-Header oder ein curl-Äquivalent anhängen. - Schließen Sie die Verbindung, nachdem das Gateway die Authentifizierung vorbereitet hat. So finden Sie Ausnahmen auf niedriger Ebene, die Anfrageobjekte in ihrer Beschreibung enthalten.
- Geben Sie nach erfolgreicher Authentifizierung ungültiges JSON zurück. Parser nehmen den fehlerhaften Teil oder den umgebenden Kontext häufig in die Ausnahme auf.
- Verwenden Sie für eine Testroute einen DNS-Namen, der nicht aufgelöst wird. So finden Sie Ausgaben von Wiederholungslogik und Endpunktdiagnosen.
Führen Sie anschließend SSH-Fehler vor und nach dem Verbindungsaufbau aus. Verwenden Sie einen Host mit falscher Hostidentität, einen Remote-Befehl mit Rückgabecode ungleich null und einen erzwungenen Befehl mit einem kontrollierten Fehler. Testen Sie keinen falschen privaten Schlüssel, indem Sie einen Testschlüssel an den Agenten zurücksenden oder den Server veranlassen, ihn zu protokollieren. Der Agent braucht nur eine Einstufung wie connection rejected oder remote command failed sowie eine sichere Laufkennung.
Testen Sie auch den gesperrten Zustand. Während der Tresor gesperrt ist, muss eine Aktion fehlschlagen, bevor eine Netzwerkauthentifizierung stattfindet. Die Antwort darf sagen, dass die Autorisierung nicht verfügbar ist. Sie darf keinen Token-Platzhalter, keinen Pfad zum Speicher der Zugangsdaten, keinen Namen einer SSH-Identitätsdatei und auch nicht die Zeichenanzahl eines Geheimnisses enthalten. Entsperren Sie anschließend den Tresor, wiederholen Sie die Aktion und verlangen Sie den serverseitigen Erfolgsnachweis. Dieses Paar findet Implementierungen, die eine Zugangsdatenanfrage erstellen, bevor sie den Sperrstatus prüfen.
Ein nützliches Fehler-Fixture prüft beide Seiten:
Agent side: the canary is absent from every collected artifact.
Gateway side: the attempted action has the expected safe error classification.
Server side: the expected request occurred, or did not occur for a locked vault test.
Die letzte Prüfung verhindert falsche Sicherheit. Wenn ein Test einen Wiederholungsfehler erwartet, das Gateway den Aufruf aber wegen einer Konfigurationspanne früher abgewiesen hat, kann der Leak-Scan bestehen, ohne den gefährlichen Code auszuführen.
Übertragen Sie keine rohen Ausnahmen über die Grenze. Fehlerobjekte sollten eine Aktions-ID, eine sichere Kategorie, eine verständliche Meldung und gegebenenfalls einen Hinweis zum Wiederholen enthalten. Sie sollten nicht die Anfragekonfiguration serialisieren, die die Ausnahme ausgelöst hat. Der Wunsch nach einfacher Fehlersuche macht vollständige Anfrage-Dumps beliebt. Wenn ein Zugangsdaten-Injektor die Anfrage besitzt, bleiben sie trotzdem die falsche Standardeinstellung.
Absturzartefakte verdienen einen absichtlichen Fehler
Ein Absturz ist kein normales API-Ergebnis, weshalb Teams ihn oft überspringen. Das ist ein Fehler. Ein Entwickler kann einen Absturzbericht an ein Ticket hängen, ein Support-Skript kann ihn archivieren und ein Diagnosesystem kann zugehörige Protokolle sammeln. Gelangt dort ein Geheimnis hinein, haben Sie statt einer sicheren Grenze ein verzögertes Leck gebaut.
Lassen Sie nach einer erfolgreichen HTTP-Aktion und erneut nach einer erfolgreichen SSH-Aktion einen Prozess auf der Agentenseite abbrechen. Halten Sie das Absturzziel vom Gateway getrennt. Sie wollen prüfen, ob die Agentenseite geheimes Material geerbt oder aufgezeichnet hat, nicht ob ein absichtlich abstürzender Zugangsdatenhalter seinen privaten Zustand offenlegt.
Sammeln Sie unter macOS den Bericht über Console oder den Diagnosepfad der Testumgebung und scannen Sie die unveränderte Datei. Apple beschreibt Absturzberichte als detaillierte Aufzeichnungen des Anwendungszustands und empfiehlt, den vollständigen Betriebssystembericht zu analysieren. Die Dokumentation weist außerdem darauf hin, dass Berichte Prozess- und Umgebungsinformationen wie Prozessidentität, Pfad, Elternprozess, Zeitangaben und Thread-Zustand enthalten.
Das Fehlen des Canarys in einem macOS-Absturzbericht beweist nicht, dass es nie im Speicher vorhanden war. Ein normaler Absturzbericht ist kein vollständiges Speicherabbild. Das ist kein Grund, den Test auszulassen. Formulieren Sie das Ergebnis korrekt: Der Bericht legte das Canary nicht offen, und der Agentenprozess erhielt es nicht über die anderen geprüften Kanäle.
Prüfen Sie außerdem Anwendungsprotokolle und Support-Archive, die rund um den Absturz erstellt wurden. Apple warnt Entwickler davor, datenschutzrelevante Informationen in Protokolle aufzunehmen. Behandeln Sie das als Anforderung für Ihr Fixture: Wenn ein Ausnahme-Printer ein Anfrageobjekt protokolliert, muss der Absturztest fehlschlagen, selbst wenn der Betriebssystembericht sauber ist.
Wenn Sie später entsprechende Tests unter Linux ausführen, nehmen Sie Metadaten von Core-Dumps und Journal-Ausgaben in die Artefaktmenge auf. Das Handbuch zu systemd-coredump beschreibt Felder, die Befehlszeile und Umgebung eines abgestürzten Prozesses speichern können. Eine Testsuite, die nur die Core-Datei scannt und Metadaten ignoriert, übersieht einen naheliegenden Leckpfad.
Bytes, Kodierungen und geteilte Werte scannen
Ein einfaches rekursives grep ist besser als nichts, übersieht aber Formen, die in JSON, URLs, Stacktraces und Binärpaketen auftreten. Erstellen Sie einen Scanner, der Dateien als Bytes liest und mehrere deterministische Umwandlungen jedes Canarys durchsucht.
Erzeugen Sie für jedes Canary mindestens diese Suchwerte:
raw bytes
base64 text
URL encoded text
JSON escaped text
hex text
first half and second half separated by one newline
Der geteilte Fall findet Protokoll-Wrapper, die lange Werte umbrechen. Die kodierten Fälle finden Systeme, die strukturierte Daten vor dem Schreiben serialisieren. Suchen Sie nicht nur nach einem Token-Präfix. Ein Präfix-Test kann bestehen, wenn das Token nach genügend Zeichen abgeschnitten wird, um weiter nutzbar zu sein, und er kann bei einer unabhängigen Kennung anschlagen.
Ein kompakter Scanner kann Dateipfad, Umwandlungsname und Byte-Offset melden, ohne das Geheimnis selbst auszugeben:
import base64
import json
import pathlib
import urllib.parse
secret = bytes.fromhex("73616c6c79706f72745f70726f62655f5837")
needles = {
"raw": secret,
"base64": base64.b64encode(secret),
"url": urllib.parse.quote_from_bytes(secret).encode(),
"json": json.dumps(secret.decode()).encode(),
"hex": secret.hex().encode(),
}
for path in pathlib.Path("artifacts").rglob("*"):
if not path.is_file():
continue
data = path.read_bytes()
for name, needle in needles.items():
offset = data.find(needle)
if offset >= 0:
raise SystemExit(f"secret match: {path} transform={name} offset={offset}")
Der Code meldet absichtlich den Offset und nicht die gefundenen Bytes. Ein Testfehler darf keine zweite undichte Stelle in der CI-Ausgabe erzeugen. Speichern Sie eine streng kontrollierte forensische Kopie nur, wenn Ihr Vorfallprozess das verlangt, und halten Sie sie außerhalb normaler Build-Protokolle.
Entpacken Sie Archive vor dem Scannen in ein geschütztes temporäres Verzeichnis. Prüfen Sie nach Möglichkeit auch komprimierte Daten, denn ein Scan roher Bytes findet ein Canary in einer komprimierten Nutzlast nicht. Wenn Ihr Telemetrie-Client Ereignisse bündelt, sammeln Sie das Bündel, bevor es den Testrechner verlässt. Es hilft wenig, später festzustellen, dass der Scanner nur lokale Dateien geprüft hat, während ein kodiertes Token bereits an einen Drittanbieter übertragen wurde.
Führen Sie eine Allowlist für erwartete öffentliche Kennungen, nicht für Geheimnisse. Wenn ein Test fehlschlägt, weil ein Feld den Namen des Testkontos enthält, entscheiden Sie, ob dieser Name selbst Zugriff gewährt. Fügen Sie keine weit gefassten Ausnahmen hinzu, nur damit der Scanner grün wird. Jede Ausnahme ist ein Loch, dessen Überprüfung Sie später vergessen werden.
Der Bericht muss Abwesenheit und Aktion zeigen
Ein guter Testbericht beantwortet vier Fragen, ohne den Leser um Vertrauen in Ihre Interpretation zu bitten.
Erstens: Welche Gateway-Aktion war erfolgreich oder schlug fehl? Zeigen Sie die öffentliche Laufkennung, den Aktionstyp und die serverseitige Beobachtung. Zweitens: Welche Artefakte wurden gesammelt? Listen Sie Startmomentaufnahme, Kindprozess-Momentaufnahme, Transkript-Bundle, Arbeitsbereich, Fehlerausgaben und Absturzartefakte auf. Drittens: Nach welchen Geheimnis-Umwandlungen hat der Scanner gesucht? Viertens: Ist ein Scan fehlgeschlagen, weil Berechtigungen, eine falsche Kodierungsannahme oder ein übersprungenes Archiv die Prüfung verhindert haben?
Ein übersprungenes Artefakt ist kein Erfolg. Markieren Sie den Test als unvollständig und lassen Sie die Suite fehlschlagen, sofern es keinen dokumentierten Grund gibt, warum das Artefakt außerhalb der Agentengrenze liegt. Diese Regel nervt während der CI-Einrichtung. Sie verhindert aber, dass ein Test Erfolg meldet, weil er das Verzeichnis mit dem Leck stillschweigend nicht öffnen konnte.
Halten Sie das Aktionsprotokoll des Gateways vom Artefakt-Bundle des Agenten getrennt. Das Gateway-Protokoll kann beweisen, dass eine durch Zugangsdaten geschützte Aktion stattgefunden hat. Das Agenten-Bundle kann zeigen, was der Agent erhalten hat. Eine gemeinsame, bequeme Exportdatei schafft einen unnötigen neuen Ort, an den sensible Informationen gelangen können.
Für Release-Prüfungen sollte die Bedingung streng sein:
PASS only when the server confirms the intended action,
all required artifacts were collected,
and no raw or transformed canary appears in agent reachable material.
Fügen Sie anschließend Negativkontrollen hinzu. Führen Sie ein absichtlich fehlerhaftes Fixture aus, das das Canary über eine Umgebungsvariable oder eine gefälschte Debug-Antwort weitergibt. Der Scanner muss es ablehnen. Ein Test, der nie zeigt, dass er ein bekanntes Leck findet, ist nur Theater.
Führen Sie die Suite immer aus, wenn jemand die Zugangsdaten-Injektion, den Prozessstart, den MCP-Transport, die Fehlerformatierung, Protokollierung, Support-Sammlung oder SSH-Verarbeitung ändert. Solche Änderungen wirken im Review unabhängig, sind aber genau die Stellen, an denen Zugangsdaten entweichen. Halten Sie eine kleinere Variante in den normalen Integrationstests und verschieben Sie Absturz- und Archiverfassung auf geplante oder Release-Läufe, wenn sie teuer ist.
Der Standard lässt sich einfach formulieren: Das Gateway darf ein Geheimnis verwenden, um zu handeln, aber der Agent darf dieses Geheimnis nicht als Daten erhalten. Wenn Ihr Test nur beobachtet, was der Agent sagt, bleibt zu viel ungeprüft. Lassen Sie den Agenten handeln, Fehler auslösen, einen Unterprozess starten und abstürzen, und scannen Sie, was zurückbleibt.
FAQ
Kann ein Blackbox-Test beweisen, dass ein KI-Agent niemals ein Geheimnis sieht?
Ein Blackbox-Test kann keine absolute Aussage über jeden CPU-Befehl oder jede künftige Version beweisen. Er kann aber eine wesentlich nützlichere Aussage belegen: Bei kontrollierten Läufen mit eindeutigen Canary-Zugangsdaten enthalten der Agentenprozess, seine Nachfahren, seine Transkripte und die gesammelten Artefakte keine Zugangsdaten. Behandeln Sie das als Freigabekriterium und nicht als philosophischen Beweis.
Sollte ich echte API-Schlüssel für Tests auf Geheimnislecks verwenden?
Verwenden Sie Zugangsdaten, die nur für ein wegwerfbares Testkonto oder einen Testserver funktionieren, und geben Sie jedem Lauf eine neue Markierung. Verwenden Sie niemals ein Produktions-Token, auch nicht mit dem Plan, es anschließend zu widerrufen. Ein Testgeheimnis muss selbst dann ungefährlich sein, wenn ein Test fehlschlägt, denn genau solche Fehler sollen gefunden werden.
Welche Artefakte sollte ich auf geleakte API-Geheimnisse prüfen?
Prüfen Sie die Startumgebung und die Befehlsargumente des Agenten, sein Arbeitsverzeichnis, untergeordnete Prozesse, gespeicherte Gesprächsdaten, Tool-Protokolle, Standardausgabe, Standardfehler, Absturzberichte und Support-Bundles. Scannen Sie die Rohdaten, bevor eine Maskierungsschicht sie verändert. Ein maskierter Bericht kann sauber aussehen, während die Originaldatei das Geheimnis noch enthält.
Ist es sicher, wenn ein Agentenaufruf ein Geheimnis enthält, das Modell es aber nicht erwähnt?
Nein. Wenn ein Token in einem Tool-Transkript auftaucht, hat es die Agentengrenze überschritten, auch wenn das Modell es nie wiederholt. Entscheidend ist, auf welche Daten der Agentenprozess zugreifen kann, nicht ob er sie ausgibt.
Wie teste ich SSH-Zugangsdaten, ohne einen privaten Schlüssel offenzulegen?
Verwenden Sie einen wegwerfbaren Server, der das authentifizierte Konto, den angeforderten Befehl und das Sitzungsergebnis protokolliert, ohne private Schlüssel oder Zugangsdaten auszugeben. Nutzen Sie ein eingeschränktes Testkonto und nach Möglichkeit einen erzwungenen Befehl. Der Nachweis soll zeigen, dass die Aktion stattgefunden hat und keine privaten Schlüsseldaten in Agentenartefakten auftauchen.
Enthalten Absturzberichte API-Schlüssel oder SSH-Geheimnisse?
Absturzberichte sollten geprüft werden, weil sie häufig in Fehlerberichte und Diagnose-Bundles kopiert werden. Ihr Fehlen beweist nicht, dass ein Geheimnis nie im Speicher war, denn ein normaler Absturzbericht ist kein vollständiges Speicherabbild. Er findet trotzdem vermeidbare Lecks in Fehlermeldungen, Prozessmetadaten, Befehlszeilen und Anwendungsprotokollen.
Sollte ich Aktionen bei gesperrtem Zugangsdaten-Tresor testen?
Testen Sie beides. Ein Gateway sollte eine Aktion bei gesperrtem Tresor ablehnen. Diese Ablehnung darf dem Agenten weder einen Platzhalter, die Länge eines Geheimnisses noch eine irreführende Zugangsdaten-Fehlermeldung senden. Wiederholen Sie die Aktion nach dem Entsperren und prüfen Sie, dass nur das vorgesehene Ergebnis sichtbar wird.
Warum sollte ich sowohl die Agentenumgebung als auch untergeordnete Prozesse testen?
Ein Prozess-Wrapper erfasst die Umgebung und Argumente beim Start. Ein vom Agenten gestartetes Prüfprogramm erfasst später die Umgebung, die an untergeordnete Prozesse vererbt wird. Sie brauchen beides, weil ein sauberer Start einen späteren Einschleusungspfad nicht ausschließt.
Wann sollte ein Test auf Geheimnislecks fehlschlagen?
Der Build sollte fehlschlagen, wenn das exakte Canary in einem Artefakt auftaucht, das ein Agent, Entwickler, Support-Mitarbeiter oder Telemetriesystem lesen kann. Das gilt auch für umgewandelte Formen wie URL-Kodierung, Base64, JSON-Escaping oder eine Aufteilung über mehrere Zeilen. Ein Sicherheitstest, der Umwandlungen ignoriert, prüft vor allem den Erfolgsfall.
Wie oft sollte ich Tests auf Geheimnislecks bei Agenten ausführen?
Führen Sie die vollständige Suite bei jeder Änderung an der Zugangsdaten-Injektion, dem Tool-Transport, dem Prozessstart, der Protokollierung, der Fehlerbehandlung oder der Absturzberichterstattung aus. Ein kleinerer Canary-Test gehört in die normalen Integrationstests. Geheimnisgrenzen brechen häufig in Verbindungscode, daher ist Warten auf ein großes Release zu spät.