# MCP-Agenten von Umgebungsvariablen lösen: Zugangsdaten migrieren

Zugangsdaten in der Umgebung eines MCP-Servers abzulegen, ist eine Abkürzung. Sie wird gefährlich, sobald ein Agent Befehle ausführen, Dateien untersuchen, Fehler analysieren oder Hilfsprozesse starten kann. Das Problem ist nicht, dass jeder Agent absichtlich ein Token ausgibt. Das Problem ist, dass du einem Prozess, der zum Erkunden und Handeln gebaut wurde, ein wiederverwendbares Geheimnis gibst und ihn dann aufforderst, sich so zu verhalten, als könne er es nicht sehen.

Verlagere die Berechtigung aus dem Agent-Prozess heraus. Lass den Agenten eine klar definierte HTTP- oder SSH-Aktion anfordern, während eine lokale Komponente mit den Zugangsdaten diese ausführt. Die Änderung klingt klein, zwingt dich aber dazu, festzuhalten, was jedes Tool tatsächlich tut, welche Identität es braucht und wie du nachweist, dass das Token nicht unbemerkt in den neuen Pfad gelangt ist.

Ich habe Migrationen scheitern sehen, weil jemand `API_TOKEN` aus einer Konfigurationsdatei entfernte, es aber in einem Shell-Profil, einem Task-Runner oder einer kopierten Projektvorlage stehen blieb. Der API-Aufruf funktionierte weiter, alle waren beruhigt und der Agent besaß noch immer die alten Zugangsdaten. Eine saubere Migration behandelt Auffinden, Ersetzen und Nachweis als getrennte Aufgaben.

## Umgebungsvariablen geben dem Agenten mehr Berechtigung als das Tool braucht

Eine Umgebungsvariable gehört nicht zu einer einzelnen Anfrage. Sie gehört zu einem Prozess und oft zu allem, was dieser Prozess startet. Wenn ein MCP-Client einen Server mit `SERVICE_TOKEN` in seiner Umgebung startet, kann der Server den Wert lesen. Das gilt auch für Kindprozesse, die ihn erben, sofern ihn nicht jemand sorgfältig entfernt. Debug-Befehle, Absturzberichte, Testdaten und eine versehentliche `env`-Ausgabe können aus einer lokalen Bequemlichkeit einen dauerhaften Leak machen.

Das unterscheidet sich davon, dass ein Tool ein authentifiziertes Ergebnis erhält. Ein Ergebnis kann eine Repository-Liste, ein Deployment-Status oder eine Fehlermeldung sein. Der Agent braucht diese Informationen, um weiterzuarbeiten. Das Bearer-Token, mit dem die Anfrage möglich wurde, braucht er nicht.

Die Unterscheidung verschwimmt, weil beide Designs dieselbe erfolgreiche Anfrage erzeugen können. Sie sind nicht gleichwertig:

- **Besitz von Zugangsdaten** bedeutet, dass der Agent ein Geheimnis außerhalb des vorgesehenen Tool-Aufrufs verwenden, kopieren, verändern oder nach außen übertragen kann.
- **Aktionsberechtigung** bedeutet, dass der Agent einen vertrauenswürdigen lokalen Ausführer bitten kann, eine Anfrage unter festgelegten Kontrollen auszuführen.
- **Zugriff auf Ergebnisse** bedeutet, dass der Agent die Antwort sieht, die er für seine nächste Entscheidung braucht.

Wer diese Unterscheidung ignoriert, landet bei einer häufigen schlechten Empfehlung: Tokens in einem Secret-Manager ablegen und sie beim Start in die Umgebung des Agenten einfügen. Das verbessert vielleicht die Speicherung im Ruhezustand, ändert aber nicht die Laufzeitgrenze. Der Agent erhält das Token weiterhin.

Die MCP-Spezifikation beschreibt ein Protokoll für Clients, Server und Tools. Sie erklärt Umgebungsvariablen nicht zur Grenze für Zugangsdaten. Behandle sie nur dann als Transport für lokale Konfiguration, wenn der empfangende Prozess dem zugrunde liegenden Geheimnis bereits vertrauen darf. Autonome Coding-Agenten erfüllen diesen Maßstab oft nicht.

## Erstelle vor jeder Konfigurationsänderung ein Tool-Inventar

Beginne mit einem schriftlichen Inventar. Bearbeite nicht zuerst JSON-Dateien, denn Konfigurationsdateien zeigen selten das vollständige Bild. Ein Tool kann eine Variable direkt lesen, einen Wrapper aufrufen, der eine andere liest, oder von einem Kommandozeilen-Client abhängen, der Zugangsdaten aus einer Datei im Home-Verzeichnis lädt.

