SSD Nodes Learn Hosting plans →
Anleitungen Matt ConnorVon Matt Connor · Aktualisiert 2026-08-25

AI-Agenten ohne geheime API-Schlüssel absichern

API-Schlüssel in Umgebungsvariablen können durch einen einzigen Tool-Aufruf abfließen. Nutzen Sie bereichsbeschränkte, kurzlebige Tokens hinter einem Credential-Gateway.

Was es bedeutet, Geheimnisse von AI-Agenten fernzuhalten

Ein AI-Agent ist ein normaler Linux-Prozess, der Befehle ausführt. Jede Umgebungsvariable, die dieser Prozess enthält, kann der von ihm ausgeführte Code lesen. Ein API-Schlüssel in der Umgebung des Agenten ist daher ein Schlüssel, den der Agent an jeden erreichbaren Host senden kann. Geheimnisse vom Agenten fernzuhalten bedeutet, ihm statt des Schlüssels eine Zugriffsmöglichkeit zu geben: ein kurzlebiges, bereichsbeschränktes Token oder einen Platzhalter, den etwas anderes an der Netzwerkgrenze durch den tatsächlichen Wert ersetzt.

Dabei geht es nicht darum, dass ein Modell feindselig wird. Der Mechanismus ist unspektakulärer. Ein Agent liest eine Webseite, eine README-Datei oder einen Issue-Kommentar mit Anweisungen und befolgt diese, weil es für ein Sprachmodell keinen Unterschied zwischen von Ihnen geschriebenem und abgerufenem Text gibt. Das ist Prompt Injection. Sobald dies geschieht, wird der Schaden genau durch eine einzige Sache begrenzt: durch das, was der Prozess lesen kann. Wenn Sie noch keine Grenze eingerichtet haben, beschreibt einen Coding-Agenten sicher auf einem Server auszuführen die Isolationsebenen, auf denen dieser Leitfaden aufbaut.

Das Bedrohungsmodell in einfachen Worten

Führen Sie dies als der Benutzer aus, unter dem Ihr Agent läuft.

tr '\0' '\n' < /proc/self/environ | grep -iE 'key|token|secret|password'

Jede von diesem Befehl ausgegebene Zeile entspricht einer HTTP-Anfrage an den Server eines Fremden. Sehen Sie sich nun an, welche Daten auf dem Datenträger in der Nähe des Agents liegen.

grep -rIl --exclude-dir=.git -e 'API_KEY' -e 'SECRET' ~/projects
find ~ -maxdepth 3 -name '.env' -o -name 'credentials' -o -name '*.pem'

Ein Agent mit einer Shell benötigt keinen ausgeklügelten Exploit, um diese Daten nach außen zu übertragen. Vier gewöhnliche Wege reichen aus. Alle vier sehen im Log wie normale Arbeit aus:

  • Ein ausgehendes curl oder fetch an einen beliebigen Host, wobei der Wert in einer Query-Zeichenfolge steht.
  • Ein git commit und git push an ein Repository, in das der Agent schreiben kann.
  • Ein Installationsskript eines Pakets, das beliebigen Code unter dem Benutzer des Agents ausführt.
  • Eine DNS-Abfrage für einen Hostnamen, der den Wert enthält. Dieser Weg funktioniert auch dann, wenn der ausgehende HTTP-Verkehr blockiert ist.

Sie können dieses Problem nicht durch eine nachträgliche Prüfung lösen. Stellen Sie stattdessen sicher, dass keine wertvollen Daten erreichbar sind.

Ein Secret im Arbeitsbaum befindet sich im Kontextfenster

Ein Agent liest Dateien. Eine .env-Datei im Repository, in dem er arbeitet, wird gelesen. Sobald sie gelesen wurde, befindet sie sich im Kontextfenster. Das bedeutet, dass sie im Transkript, in jedem von Ihnen geführten Log und in allem enthalten ist, was der Agent anschließend schreibt.

Zuvor lag der Schlüssel im Arbeitsbaum des Agenten:

cd ~/projects/billing
cat .env
# STRIPE_SECRET_KEY=sk_live_...
# DATABASE_URL=postgres://app:hunter2@db.internal:5432/billing

Danach wurde die Datei außerhalb seiner Reichweite verschoben:

sudo install -d -m 750 -o root -g agent-review /etc/agent-review
sudo install -m 640 -o root -g agent-review ~/projects/billing/.env /etc/agent-review/billing.env
rm ~/projects/billing/.env

