Wie du einem KI-Coding-Agenten ein Secret gibst, ohne es in den Prompt zu schreiben
Ein Agent braucht einen Stripe-Key oder ein Datenbank-Passwort, um seinen Befehl auszuführen. Klebst du ihn in den Chat, landet er im Transkript auf deiner Platte, beim Modellanbieter und manchmal in einem Commit. Die Regel, bei der wir nach drei eigenen Fehlern gelandet sind: Ein Secret erreicht einen Agenten über eine Umgebungsvariable und über nichts anderes.
Die Situation ist immer dieselbe. Ein Agent steckt mitten in einer Aufgabe, er muss deine Stripe-Test-API aufrufen, eine Migration gegen die Staging-Datenbank fahren oder in eine private Registry pushen. Er fragt nach dem Key. Du hast den Key in deinem Passwort-Manager, der Agent wartet, und das Schnellste der Welt ist, ihn in den Chat zu kleben.
Dieses Einfügen ist der Moment, in dem der Key deine Kontrolle verlässt. Nicht weil das Modell bösartig wäre, sondern weil ein Prompt ein gespeichertes, weitergereichtes Objekt ist: Er geht in eine Transkriptdatei auf deiner Platte, er geht an den Modellanbieter, und er wird von jeder Wiederholung und jedem Subagent kopiert, der die Konversation erbt.
Wir bauen AgentsRoom, eine Desktop-App, die Coding-Agenten betreibt, also mussten wir das für uns selbst lösen. Im September 2026 haben wir es dreimal falsch gemacht. Hier ist die Regel, bei der wir gelandet sind, die drei Fehler, die sie hervorgebracht haben, und wie du sie anwendest, ob du unsere App nutzt oder nicht.
Die kurze Antwort
- Ein Secret erreicht einen Agenten über eine Umgebungsvariable und über nichts anderes. Nicht über eine Nachricht, nicht über ein Ticket, nicht über einen Skill, nicht über ein Kommandozeilen-Flag.
- Der Agent nutzt
$NAME, nie den Wert. Die Shell setzt ihn ein, wenn der Befehl läuft. - Speichere den Wert einmal, außerhalb des Repos, verschlüsselt durch den Schlüsselbund deines Systems, und referenziere ihn überall sonst über seinen Namen.
- Ein Secret, das durch eine Konversation gelaufen ist, ist verbrannt. Tausch es aus, dann räum auf.
- Schwärzen ist ein Sicherheitsnetz, kein Plan. Es erwischt, was wie ein Key aussieht, nicht ein Datenbank-Passwort, das sich wie ein Wort liest.
Warum das Einfügen schlimmer ist, als es aussieht
Drei Dinge passieren gleichzeitig, und nur das erste ist offensichtlich.
Es geht an den Modellanbieter. Das ist der Teil, den alle sehen. Dein Key steckt jetzt in einem Request-Body auf fremder Infrastruktur, in einer Konversation, die du nicht bearbeiten kannst.
Es geht auf deine Platte, im Klartext. Claude Code, Codex, Antigravity CLI und der Rest führen ein Transkript der Konversation, damit du sie fortsetzen kannst. Diese Datei liegt unverschlüsselt in deinem Home-Verzeichnis, so lange das CLI seinen Verlauf behält. Durchsuch deine Transkripte einmal nach der Zeichenkette sk- und sieh dir an, was zurückkommt.
Es breitet sich seitwärts aus. Die Konversation ist das Gedächtnis des Agenten, also kopiert alles, was die Konversation kopiert, auch den Key: eine fortgesetzte Sitzung, ein geforkter Agent, ein Subagent, der mit dem Kontext des Elternteils startet, eine Zusammenfassung, die in eine Projektdatei geschrieben wird. Wir haben gesehen, wie ein Key von einer Chat-Nachricht in eine Ticketbeschreibung und von dort in die erste Nachricht eines zweiten Agenten gewandert ist, ohne dass irgendjemand etwas falsch gemacht hätte.
Und das übliche Sicherheitsnetz hält nicht. Das Schwärzen der Ausgabe arbeitet über Muster: sk-…, glpat-…, die Form eines JWT. Es kann nicht wissen, dass thursday-harbour-71 das Passwort deiner Staging-Datenbank ist. In unserer eigenen App schwärzen wir erkannte Werte in der Terminal-Ausgabe, und wir halten das trotzdem für ein Netz unter dem Trapez, nicht für das Trapez.
Die Regel der einen Tür
Hier ist die Regel, in einer Zeile: Zugangsdaten erreichen einen Agenten über eine Umgebungsvariable des Prozesses, in dem er läuft, und über keinen anderen Kanal.
Alles andere ist wörtlicher Text. Eine Nachricht, die du tippst, eine Ticketbeschreibung, eine Skill-Datei, ein System-Prompt, ein Kommandozeilen-Flag: Das alles wird von einem Menschen oder einem Modell gelesen, also ist ein dort geschriebenes Secret ein veröffentlichtes Secret.
Die Kommandozeile verdient einen eigenen Satz, weil sie sich sicherer anfühlt als eine Chat-Nachricht und es nicht ist. Ein Wert in --api-key=… ist über ps für jeden Prozess auf der Maschine sichtbar, er landet im Verlauf deiner Shell, er wird von allem protokolliert, was den gestarteten Befehl aufzeichnet, und er taucht in Diagnosewerkzeugen auf, die dir die Prozesszeile zurückgeben. Eine Umgebungsvariable eines Prozesses ist von diesem Prozess und von root lesbar. Kleinere Angriffsfläche, gleicher Komfort.
Der Agent dagegen braucht den Wert nie. Er muss das hier schreiben:
curl -H "Authorization: Bearer $STRIPE_SECRET_KEY" https://api.stripe.com/v1/charges
Die Shell setzt $STRIPE_SECRET_KEY bei der Ausführung ein. Der Agent hat siebzehn Zeichen und ein Dollarzeichen geschrieben. Sein Transkript enthält siebzehn Zeichen und ein Dollarzeichen.
Wie es in unserer App funktioniert
Der Mechanismus zählt weniger als die Form, aber die Form lässt sich leichter übernehmen, wenn man eine Umsetzung sieht.
Ein Tresor, eine Datei. AgentsRoom hält Secrets in einer einzigen Datei in deinem Home-Verzeichnis, Modus 0600, verschlüsselt über den Schlüsselbund des Betriebssystems, bei jedem Schreibvorgang neu bestätigt. Nichts wird auf einen Server synchronisiert, und nichts geht auf einen anderen Rechner über: Ein Secret gehört der Maschine, die es hält. Ist der Schlüsselbund nicht verfügbar, schlägt das Speichern fehl, statt auf Klartext zurückzufallen.
Du speicherst einen Wert einmal. Befehle & Verbindungen > Secrets, in jedem Projekt. Ein Name (Buchstaben, Ziffern, Punkt, Bindestrich, Unterstrich, 64 Zeichen, damit er als Name einer Umgebungsvariable taugt) und ein Wert, in ein Passwortfeld getippt. Die Zeile, die erscheint, zeigt den Namen und seine Referenz, {{secret:STRIPE_SECRET_KEY}}, und einen Knopf, der die Referenz kopiert. Es gibt keinen Knopf zum Anzeigen und keinen zum Kopieren des Werts, weil es keinen Codepfad gibt, der einen Wert an die Oberfläche zurückgibt.
Du referenzierst ihn dort, wo die Umgebung gebaut wird. Agent bearbeiten > Erweitert > Umgebungsvariablen, oder die Projekteinstellungen, oder die Provider-Einstellungen, oder eine Dev-Befehlszeile:
STRIPE_SECRET_KEY={{secret:STRIPE_SECRET_KEY}}
Beim Start setzt der Hauptprozess den Wert in die Umgebung des Terminals ein, das er gleich erzeugt. Der Renderer sieht ihn nie, der Agent sieht ihn nie, das Handy sieht ihn nie. Die Seite zum Secret Manager führt durch die Bildschirme.
Der Agent entdeckt Namen, keine Werte. Ein Agent, der an unsere MCP-Tools angebunden ist, kann secrets_list aufrufen und bekommt die Liste der Namen auf dieser Maschine zurück. Das reicht, damit er nützlich ist: Er kann sagen „du hast ein STRIPE_SECRET_KEY gespeichert, füg STRIPE_SECRET_KEY={{secret:STRIPE_SECRET_KEY}} zur Umgebung dieses Agenten hinzu, dann nutze ich $STRIPE_SECRET_KEY". Er kann den Wert nicht lesen, auch nicht, während er einen Befehl ausführt, der ihn benutzt.
Drei Fehler, die wir ausgeliefert haben
Die Regel oben klingt offensichtlich, wenn sie einmal dasteht. Sie ist das Narbengewebe von drei Bugs, alle im September 2026, alle von Nutzern gemeldet.
Eine in einem Ticket zitierte Referenz kam aufgelöst heraus
19. September. Robert hatte eine Zuordnung in einer Ticketbeschreibung dokumentiert, das völlig vernünftige STRIPE_SECRET_KEY={{secret:STRIPE_SECRET_KEY}}, damit derjenige, der das Ticket übernimmt, weiß, was zu setzen ist. Über die API gelesen, gab das Ticket die Referenz unverändert zurück. Aber der aus diesem Ticket gestartete Agent bekam den Wert in seiner ersten Nachricht.
Die Ursache war ein Detail der Verkabelung mit einer sehr realen Folge. Das Briefing eines Tickets wird zum ersten Prompt des Agenten, und dieser reiste in einer Umgebungsvariable des Startbefehls mit. Unser Resolver setzte jeden Umgebungswert ein, also setzte er auch den Prompt ein. Der Key ging auf die Platte und an den Modellanbieter. Austausch, kein Weg daran vorbei.
Die Korrektur bestand darin, den Startbefehl eines Agenten wörtlich zu machen: Trägt die Umgebung eine Agenten-ID, bleibt die Variable mit dem ersten Prompt unangetastet. Ein Dev-Befehl, der dieselbe Variable nutzt, hat keine Agenten-ID und löst auf wie zuvor. Einen Nebeneffekt haben wir bewusst in Kauf genommen: Eine in die CLI-Optionen eines Agenten getippte Referenz wird ebenfalls nicht mehr aufgelöst, was richtig ist, denn eine Kommandozeile landet ohnehin in ps und in Logs.
Die Lehre: Die Tür muss mit Absicht eng sein. „Überall einsetzen, wo es nützlich sein könnte" ist genau der Weg, auf dem ein Secret dort landet, wo es nie sein sollte.
Eine in eine Nachricht geklebte Referenz, die sich nie auflöst
22. September. Cs040618 meldete das umgekehrte Problem: „Ich klebe die Referenz in die Konversation, und der Agent kann nicht verstehen, was dieser Key ist."
Kein Bug. Eine Nachricht ist von Haus aus wörtlicher Text, was genau die Korrektur von drei Tagen zuvor ist. Aber nichts in der App sagte das im Moment der Handlung, und der Agent, der {{secret:…}} in einer Nachricht bekam, hatte keine Ahnung, was er antworten sollte.
Drei Korrekturen, alle darüber, den Leuten zu sagen, wo die Tür ist: ein Hinweis, der erscheint, wenn du eine Referenz in das Eingabefeld klebst, und auf die Umgebungsvariablen zeigt, ein Hilfetext über der Secret-Liste, der die drei Felder benennt, in denen eine Referenz eingesetzt wird, und „nie in einer Nachricht" sagt, und eine Zeile in den Anweisungen des Agenten selbst, die ihm sagt, was er antwortet, wenn eine Referenz in einer Nachricht ankommt.
„Einstellungen > Secrets" gab es nicht
28. September. Mohammads Agent reichte einen Bericht ein: Der Nutzer sagt, er habe OTPIQ_API_KEY unter Einstellungen > Secrets hinzugefügt, über dreißig Minuten mehrmals gespeichert, und secrets_list gibt immer noch dieselben drei alten Secrets zurück.
Der Speicherpfad war in Ordnung. Das Secret war nie im Tresor angekommen, denn es gibt keine Secrets-Seite in den Einstellungen. Sechs Hilfetexte in der Desktop-App, eine Seite auf dieser Website und die Anweisungen des Agenten schickten die Leute alle auf einen Bildschirm, den es nicht gab. Was es in den Einstellungen gibt, ist der Block für Umgebungsvariablen, also hat er den Token dort eingetippt, in geschweiften Klammern, was keine Referenz ist: nie eingesetzt, unverändert an den Agenten geschickt und mit dem Projekt synchronisiert, also hat der Token die Maschine verlassen.
Wir haben die Texte so korrigiert, dass sie den echten Pfad nennen, die an Agenten gerichteten Tools sagen lassen, wo ein Secret hinzugefügt wird, und eine Prüfung im Umgebungsblock ergänzt, die roh aussehende Zugangsdaten markiert, einen Namen in geschweiften Klammern, der keine Referenz ist, und eine Referenz auf ein Secret, das es auf dieser Maschine nicht gibt.
Die Lehre hier hat gar nichts mit Secrets zu tun: Ein falscher Pfad in einem Hilfetext ist ein Sicherheitsbug. Er schiebt den Nutzer zum nächstgelegenen Feld, das richtig aussieht.
Wenn du AgentsRoom nicht nutzt
Die Regel ist übertragbar. Nimm von diesen Wegen den, der zu deinem Setup passt; sie enden alle am selben Ort, bei einer Umgebungsvariable in dem Prozess, in dem der Agent läuft.
- Das CLI eines Passwort-Managers.
op run -- claudemit 1Password, oder das Äquivalent bei Bitwarden und Doppler: Das Werkzeug liest Referenzen aus einer Vorlage, spielt die echten Werte in die Umgebung des Kindprozesses ein, und nichts wird auf die Platte geschrieben. direnvmit einer gitignorierten.envrc. Einfach, lokal, pro Verzeichnis. Trag.envrcund.env*in die.gitignoreein, bevor der erste Wert hineingeht, nicht danach.- Eine
.env-Datei, die der Agent nie liest. Halt sie aus dem Repo heraus und lade sie in der Shell, die den Agenten startet. Liegt die Datei im Repository, wird der Agent sie irgendwann öffnen, in einer Nachricht zitieren, und du bist wieder am Anfang. - Cloud-Zugangsdaten: nimm kurzlebige. GitHub OIDC in der CI statt langlebiger AWS-Keys, und eine Workload Identity statt einer Schlüsseldatei für ein Dienstkonto.
Was du auch wählst, schreib die Regel in die Anweisungen des Agenten, damit er aufhört zu fragen. Ein Absatz in CLAUDE.md oder AGENTS.md genügt: nie nach dem Wert von Zugangsdaten fragen, nie welche in eine Datei schreiben, $NAME benutzen und dem Nutzer sagen, welche Variable er setzen soll. Wir veröffentlichen einen kleinen Skill, der genau das sagt, und er ist fünf Zeilen lang.
Wenn ein Key schon durch eine Konversation gelaufen ist
Der Reihe nach, und der erste Schritt ist nicht optional.
- Tausch ihn aus. Einen Prompt kannst du nicht zurückholen. Geh davon aus, dass der Wert kompromittiert ist, und stell einen neuen aus.
- Finde die Transkripte. Die CLI legen Konversationsdateien in deinem Home-Verzeichnis ab. Durchsuch sie nach dem alten Wert und lösche oder kürze, was passt.
- Prüf die Orte, die Text kopieren. Den Verlauf deines Zwischenablage-Managers, das Ticket oder Issue, in dem der Agent gebrieft wurde, jede Zusammenfassung, die der Agent ins Repository geschrieben hat, und
git log -p, falls der Agent commitet hat, während er ihn hielt. - Und erst dann bau die Tür. Neuer Wert hinter einer Umgebungsvariable, Referenz über den Namen, und die Anweisungen des Agenten aktualisiert, damit der nächste nicht fragt.
Schritt 4 zuletzt, denn ein sauberer Mechanismus um einen geleakten Key herum ist nur ein besser aufgeräumtes Leck.
Fragen, die Leute wirklich stellen
Warum gehört ein API-Key nie in einen Prompt an einen KI-Agenten?
Weil ein Prompt gespeichert und weitergereicht wird. Claude Code, Codex und die anderen CLI schreiben die Konversation in eine Transkriptdatei auf deiner Platte, und die Nachricht selbst geht an den Modellanbieter. Von dort steht der Key außerdem im Verlauf deiner Zwischenablage, in jedem Log, das die Nachricht mitschreibt, und in den Wiederholungen und Subagents, die die Konversation kopieren. Das musterbasierte Schwärzen erwischt, was wie sk- oder glpat- aussieht, nicht ein Datenbank-Passwort, das wie ein gewöhnliches Wort aussieht.
Wie nutzt ein KI-Coding-Agent ein Secret, das er nicht lesen kann?
Über eine Umgebungsvariable. Du legst den Wert in eine Umgebungsvariable des Prozesses, in dem der Agent läuft, und der Agent schreibt $STRIPE_SECRET_KEY in den Befehl statt des Werts. Die Shell setzt ihn ein, wenn der Befehl läuft. Der Agent sieht die Zeichen nie, also landen sie weder in seiner Konversation noch in seinem Transkript.
Kann ich ein Secret stattdessen als Kommandozeilen-Argument übergeben?
Du kannst, und du solltest nicht. Eine Kommandozeile ist über ps für jeden Prozess auf der Maschine sichtbar, sie landet im Verlauf deiner Shell, in Prozess-Logs und in jedem Diagnosewerkzeug, das den gestarteten Befehl ausliest. Eine Umgebungsvariable eines einzelnen Prozesses ist von diesem Prozess und von root lesbar, und das ist eine viel kleinere Angriffsfläche.
Wo speichert AgentsRoom die Secrets, die Agenten nutzen?
In einer einzigen Datei in deinem Home-Verzeichnis, Modus 0600, verschlüsselt über den Schlüsselbund deines Betriebssystems, nur auf dieser Maschine. Nichts wird auf einen Server synchronisiert, und es gibt keinen Knopf, der einen Wert wieder anzeigt. Die App zeigt Namen, der Agent sieht Namen, und der Wert wird nur im Hauptprozess entschlüsselt, in dem Moment, in dem ein Terminal oder ein Befehl startet.
Was passiert, wenn ich eine Secret-Referenz in eine Nachricht an den Agenten klebe?
Es wird nichts eingesetzt, und das ist Absicht. Eine Nachricht, eine Ticketbeschreibung, ein Skill und ein System-Prompt sind wörtlicher Text, also kommt eine dort geschriebene Referenz als Text beim Agenten an. Nur der Wert einer Umgebungsvariable wird eingesetzt. Wir haben das auf die harte Tour gelernt: Eine in einer Ticketbeschreibung zitierte Referenz kam früher aufgelöst in der ersten Nachricht des daraus gestarteten Agenten heraus.
Ein Key ist schon durch eine Konversation gelaufen. Was tue ich?
Du tauschst ihn als Erstes aus, vor allem anderen, denn du kannst ihn nicht zurückholen: Er liegt beim Anbieter und in der Transkriptdatei auf deiner Platte. Danach löschst oder kürzt du die Transkripte, die ihn enthalten, prüfst deinen Zwischenablage-Manager und durchsuchst das Repository, falls der Agent ihn in eine Datei geschrieben hat. Erst danach legst du den neuen Wert hinter eine Umgebungsvariable.
Die kurze Fassung
Ein Agent muss deinen Key nicht lesen. Er braucht einen Prozess, dessen Umgebung ihn schon enthält.
Speichere den Wert einmal, außerhalb des Repositorys, verschlüsselt vom Betriebssystem. Referenziere ihn über seinen Namen dort, wo die Umgebung gebaut wird. Lass den Agenten $NAME schreiben. Halte jeden anderen Kanal wörtlich, auch die, in denen das Einsetzen bequem gewesen wäre, denn die bequemen Kanäle sind genau die, die gespeichert und weitergereicht werden.
Und wenn du es falsch machst, und das wirst du, tausch zuerst aus und räum danach auf.
AgentsRoom herunterladen
Führe alle deine KI-Agenten aus, in all deinen Projekten, aus einem einzigen Fenster.
Companion-App: Agenten auch unterwegs im Blick behalten
Nutze Claude, Codex, Antigravity CLI oder einen anderen KI-Anbieter.
Bugs und Wünsche direkt in dein öffentliches Backlog schicken.
Weiterlesen
Wie man 3 bis 8 Coding Agents parallel ausführt, ohne den Überblick zu verlieren
Mehrere Claude Code oder Codex Agents gleichzeitig zu starten, ist einfach. Die Kontrolle zu behalten, ist der Punkt, an dem es scheitert. Hier ist die Methode, die tatsächlich funktioniert.
Zum ArtikelRoutines in Claude Code: Was in der Cloud läuft, was auf deiner Maschine bleibt und wie du wählst
Routines sind der Weg von Claude Code, einen gespeicherten Prompt ohne dich auszuführen: nach Zeitplan, auf einen API-Aufruf hin oder bei einem GitHub-Ereignis, als Cloud Session auf einem frischen Klon deines Repositorys. Sie sind in der Research Preview. Claude Code hat außerdem zwei lokale Wege, Arbeit zu planen, die geplanten Aufgaben der Desktop-App und /loop, und die drei verhalten sich nicht gleich: minimales Intervall, Zugriff auf deine lokalen Dateien, Berechtigungsabfragen, was passiert, wenn der Laptop schläft. Dieser Leitfaden stellt die drei mit den Grenzen aus der Dokumentation vor und erklärt dann, warum unsere eigenen sieben nächtlichen Agenten stattdessen auf einer lokalen Maschine laufen.
Zum ArtikelEin Claude-Konto auf zwei Rechnern oder zu zweit: Was funktioniert
Ein Claude-Konto lässt sich auf allen deinen Geräten anmelden, und alle zehren von denselben 5-Stunden- und Wochenlimits, Claude und Claude Code zusammen. Zu zweit auf einem Konto verstößt gegen die Bedingungen von Anthropic, und ein Familienabo gibt es nicht. Was wir am 25. Oktober 2026 geprüft haben und wie du siehst, welcher Rechner was verbraucht hat.
Zum Artikel