Notiere für jedes MCP-Tool den Tool-Namen, den Befehl, das Ziel, die Authentifizierungsmethode, den Besitzer der Zugangsdaten, den Berechtigungsumfang und die harmlose Anfrage, die du zum Testen verwenden kannst. Halte außerdem fest, wo das Geheimnis derzeit in den Prozess gelangt: Client-Konfiguration, Shell-Startdatei, `.env`-Datei, CI-Export, Passwortmanager-Befehl oder Hilfsskript.

Ein kompaktes Inventar könnte so aussehen:

| Tool | Aktionsziel | Bisheriger Geheimnispfad | Neue Grenze | Test |
| --- | --- | --- | --- | --- |
| Issuesuche | Issue-API | `ISSUES_TOKEN` in der Client-Konfiguration | lokale HTTP-Aktion | ein bekanntes Projekt auflisten |
| Deployment-Status | Deployment-API | `.env.local` | lokale HTTP-Aktion | Servicestatus lesen |
| Host-Diagnose | SSH-Host-Alias | Pfad zur privaten Schlüsseldatei | lokale SSH-Aktion | `uname` ausführen |
| Paketveröffentlichung | Registry-API | Shell-Export | lokale HTTP-Aktion | Paketmetadaten lesen |

Verstecke weitreichende Rechte nicht hinter vagen Namen wie `prod-token` oder `default-key`. Gib dem Zugangsdaten-Eintrag einen Namen, der einem Operator sagt, was er darf und wohin er führt. `deploy-api-production-read` ist weniger hübsch, aber bei einer hektischen Prüfung deutlich sicherer.

Das Inventar zeigt auch, ob ein Zugangsmittel überhaupt existieren sollte. Ich habe schreibberechtigte Tokens an Tools gefunden, die nur Projektmetadaten lesen, weil jemand eine Entwicklungsumgebung kopiert hatte. Eine Migration ist der richtige Zeitpunkt, engere Zugangsdaten auszustellen. Sie ist kein Grund, jede alte Berechtigung in einen schöneren Container zu verpacken.

## Entferne die Geheimnisinjektion, statt sie zu tarnen

Eine migrierte Konfiguration darf das Geheimnis nicht mehr an den Agenten oder dessen MCP-Server liefern. Ein Literal-Token durch `${SERVICE_TOKEN}`, `$(secret-tool lookup ...)` oder den Pfad zu einer ungeschützten Datei zu ersetzen, erfüllt diese Anforderung nicht. Du hast die Schreibweise geändert, nicht die Berechtigung.

Suche zuerst nach aktuellen Verweisen. Im Projektverzeichnis findet dieser Befehl viele offensichtliche Fälle:

```sh
rg -n --hidden --glob '! .git' 'API[_-]?KEY|API[_-]?TOKEN|SECRET|PASSWORD|PRIVATE[_-]?KEY|Authorization: Bearer' .
```

Die erwartete Ausgabe besteht aus Einträgen in der Form `Datei:Zeile:übereinstimmender Text`. Füge diese Ausgabe nicht in ein Ticket ein, wenn sie aktive Werte enthält. Verwende sie für eine Liste der nötigen Maßnahmen und durchsuche anschließend die üblichen benutzerbezogenen Speicherorte separat, etwa Shell-Profile und MCP-Client-Einstellungen.

Vergleiche danach die für den alten Agent-Prozess sichtbare Umgebung mit der Umgebung des neuen Prozesses. Liste in einer kontrollierten Test-Shell nur die Namen auf, ohne Werte auszugeben:

```sh
env | cut -d= -f1 | sort | rg 'TOKEN|KEY|SECRET|PASSWORD'
```

Die alten Namen müssen aus dem Prozess verschwunden sein, der den Agenten startet. Wenn dort `SERVICE_TOKEN` auftaucht, ist die Migration unvollständig, auch wenn der neue Gateway-Pfad funktioniert.

Vermeide das verlockende halbe Design, bei dem der MCP-Server das Token besitzt, der primäre Agent aber nicht. Das reduziert zwar einen Offenlegungspfad, doch der Server erhält weiterhin unbeschränkten Besitz der Zugangsdaten. Wenn dieser Server beliebige Befehle ausführen, Plugins laden oder Logs schreiben kann, hast du das Problem nur in einen Prozess verschoben, der oft weniger genau geprüft wird.

