th3chris
Alle Artikel
7 Min. Lesezeit

Wie KI-Agents Zugangsdaten leaken — und wie man es verhindert

KISecurityDevOpsSecrets

Du arbeitest mit einem KI-Coding-Agent — Claude Code, Cursor, egal — in deinem Repo, und für „mach den Pull Request auf, ruf die Staging-API, stoß das Deployment an" braucht er Zugangsdaten. Gibst du ihm welche, ist die naheliegende Übergabe schon der Leak — und „dann gebe ich ihm eben keine" rettet dich nicht: dann besorgt er sie sich selbst, liest die .env, fragt den Vault — und leakt sie dabei, ohne dass du es überhaupt merkst. So oder so wandert der Wert durch das KI-Modell und ist damit weg.

Der unangenehme Teil: dieses Credential wird an einen Dritten kopiert — den Modell-Anbieter — dort gespeichert und entgleitet deiner Kontrolle. Für die meisten Unternehmen ist das zugleich ein Compliance-Problem. Hier ist, warum das passiert und wie man es dauerhaft schließt.

Kurz gesagt — KI-Agents leaken Zugangsdaten, indem sie sie als Output lesen, der an den Modell-Anbieter geht. Die Lösung: einen Agent ein Secret benutzen lassen, ohne dass er es je sieht.

Warum das naheliegende Setup leakt

Der Mechanismus ist simpel — und tückisch: in dem Moment, in dem der Agent den Wert liest — aus .env, Vault oder deiner Nachricht — wird er Teil der Konversation, die der Agent an den KI-Anbieter schickt. Der Token steht jetzt in fremden Logs. Den Chat hinterher zu löschen bringt nichts; übertragen wurde er in dem Moment, in dem er auftauchte.

Mit „bitte sei vorsichtig" im Prompt löst du das nicht. Eine Anweisung im Prompt ist eine Empfehlung, und Empfehlungen werden ignoriert — von diesem Agent, vom nächsten oder von irgendeinem Tool drumherum. Die Lösung muss strukturell sein: das Secret muss unmöglich zu sehen sein, nicht bloß unerwünscht.

Das ist nicht hypothetisch. Anfang 2026 leakten 7 % der Skills eines populären Agent-Marktplatzes Zugangsdaten auf genau diese Weise — den Vorfall habe ich in dem OpenClaw-Leak aufgedröselt.

Und es sind nicht nur Agents, die sich Secrets holen: Millionen Entwickler — und „Vibe-Coder" — pasten API-Keys jeden Tag direkt in den Prompt. Dasselbe Leck, nur von Hand — aus Bequemlichkeit und in dem leichtgläubigen Vertrauen, dass schon nichts passiert.

Benutzen ist nicht Sehen

Die ganze Lösung in einem Satz: ein Agent muss ein Credential benutzen, aber er muss es nie sehen. Das sind zwei verschiedene Dinge, und sie auseinanderzuhalten ist der ganze Trick.

Konkret: das Secret geht in das Programm, das der Agent ausführt — nie in den Text, den das KI-Modell liest. Die Shell sitzt dazwischen: sie reicht den Wert als Umgebungsvariable an ein Programm weiter, während der Agent nur den Befehl sieht, den er getippt hat.

Zuerst: wo wohnt das Secret?

Ein Secret aus dem Blickfeld der KI zu halten, funktioniert nur, wenn es irgendwo liegt, wo ein Tool es bei Bedarf holen kann — nicht hartkodiert im Repo, nicht in eine Config gepastet, die der Agent liest. Dieses „irgendwo" ist ein Secrets-Manager (ein Tresor): ein Ort, der Zugangsdaten verschlüsselt speichert, sie an autorisierte Programme aushändigt und protokolliert, wer was angefasst hat.

Ich nutze Infisical, eine Open-Source-Plattform fürs Secrets-Management. Sie passt aus drei Gründen zu einem KI-Agent-Setup: sie ist selbst hostbar, die Secrets bleiben also auf meiner eigenen Infrastruktur, ohne Dritt-SaaS dazwischen; sie ist Open Source; und sie bringt vollwertige Machine Identities mit — headless-Auth mit kurzlebigen Tokens, gemacht für genau diese Agent- und CI-Nutzung, ohne menschliches Login. Der eigentliche Gewinn für dieses Problem: sie übernimmt den Schritt „das Secret dem Programm geben, nie dem Prompt" für dich (nächster Abschnitt). Mit einem anderen Tresor baust du diesen Schritt selbst — ein paar Zeilen, gegen Ende gezeigt. Beides geht; Infisical macht es nur zum Weg des geringsten Widerstands.

In der Praxis: meistens ein einziger Befehl

Sobald das Secret in Infisical liegt, ist das Benutzen meist ein einziger Befehl. Die CLI bringt infisical run mit, das die Secrets eines Projekts als Umgebungsvariablen in einen Child-Prozess injiziert und sie nie ausgibt:

infisical run --env=prod --path=/git -- gh pr list

gh bekommt den Token aus seiner Umgebung; er taucht nie auf stdout auf, kann also nicht ins Transcript. Für die meisten Teams ist dieser eine Befehl die Lösung.

Ich packe ihn in einen get-secret-Helper, damit der Aufruf kurz ist und die Auth automatisch passiert:

get-secret exec git -- gh pr list