Der Benutzer des Agenten kann die Datei nicht mehr öffnen, weil der Arbeitsbaum sie nicht mehr enthält. Deny-Regeln in der eigenen Konfiguration des Agenten sind eine zusätzliche Schutzschicht, aber nicht die erste. Claude Code liest Berechtigungsregeln aus .claude/settings.json im Projekt:

{
  "permissions": {
    "deny": ["Read(./.env)", "Read(./secrets/**)", "Read(./**/*.pem)"]
  }
}

Das verhindert, dass der Agent beim Erkunden versehentlich eine Datei öffnet. Es verhindert jedoch nicht, dass eine eingeschleuste Anweisung base64 .env ausführt, weil es sich dabei um einen Shell-Befehl und nicht um das Lesen einer Datei handelt. Ob Sie vor der Ausführung dieses Befehls gefragt werden, hängt vom Berechtigungsmodus der Sitzung ab. Außerdem wird der automatische Modus im August 2026 zum Standard für Claude Code, sodass ein Server, den Sie nicht überwachen, mehr dieser Befehle unbeaufsichtigt ausführt. Dieselbe Einschränkung gilt für alles, was die Gewohnheiten des Agenten und nicht seine Berechtigungen beeinflusst: Eine Fähigkeit, die den Agenten auf die kleinstmögliche funktionierende Änderung beschränkt, verhindert, dass ein Lauf Dateien öffnet, die er nicht hätte öffnen dürfen. Dennoch handelt es sich weiterhin nur um eine Empfehlung, von der das Modell abgebracht werden kann. Betrachten Sie die Konfiguration als Leitplanke und die Dateisystemberechtigung als Mauer. Dieselbe Trennung gilt innerhalb von Containern: Umgebungsdateien und Secrets in Docker Compose behandelt die entsprechende Variante dieses Problems eine Ebene tiefer.

Geben Sie jedem Agenten einen eigenen Benutzer ohne privilegierte Rechte

Wenn der Agent unter Ihrem Benutzerkonto läuft, übernimmt er Ihre SSH-Schlüssel, Ihre Cloud-Anmeldedaten und Ihre Shell-Historie. Ein separater Benutzer erfordert einen Befehl und entfernt all das.

sudo adduser --disabled-password --gecos "" agent-review
sudo chmod 700 /home/agent-review
sudo -u agent-review cat ~/.ssh/id_ed25519

Die letzte Zeile muss mit cat: /home/you/.ssh/id_ed25519: Permission denied fehlschlagen. Wenn stattdessen ein Schlüssel ausgegeben wird, ist Ihr Home-Verzeichnis für die Gruppe oder alle Benutzer lesbar. chmod 700 ~ behebt das. Fügen Sie den Agentenbenutzer nicht zu sudo hinzu. Geben Sie ihm keine NOPASSWD-Regel, die über den tatsächlich benötigten einzelnen Befehl hinausgeht. Benutzer mit geringsten Rechten auf einem VPS beschreibt die Details zu Gruppen und sudoers. Behalten Sie diese Trennung bei, sobald Sie mehr als eine Sitzung auf dem Server ausführen. Eine Claude-Code-Sitzung kann Text direkt an eine andere senden. Alles, was die erste Sitzung enthält, kann in einer einzelnen Nachricht diesen Kanal passieren.

Eine weitere Zugriffsschranke ist auf einem Cloud-VPS sinnvoll. Der Instanz-Metadatendienst antwortet unter einer festen Link-Local-Adresse. Häufig gibt er jedem anfragenden Prozess Rollen-Anmeldedaten aus.

sudo iptables -A OUTPUT -m owner --uid-owner agent-review -d 169.254.169.254 -j REJECT

Prüfen Sie dies von der Seite des Agenten aus. sudo -u agent-review curl -s --max-time 3 http://169.254.169.254/ sollte nichts ausgeben und mit einem Fehlercode ungleich null beendet werden, weil das Paket verworfen wird, bevor es den Server verlässt.

Credential an der Grenze injizieren

Das Muster, das dieses Problem tatsächlich löst, ist die Credential-Injektion. Der Agent hält niemals einen echten Schlüssel. Er sendet seine Anfrage über ein lokales Gateway. Das Gateway ersetzt unterwegs einen Platzhalter durch das echte Secret. Das Secret liegt im Speicher des Gateways, in einem anderen Prozess und unter einem anderen Benutzer.

OneCLI ist eine quelloffene Implementierung dieses Verfahrens. Das Projekt steht unter der Apache-2.0-Lizenz und läuft als Container neben dem Agenten. Im Juli 2026 dokumentiert das Projekt diesen Aufbau:

git clone https://github.com/onecli/onecli.git
cd onecli
docker compose -f docker/docker-compose.yml up -d --wait