Verwende nicht geheime Konfiguration für die Zielauswahl. Eine Basis-URL, ein Host-Alias, eine Konto-ID und eine Bezeichnung für die Zugangsdaten können in die Konfiguration gehören, solange sie keinen Zugriff gewähren. Bewahre die authentifizierenden Daten in einem lokalen Tresor auf, den der Agent nicht als Datenquelle abfragen kann.

## Den neuen Pfad als Anfragen, Zugangsdaten und Ergebnisse modellieren

Der neue Ablauf braucht eine klare Grenze: Der Agent benennt eine Aktion und liefert gewöhnliche Anfragedaten, der lokale Ausführer wählt die Zugangsdaten aus und fügt sie ein, anschließend gibt er die Antwort zurück. Der Agent erhält niemals einen Platzhalter, den er in das Geheimnis auflösen kann.

Bei einem HTTP-Tool musst du die öffentliche Anfragenform von der privaten Authentifizierung trennen. Der Agent kann diese Anfrage anfordern:

```text
GET https://api.example.internal/projects/atlas/issues?state=open
```

Der lokale Ausführer fügt die passende Bearer-, Basic- oder benutzerdefinierte Header-Authentifizierung ein und gibt Antworttext und Status zurück. Wenn der Agent einen nicht genehmigten Host, eine nicht erlaubte Methode oder ein falsches Konto anfordert, muss der Ausführer die Anfrage ablehnen, statt zu raten, welches Zugangsmittel passt.

Bei SSH enthält die Anfrage einen Host und einen Befehl, während der private Schlüssel lokal bleibt. Das ist wichtig, weil SSH-Werkzeuge Berechtigungen leicht über Pfade, Agent-Weiterleitung, Konfigurations-Includes und geerbtes `SSH_AUTH_SOCK` einschleusen. Ein Pfad zu einem privaten Schlüssel in der Tool-Konfiguration ist kein sicherer Ersatz. Der Agent kann die Datei häufig lesen, kopieren oder den verwendenden Befehl verändern.

Sallyport verwendet diese Form über seinen integrierten `sp mcp`-stdio-Shim: Agenten führen MCP-Aufrufe aus, während die App HTTP-API-Aufrufe und SSH-Befehle erledigt, ohne API-Schlüssel oder SSH-Schlüssel an den Agenten zu übergeben. Diese Grenze ist nur dann nützlich, wenn du auch die alte Umgebungsinjektion entfernst.

Mach den lokalen Ausführer nicht zu einem universellen Proxy mit einem allmächtigen Zugangsmittel. Die Anfrage eines Agenten sollte ein konfiguriertes Ziel und Zugangsmittel nennen, nicht eine beliebige URL plus eine Token-Auswahl liefern. Andernfalls kann ein prompt-injizierter Agent ein legitimes Zugangsmittel zum Signieren einer Anfrage an einem Ort verwenden, den du nie vorgesehen hast.

## Wähle Genehmigungspunkte, die Menschen noch bewerten können

Menschliche Genehmigung funktioniert, wenn jemand versteht, was er genehmigt. Sie scheitert, wenn ein lang laufender Agent eine Reihe nahezu identischer Abfragen erzeugt, bis die Person sie einfach durchklickt. Das ist vorhersehbar und ein Designfehler, kein Versagen der Aufmerksamkeit eines Operators.

Verwende eine Genehmigung pro Sitzung, wenn du festlegen musst, dass ein bestimmter Agent-Prozess die konfigurierten Aktionen während eines Laufs verwenden darf. Die Genehmigung sollte den Prozess so identifizieren, dass du den echten Client von einer Imitation unterscheiden kannst. Ein Prozessname allein ist ein schwacher Beleg, weil jedes Programm einen vertrauten Namen wählen kann.

Reserviere eine Genehmigung pro Aufruf für Zugangsdaten, deren Folgen eine neue menschliche Entscheidung erfordern. Schreibzugriff auf die Produktion, ein destruktiver Host-Befehl und eine zahlungsnahe API rechtfertigen diesen Aufwand. Eine schreibgeschützte Issuesuche normalerweise nicht. Wenn jeder Tool-Aufruf eine Entscheidung verlangt, lesen Operatoren die Entscheidung irgendwann nicht mehr.

Ein gesperrter Tresor muss Anfragen ablehnen, selbst wenn ein zuvor genehmigter Agent weiterläuft. Genau dafür gibt es die Tresorgrenze. Ein unbeaufsichtigter Prozess darf seine Berechtigung nicht allein deshalb behalten, weil er sie früher am Nachmittag hatte.