Darunter ist das nur infisical run mit einem Machine-Identity-Token aus dem OS-Keychain — so spart sich jeder Aufruf die Flags --token, --projectId und --domain. Zum Benutzen eines Secrets könntest du genauso das nackte infisical run tippen; hier ist der Wrapper reine Bequemlichkeit. Echte Arbeit leistet er nur an einer Stelle — beim Lese-Pfad weiter unten, genau dort, wo die nackte CLI leaken würde.

Die eine Lücke: einen einzelnen Wert lesen

infisical run deckt das Benutzen ab. Aber sobald du einen Rohwert anforderst — infisical secrets get GITHUB_TOKEN — druckt die CLI ihn im Klartext nach stdout. Für einen Menschen am Terminal ist das in Ordnung; für einen Agent ist dieser stdout wieder das Transcript.

Das Einzige, was sich selbst zu schreiben lohnt, ist also ein dünnes Gate auf diesem Lese-Pfad — den Wert nur ausgeben, wenn wirklich ein Mensch zuschaut:

# get-secret <folder>/<NAME> — gibt einen Wert aus, aber nur an einen Menschen.
val=$(infisical secrets get "$name" \
        --projectId "$PROJECT_ID" --env=prod --path="/$folder" \
        --token "$(get_token)" --plain --silent)

if [ -t 1 ]; then                      # stdout ist ein echtes Terminal -> ein Mensch
  printf '%s\n' "$val"
else                                   # stdout ist eine Pipe -> ein Agent; verweigern
  printf '[redacted len=%s]\n' "${#val}"
fi

[ -t 1 ] ist der ganze Trick: der stdout eines KI-Agents ist im Normalfall eine Pipe, kein Terminal, also bekommt er im Normalbetrieb [redacted len=40] und nichts weiter.

Ich habe es so getestet, wie man jede Security-Behauptung testen sollte: echten Wert holen, alles einfangen, was der Befehl ausgibt, diese Ausgabe nach dem Secret durchsuchen. Es taucht nirgends auf, wo ein Agent es lesen kann.

Die Anbindung an Infisical

Der einzige weitere bewegliche Teil ist die Auth — und die ist headless by design, kein interaktives Login:

  • einmalig: ein Universal-Auth-client_id:client_secret (eine Machine Identity) im OS-Keychain ablegen
  • pro Aufruf: infisical login --method=universal-auth … liefert einen kurzlebigen Token (gecacht ~25 min), der jedem Befehl als --token übergeben wird
  • --projectId, --env=prod, --path=/git wählen genau aus, was gelesen wird

Das ist der ganze Skill: infisical run zum Benutzen, ein TTY-gegateter infisical secrets get zum Lesen, Machine-Identity-Auth — vielleicht achtzig Zeilen Shell. Ein neues Secret zu schreiben ist die asymmetrische Richtung: der Wert muss von irgendwoher hereinkommen, und wenn ein Mensch ihn in den Chat pastet, damit der Agent ihn speichert, ist dieser Paste schon das Leck. Der Schreibpfad nimmt Werte deshalb nur über stdin oder eine Datei, nie in einen Befehl getippt:

echo -n "$VALUE" | set-secret git/TOKEN -      # wrappt `infisical secrets set`, liest stdin

Wenn dein Tresor kein run mitbringt

infisical run nimmt dir den Injection-Schritt ab: Secrets holen, in die Umgebung legen, Kommando ausführen, nie stdout berühren. Tresore wie HashiCorp Vault, pass oder AWS Secrets Manager geben dir nur den Wert zurück — diesen einen Schritt baust du also selbst. Es sind eine Handvoll Zeilen:

#!/bin/bash
# run-with-secret <cmd...> — Wert aus beliebigem Tresor in die Env, dann Kommando ausführen.
export GITHUB_TOKEN="$(vault kv get -field=token secret/git)"   # oder: pass show git/token, aws secretsmanager get-secret-value …
exec "$@"

run-with-secret gh pr list reicht den Token über Command-Substitution in die Umgebung an gh — er wandert nie über stdout, der Agent sieht nur den Befehl, nie den Wert. Mehrere Secrets? Mehrere export-Zeilen. Genau das macht get-secret exec unter der Haube; Infisical erspart dir nur, es zu schreiben.

Die Aufteilung ist also einfach. Das Read-Gate von oben baust du einmal, egal welcher Tresor. Die Injection ist mit Infisical (infisical run) gratis und mit allem anderen ein paar Zeilen. Die Sicherheit steckte nie im Tresor — sie steckt darin, wie du den Wert an den Agent übergibst: in den Prozess, nie in den Prompt.


Das ist eine kleine, strukturelle Entscheidung. Und zugleich der Unterschied zwischen „wir lassen die KI an Produktion" und „wir lassen die KI sicher an Produktion". Teams genau solche Grenzen sauber ziehen zu helfen — damit Automatisierung schnell bleibt, ohne still Risiko aufzubauen — ist Teil meiner Arbeit. Wenn dich das beschäftigt, lass uns reden.

Bereit?

Lass uns dein Projekt besprechen.

2–3 Minuten gezielte Fragen, eine klare Einschätzung — und ich melde mich persönlich. Lieber direkt schreiben? Auch das geht.

Ohne Konto · Antwort innerhalb 24 h