Das Dashboard lauscht auf Port 10254 und das Gateway auf Port 10255. Sie speichern das echte Credential einmal und geben jedem Agenten anstelle des Schlüssels einen Platzhalterwert sowie ein eigenes, eingeschränkt gültiges Zugriffstoken. Der Agent sendet dieses Token in einem Proxy-Authorization-Header. Das Gateway ordnet die ausgehende Anfrage anhand von Host und Pfad zu, entschlüsselt das passende Credential und ersetzt den Platzhalter. Die Umgebung des Agenten enthält damit nichts, was sich zu stehlen lohnt.

Der entscheidende Vorteil ist nicht die Verschlüsselung. Entscheidend ist, dass die Frage „Welches Credential hat dieser Agent wann verwendet?“ zu einer Log-Abfrage wird. Sie lesen einen Audit-Trail aus, statt zu ermitteln, in welcher von sechs Umgebungen eine Kopie des Schlüssels lag.

Das Geheimnis an den Prozess übergeben, nicht an die Umgebung

Wenn Sie den Agent unter systemd ausführen, benötigen Sie überhaupt keine Umgebungsvariablen. LoadCredential= legt das Geheimnis in einem privaten Verzeichnis ab, auf das nur dieser Dienst zugreifen kann. In der Unit-Datei ist es als %d verfügbar und innerhalb des Prozesses als $CREDENTIALS_DIRECTORY. Der Wert erscheint nie in /proc/<pid>/environ. Daher kann ps eww ihn nicht anzeigen. Das Verzeichnis wird gelöscht, sobald der Dienst beendet wird.

Verschlüsseln Sie die Zugangsdaten zunächst für den Computer. Diese Befehle stammen aus der systemd-Dokumentation und funktionieren mit systemd 250 oder neuer. Das umfasst Ubuntu 24.04 und Debian 13:

echo -n 'sk-example-value' > /tmp/plain.txt
sudo systemd-creds encrypt --name=api_key /tmp/plain.txt /etc/credstore/api_key.cred
shred -u /tmp/plain.txt
sudo systemd-run -P --wait -p LoadCredentialEncrypted=api_key:/etc/credstore/api_key.cred \
  systemd-creds cat api_key

Der letzte Befehl gibt sk-example-value aus. Damit ist nachgewiesen, dass die verschlüsselte Datei auf diesem Host entschlüsselt werden kann. Verweisen Sie anschließend in der Unit darauf:

[Service]
User=agent-review
LoadCredentialEncrypted=api_key:/etc/credstore/api_key.cred
Environment=AGENT_KEY_FILE=%d/api_key
ExecStart=/usr/local/bin/agent-worker

Ihr Agent-Code öffnet die Datei unter $AGENT_KEY_FILE, sobald er den Wert benötigt. Das Lesen einer Datei dauert nur einen Moment. Eine Umgebungsvariable bleibt während der gesamten Lebensdauer des Prozesses bestehen und ist in jedem von ihm gestarteten Kindprozess verfügbar.

Kurzlebige Tokens sind langlebigen Schlüsseln vorzuziehen

Ein Schlüssel ohne Ablaufdatum bleibt gültig, wenn er Monate später in einem Log oder Transkript auftaucht. Wenn der Dienst ein Session-Token anbietet, verwenden Sie dieses und setzen Sie die kürzeste für die Aufgabe ausreichende Gültigkeitsdauer.

aws sts assume-role \
  --role-arn arn:aws:iam::123456789012:role/agent-readonly \
  --role-session-name agent-review \
  --duration-seconds 900

Fünfzehn Minuten ist die kürzeste von AWS STS (security token service) akzeptierte Dauer und reicht normalerweise für eine einzelne Agent-Aufgabe aus. Geben Sie dem Agent-Benutzer für GitHub einen eigenen gh-Login mit einem fein granularen Token, das auf das einzelne Repository beschränkt ist, in dem er arbeitet. Dadurch liefert gh auth token innerhalb dieser Sitzung etwas, das auf nichts anderes zugreifen kann. Beschränken Sie zuerst nach Ressource und anschließend nach Zeit.

Prüfen und weiter prüfen

Nach jeder Änderung an der Konfiguration eines Agenten sollten Sie drei Prüfungen ausführen. Führen Sie sie als Benutzer des Agenten aus, nicht als Sie selbst.

sudo -u agent-review env | grep -iE 'key|token|secret'
sudo -u agent-review ls -la /home/you/ 2>&1 | head -3
sudo -u agent-review curl -s -o /dev/null -w '%{http_code}\n' --max-time 5 https://api.github.com/user

