Damit Codex auf Windows-Rechnern produktiv arbeiten kann, ohne dass Nutzer entweder jede Kleinigkeit abnicken oder blind „Vollzugriff“ geben müssen, braucht es eine Sandbox, die Dateizugriffe und Netzwerkverkehr wirklich erzwingt. Genau diese Art von durchgängiger, agententauglicher Einschränkung liefert Windows nicht als fertiges Werkzeug, deshalb entstand eine eigene Windows-Sandbox-Architektur.
Übersicht:
Warum Agenten ohne OS-Grenze riskant sind
Ein Coding-Agent ist am Ende kein abstrakter Helfer, er stößt lokal Prozesse an. Läuft er mit den Rechten des angemeldeten Users, kann er prinzipiell alles, was dieser User auch darf, inklusive Dateien lesen, Dateien verändern, Git-Branches erstellen oder Tools ausführen.
Codex ist so gebaut, dass es standardmäßig möglichst nützlich bleibt, aber nicht unnötig weit greift: Lesen ist breit möglich, Schreiben soll sich auf das Projektverzeichnis beschränken, und Internetzugang ist nur dann vorgesehen, wenn er bewusst erlaubt wird. Damit diese Leitplanken mehr sind als Konvention, braucht es eine Ausführungsumgebung, die das Betriebssystem selbst durchsetzt, nicht nur die UI oder ein „Bitte halt dich dran“ in der Prozesslogik. Einen Überblick, wie Codex Aufgaben ausführt, liefert die Codex-Dokumentation.
Auf macOS und Linux existieren etablierte Mechanismen, um Prozesse zuverlässig einzuhegen, etwa Apples App-Sandbox (Apple App Sandbox) oder Linux-Ansätze wie seccomp und Tools wie bubblewrap. Unter Windows ist die Lage komplizierter, weil die passenden Bausteine entweder nicht zum Agentenmodell passen oder für den Alltag auf Entwicklerlaptops unpraktisch sind.
Warum Windows-Bordmittel nicht passten
Für die Windows-Umsetzung wurden mehrere naheliegende Wege geprüft. Jeder davon hatte ein starkes Argument, und eine entscheidende Schwäche, wenn Codex wie ein Entwickler arbeiten soll, also mit Shell, Build-Tools, Paketmanagern und wechselnden Binaries.
| Ansatz | Warum er attraktiv wirkt | Warum er für Codex scheitert |
|---|---|---|
| AppContainer | Klare OS-Grenze mit Capabilities | Für Anwendungen gedacht, die ihre benötigten Ressourcen vorab eng definieren, nicht für offene Entwickler-Workflows mit vielen Tools. Siehe AppContainer isolation. |
| Windows Sandbox | Starke Isolation über eine frische, wegwerfbare Umgebung | Arbeitet wie ein separater Desktop, Codex müsste Quellcode, Toolchains und Kontext umständlich „überbrücken“, außerdem ist die Verfügbarkeit je nach Edition eingeschränkt. Siehe Windows Sandbox. |
| Mandatory Integrity Control | Integritätslevel könnten Schreibrechte systemisch begrenzen | Die nötigen Label-Änderungen betreffen reale Dateien und verändern das Vertrauensmodell des Workspace für alle Low-Integrity-Prozesse, nicht nur für Codex. Siehe Mandatory Integrity Control. |
Aus Sicht der Praxis war der Knackpunkt immer derselbe: Codex ist kein einzelnes, vorhersehbares Programm. Es steuert beliebige Werkzeuge, und genau diese Offenheit macht eine „klassische App-Sandbox“ schwer anwendbar.
Der Prototyp ohne Adminrechte
Der erste funktionierende Ansatz sollte ohne Adminrechte auskommen, damit der Einsatz auf Firmenlaptops nicht an UAC-Prompts oder fehlenden lokalen Adminrechten scheitert. Zwei Ziele standen im Vordergrund: Schreibzugriffe sauber begrenzen und den Internetzugang möglichst zuverlässig unterbinden.
Dateischreiben präzise begrenzen
Windows bietet dafür eine Kombination, die erstaunlich gut zu „darf nur hier schreiben“ passt: Identitäten über SIDs und ein eingeschränktes Zugriffstoken. SIDs sind die internen Sicherheitskennungen, die Windows für Rechteprüfungen verwendet, Details dazu stehen in Microsofts Übersicht zu Security Identifiers.
- Eigene Sandbox-Identität: Es wurde eine künstliche SID erzeugt, die nur für die Sandbox existiert und in ACLs auftauchen kann.
- Gezielte ACLs: Diese SID bekam Schreib- und Löschrechte im aktuellen Projektordner und optional weiteren, konfigurierten Wurzelpfaden.
- Schutzinseln im Workspace: Bestimmte Unterordner, etwa Git-Metadaten oder Agenten-Ordner, wurden innerhalb des grundsätzlich beschreibbaren Bereichs explizit auf „read-only“ gesetzt.
- Write-restricted Token: Prozesse liefen mit einem restriktiven Token, das bei Schreiboperationen eine zusätzliche Prüfung erzwingt. Der Mechanismus hängt an „restricted SIDs“ und dem doppelten Access-Check, beschrieben in CreateRestrictedToken.
Netzwerk drosseln, ohne es wirklich zu sperren
Ohne Adminrechte sind harte Netzwerkregeln schwer. Deshalb wurde zunächst versucht, typische Entwickler-Tools in eine Sackgasse zu lenken, über Umgebungsvariablen und Suchpfad-Tricks. Das half gegen viele Standardfälle, war aber kein Sicherheitszaun.
- Proxy-Umleitung: Variablen wie HTTPS_PROXY oder ALL_PROXY zeigten auf 127.0.0.1:9, also absichtlich ins Leere.
- Git-Transport blockieren: Git-spezifische Proxy-Variablen und ein hart abbrechender SSH-Wrapper sollten Pulls und Installs stoppen.
- PATH-Übersteuerung: Stub-Binaries für ssh und scp sollten vor den echten Tools gefunden werden.
Das Problem ist grundsätzlich: Ein Prozess kann Umgebungsvariablen ignorieren, absolute Pfade nutzen oder direkt Sockets öffnen. Für ein System, das auch bei unfreundlichem Code standhalten soll, ist das zu wenig.
Warum der Ansatz trotzdem nicht reichte
- Setup-Kosten: ACLs auf großen Repositories zu setzen kann spürbar dauern.
- Persistente Spuren: Rechteänderungen landen im echten Dateisystem und müssen später wieder sauber verwaltet werden.
- Policy-Wechsel ist teuer: Eine Anpassung der Regeln bedeutet oft erneutes, aufwendiges ACL-Tuning.
- Netzwerk bleibt „best effort“: Genau der Teil, der bei Exfiltration kritisch ist, war nicht verlässlich.
Warum Netzwerk-Schutz die Architektur kippte
Der entscheidende Lernpunkt war: Bei Agenten ist Netzwerkzugang nicht nur Komfort, sondern ein Risikokanals. Wenn ein Agent im schlimmsten Fall Code ausführt, darf er nicht still Daten nach außen tragen.
Für echte Durchsetzung ist die Windows-Firewall das naheliegende Werkzeug. Die Dokumentation zu Regeln und deren Einsatz findet sich bei Microsoft unter Windows Firewall Rules. Praktisch zeigte sich jedoch ein Matching-Problem: Regeln lassen sich gut an Benutzer oder Programmwege binden, aber nicht so, dass sie ausschließlich für „diese eine“ Prozesshierarchie gelten, die per restricted Token gekennzeichnet ist.
Damit blieb als robustes Modell: Prozesse, die garantiert offline sein sollen, müssen als eigener Windows-Sicherheitsprinzipal laufen, damit Firewall-Regeln sauber daran andocken können. Genau diese Entscheidung machte eine Setup-Phase mit Adminrechten sinnvoll.
Die finale Sandbox mit eigenen Windows-Nutzern
Die endgültige Lösung verlagert den starken Netzwerkhebel in Windows-eigene Mechanik, indem Codex zwei lokale Konten nutzt, die nur für Sandbox-Prozesse existieren. Ein Konto ist für Offline-Ausführung gedacht und wird per Firewall auf „kein Outbound“ gesetzt, das zweite Konto dient als explizit freigeschalteter Online-Pfad.
Setup mit Adminrechten, Laufzeit ohne Dauer-Prompts
Die Einrichtung ist umfangreicher als beim Prototyp, wird aber gezielt in einen separaten Setup-Schritt gepackt, damit Codex später normal, ohne ständige UAC-Interaktionen arbeiten kann.
- Konten anlegen: Es entstehen zwei lokale Benutzer für Sandbox-Läufe, getrennt nach Offline und Online.
- Zugangsdaten sichern: Die Credentials werden lokal gespeichert und mit Windows DPAPI geschützt, etwa über CryptProtectData.
- Firewall-Regeln setzen: Für das Offline-Konto werden Outbound-Regeln so konfiguriert, dass der Netzwerkabfluss zuverlässig blockiert wird.
- Leserechte nachziehen: Weil ein separater Windows-User nicht automatisch überall lesen darf, werden für typische Systempfade zusätzliche Read-ACLs ergänzt, soweit nötig. Das passiert teilweise asynchron, um die Wartezeit zu drücken.
Warum ein eigener Command-Runner nötig wurde
Windows-Prozessstart über Benutzergrenzen ist nicht nur eine Frage von „Token bauen“, sondern auch von Privilegien und API-Semantik. Deshalb wurde die Ausführung in eine eigene Komponente ausgelagert, die bereits als Sandbox-User läuft und dann erst das finale eingeschränkte Token für den eigentlichen Kindprozess prägt.
- Anmeldung als Sandbox-User: Funktionen wie CreateProcessWithLogonW und LogonUserW bilden die Brücke in den anderen Sicherheitskontext.
- Finaler Spawn: Der Runner startet den Zielprozess dann mit einem eingeschränkten Primär-Token, wofür Windows APIs wie CreateProcessAsUserW relevant sind.
Unterm Strich besteht die Windows-Implementierung aus mehreren Binaries mit klaren Rollen: dem normalen Codex-Harness, einem Setup-Tool für den Admin-Schritt, einem Command-Runner für das Ausführen im Sandbox-User-Kontext und dem jeweiligen Kindprozess, der die eigentliche Entwickleraktion ausführt.
Praxisregel für Offline und Online
Konkretes Praxisbeispiel
Ein Agent soll in einem Repository Tests laufen lassen, eine Datei anpassen und einen Commit vorbereiten. Das funktioniert im Offline-Modus typischerweise ohne Internet, weil Lesen, Schreiben im Workspace und lokale Kommandos erlaubt sind. Wenn der Agent danach Abhängigkeiten nachladen will, etwa über einen Paketmanager, scheitert der Schritt im Offline-Modus bewusst an der Netzsperre, und es braucht eine explizite Freigabe oder einen Wechsel in den Online-Modus.
Klare Entscheidungsregel
- Offline lassen: Alles, was rein lokal ist, zum Beispiel Tests, Linter, Formatierung, Code-Suche, Git-Status, Build ohne Downloads.
- Online nur gezielt: Sobald ein Schritt externe Kommunikation erfordert, etwa Paket-Downloads, API-Calls oder Git-Pull, ist eine bewusste Entscheidung nötig, entweder per Approval oder per Wechsel in den Online-Sandbox-User.
- Stoppsignal: Schreiben außerhalb des Workspace, oder Zugriffe auf besonders sensitive Pfade, sollten als „muss bestätigt werden“ behandelt werden, selbst wenn der Befehl technisch möglich wäre.
Mini-Modell zur Einordnung
Bei Agenten-Sandboxing entscheiden drei Hebel über die reale Sicherheit: Identität, Dateirechte und Netzwerk-Egress. macOS und Linux liefern dafür eher „aus einem Guss“ passende primitives, Windows zwingt häufiger zu Komposition. Das Ergebnis wirkt komplex, ist aber eine direkte Folge der Produktanforderung: Ein Agent soll wie ein Entwickler arbeiten können, nur innerhalb einer klaren, erzwungenen Grenze.