Sallyport hat drei feste Kontrollen statt einer Richtliniensprache: eine Tresorsperre, die Autorisierung jedes neuen Agent-Prozesses und eine optionale Genehmigung bei jedem Schlüssel. Das feste Modell ist bewusst enger als eine Regel-Engine. Dadurch gibt es weniger ausgeklügelte Regeln, die ein müder Operator falsch schreiben kann.

## Erfolg und Geheimhaltung als getrennte Aussagen testen

Eine erfolgreiche Tool-Antwort beweist nur, dass etwas die Anfrage authentifiziert hat. Sie beweist nicht, dass der Agent die Zugangsdaten nicht erhalten konnte. Führe eine Migrationprüfung durch, die beide Aussagen testet, zunächst mit einer risikoarmen Aktion.

Verwende für jedes Tool diese Abfolge:

1. Sperre den lokalen Tresor und rufe das Tool auf. Der Aufruf muss fehlschlagen, ohne auf ein Token aus der Umgebung zurückzugreifen.
2. Entsperre den Tresor, starte einen frischen Agent-Prozess und genehmige ihn, falls deine Einrichtung das verlangt. Führe die harmlose Anfrage aus, die du im Inventar festgelegt hast.
3. Prüfe das Aktionsjournal oder den serverseitigen Audit-Eintrag auf genaues Ziel, Konto, Methode und Ergebnisstatus. Stelle sicher, dass die Aktion protokolliert wird, ohne das Geheimnis zu protokollieren.
4. Untersuche aus dem erlaubten Ausführungspfad des Agenten seine Umgebung auf den alten Variablennamen und seinen Arbeitsbereich auf den Token-Präfix. Das Token darf an keiner dieser Stellen erscheinen.
5. Starte den Agent-Prozess neu und wiederhole die Anfrage. So stellst du sicher, dass du nicht versehentlich auf einen vom alten Shell-Prozess geerbten Zustand angewiesen bist.

Der erste Schritt deckt einen subtilen, aber gravierenden Fehler auf. Teams richten manchmal einen Tresorpfad ein, lassen die alte Variable aber als Rückfalloption bestehen. Wenn der Tresor gesperrt ist, funktioniert das Tool trotzdem. Das wirkt zuverlässig, bis dieselbe Rückfalloption in einem CI-Worker, einem kopierten Repository oder einem Agent-Transkript auftaucht.

Bitte den Agenten nicht darum, als Hauptnachweis alle Umgebungsvariablen auszugeben. Dieser Test schafft selbst einen Offenlegungspfad und kann das alte Token in den Gesprächsverlauf bringen. Prüfe Namen aus einer kontrollierten Shell und verwende bei Bedarf eine bewusst nicht geheime Marker-Variable für Probeläufe, um das Vererbungsverhalten zu testen.

Teste bei SSH einen Befehl, der harmlose Informationen zur Systemidentität zurückgibt, statt einen Befehl zu verwenden, der den Zustand verändert. Bestätige das Ergebnis und prüfe anschließend, dass die Agent-Konfiguration einen Host-Verweis statt des privaten Schlüsselmaterials enthält. Untersuche außerdem die SSH-Konfiguration auf `ForwardAgent yes`. Agent-Weiterleitung kann einem entfernten Host einen Weg geben, lokale Identitäten zu verwenden. Das ist ein eigenes Risiko und etwas anderes als die Offenlegung der privaten Schlüsseldatei.

## Audit-Einträge müssen die Rekonstruktion strittiger Aktionen ermöglichen

Ein Aktionslog ist dann nützlich, wenn es eine unangenehme Frage am Montagmorgen beantwortet: Welche Agent-Sitzung hat diese Anfrage über welches konfigurierte Zugangsmittel ausgeführt, und hat ein Mensch sie genehmigt? Eine vage Zeile wie `tool succeeded` klärt nichts.

Führe ein Sitzungsprotokoll für Agent-Läufe und ein Aufrufprotokoll für einzelne Aktionen. Das Sitzungsprotokoll zeigt, wann ein Prozess begann, welche Identität du genehmigt hast und wann du sie widerrufen hast. Das Aufrufprotokoll zeigt, was unter dieser Sitzung geschah. Vermische beides nicht zu einem einzigen flachen Ereignisstrom, wenn du einen Lauf unter vielen untersuchen musst.

Manipulationsnachweise sind wichtig, weil ein Agent mit lokaler Befehlsausführung nach einer unerwünschten Aktion versuchen kann, seine Spuren zu beseitigen. Ein hashverkettetes Log ermöglicht dir, geänderte oder gelöschte Historie zu erkennen. Das funktioniert aber nur, wenn die Prüfung nicht davon abhängt, dass der Agent kooperiert.