Die erste Prüfung sollte überhaupt keine Ausgabe erzeugen. Die zweite sollte ls: cannot open directory '/home/you/': Permission denied ausgeben. Die dritte zeigt, welche Identität der Netzwerkpfad des Agenten präsentiert. Genau diese Frage soll das Gateway-Muster beantworten: Ein 401 bedeutet, dass der Agent keine eigenen GitHub-Anmeldedaten mitführt. Ein 200 bedeutet, dass er welche mitführt. Sie sollten daher wissen, um welches Token es sich handelt. Wenn Sie Agenten unbeaufsichtigt ausführen, behandelt Kosten für KI-Agenten auf einem VPS begrenzen die zugehörigen Budgetgrenzen für diese Zugriffsbeschränkungen.

FAQ

Kann ich dem Modell einfach vertrauen, dass es meine Schlüssel nicht weitergibt?

Nein, denn in diesem Bedrohungsmodell ist das Modell nicht der Angreifer. Der Agent liest Text aus Webseiten, Repositories und Issue-Trackern. Dieser Text kann Anweisungen enthalten. Das Modell kann Ihre Anweisungen nicht zuverlässig von abgerufenen Texten unterscheiden. Jede Kontrolle, die davon abhängt, dass das Modell die richtige Entscheidung trifft, versagt, sobald eine eingeschleuste Anweisung überzeugend formuliert ist. Die Kontrolle muss daher stattdessen im Betriebssystem oder im Netzwerk umgesetzt werden.

Sind Umgebungsvariablen für Agent-Secrets wirklich so problematisch?

Sie sind in einer bestimmten Hinsicht problematisch: Sie werden vererbt. Jeder vom Agenten gestartete Kindprozess erhält eine Kopie. Dazu gehören Build-Skripte, Test-Runner und Hooks für die Paketinstallation. Die Variablen sind über /proc/<pid>/environ außerdem für denselben Benutzer lesbar. Alles, was der Agent ausführt, kann sie daher lesen, ohne dass der Agent sie weitergeben muss. Eine Datei, die erst zum Verwendungszeitpunkt gelesen wird, begrenzt die Offenlegung auf diesen Zeitpunkt. Das ist mit LoadCredential= oder einem Gateway möglich.

Ist das Problem damit gelöst, Secrets in einem Vault abzulegen?

Nur teilweise. Ein Vault löst das Speicherproblem. Wenn Sie diesen Vault selbst hosten, benötigt er eine eigene Härtung, denn ein Vaultwarden-Server wird üblicherweise über sein Admin-Token oder seine Backup-Datei kompromittiert und nicht über die verschlüsselten Einträge, die er speichert. Der letzte Schritt bleibt davon unberührt: Etwas ruft das Secret aus dem Vault ab und übergibt es dem Agenten als Umgebungsvariable. Damit befinden Sie sich wieder am Ausgangspunkt. Entscheidend ist, wer die Ersetzung vornimmt. Ruft der Agent das Secret ab, verfügt der Agent über das Secret. Führt ein Gateway oder das Init-System die Ersetzung außerhalb des Prozesses des Agenten durch, hält der Agent das Secret nie selbst.

Wie stelle ich fest, ob ein Agent bereits etwas weitergegeben hat?

Nachträglich können Sie das meistens nicht feststellen. Das spricht für ein Gateway. Ohne Gateway sind Ihre Belege auf die Shell-History, das Transkript des Agenten und ausgehende Verbindungsprotokolle verteilt. Letztere werden Sie wahrscheinlich nicht erfassen. Mit einem Credential-Gateway ist jede Verwendung eines Credentials eine einzelne Zeile mit der Identität des Agenten und einem Zeitstempel. Wenn Sie eine Weitergabe vermuten, rotieren Sie den Schlüssel zuerst und untersuchen Sie den Vorfall danach. Eine Rotation ist günstig, Gewissheit nicht.

Was sollte ich heute mindestens tun?

Verschieben Sie jede .env-Datei aus den Verzeichnissen, in denen Ihre Agenten arbeiten, und erstellen Sie für jeden Agenten einen eigenen unprivilegierten Benutzer. Diese beiden Änderungen dauern etwa zehn Minuten. Sie schließen den häufigsten Angriffsweg: Ein Agent liest eine Credential-Datei, die keinen Grund hatte, neben dem Code zu liegen. Das Gateway und kurzlebige Tokens sind der nächste Schritt, nicht der erste. Dieser Ausgangspunkt gilt für jede Agent-Laufzeitumgebung, einschließlich dem sicheren Betrieb eines autonomen Agenten auf einem VPS.