Sallyport erzeugt beide Journale aus einem verschlüsselten, schreibgeschützten, hashverketteten Audit-Log und unterstützt die Offline-Prüfung der Kette über Chiffretext mit diesem Befehl:

```sh
sp audit verify
```

Ein erfolgreiches Ergebnis sollte bestätigen, dass die Prüfung abgeschlossen wurde. Bei einem Fehler musst du das Journal als verdächtig behandeln, bis du den Bruch verstanden hast. Die Prüfung sagt nicht, ob die Aktion klug war. Sie sagt, ob die Aufzeichnung noch durchgängig ist.

Halte Audit-Daten aus Modell-Prompts und normalen Chat-Transkripten heraus. Der Datensatz kann vertraulichen Anfragekontext oder Metadaten der Antwort enthalten, auch wenn er nie das Zugangsmittel enthält. Der Zugriff für Untersuchungen darf nicht zu einer Hintertür für beiläufiges Browsen werden.

## Rotation ist die Bereinigung, die deine Migrationsabsicht beweist

Sobald jeder neue Pfad seine Tests besteht, rotierst du das alte Zugangsmittel. Es gültig zu lassen, weil «wir vielleicht zurückrollen müssen», verlängert den Zeitraum, in dem vergessene Konfigurationen sich noch authentifizieren können. Baue den Rückweg auf einem separat kontrollierten Ersatz auf, nicht auf einem Geheimnis, das du bereits in lokalen Umgebungen verteilt hast.

Die Reihenfolge der Rotation ist wichtig. Erstelle das neue Zugangsmittel mit begrenztem Umfang, speichere es lokal, validiere den neuen Pfad, entferne die alte Geheimnisinjektion und widerrufe dann das alte Zugangsmittel. Wenn ein altes Token möglicherweise in die Versionsverwaltung, eine Chatnachricht, ein Support-Ticket oder eine Build-Ausgabe gelangt ist, widerrufe es zuerst und nimm den Ausfall in Kauf, während du sicheren Zugriff wiederherstellst.

Wiederhole die Suche nach der Sperrung. Du suchst nach veralteten Verweisen, nicht nach aktiven Geheimniswerten. Entferne tote Variablennamen aus Beispieldateien, Onboarding-Dokumenten, Shell-Profilen, Task-Skripten und Testanweisungen. Künftige Entwickler kopieren Beispiele mit erstaunlicher Treue.

Hinterlasse zum Schluss einen bewusst vorgesehenen Fehlertest in deinen Betriebshinweisen: Sperre den Tresor und führe einen harmlosen Tool-Aufruf aus. Wenn der Aufruf gelingt, hat jemand eine Umgehung wieder eingeführt. Diese einzelne Prüfung entdeckt mehr fehlerhafte Migrationen als ein weiteres ausgearbeitetes Architekturdiagramm.

## Behandle weitreichende Zugangsdaten als Designfehler des Tools

Ein Token in einen Tresor zu verschieben, macht ein weitreichendes Token für einen Agenten nicht passend. Es ändert nur, wer es besitzt. Ein Tool, das Projekt-Issues abfragen kann, sollte nicht stillschweigend die Berechtigung besitzen, Projekte zu löschen, Abrechnungen zu ändern oder Produktionscode zu deployen.

Teile Tools nach tatsächlicher Arbeit und möglichen Folgen auf. Schreibgeschützte Entdeckungsaktionen können ein begrenztes Zugangsmittel und eine moderate Genehmigung verwenden. Aktionen, die den Zustand ändern, brauchen engere Bereiche, explizite Ziele und manchmal eine Zustimmung pro Aufruf. Das erleichtert auch die Überwachung eines Agenten, weil seine verfügbaren Verben zu der Aufgabe passen, die du ihm gegeben hast.

Sei misstrauisch gegenüber einem universellen `admin`-Zugangsmittel, das mit der Einfachheit des Tools begründet wird. Diese Einrichtung ist beliebt, weil sie heute Konfigurationsarbeit spart. Morgen erschwert sie die Reaktion auf Vorfälle, weil du nicht erkennen kannst, welche Anfragen diese Macht brauchten und welche sie nur geerbt haben.

Die Migration ist erfolgreich, wenn ein Agent seine vorgesehene Arbeit erledigen kann, ein gesperrter Tresor ihn stoppt, ein neuer Prozess die konfigurierte Berechtigung erst erwerben muss und kein altes Token in seiner Umgebung bleibt. Fehlt für eine dieser Aussagen ein Test, hast du eine funktionierende Demo, aber keine Grenze für Zugangsdaten.
