Implementierung einer sicheren Sandbox für lokale Agents

von Ani Betts, Yash Gaitonde & Alex Haugland in Forschung
Implementierung einer sicheren Sandbox für lokale Agents

Coding-Agents werden immer besser darin, Terminalbefehle auszuführen, um ihre Umgebung zu erkunden und Änderungen vorzunehmen. Nutzer, die diese Befehle automatisch genehmigen, schalten deutlich leistungsfähigere Agents frei – allerdings zum Preis eines erhöhten Risikos. Ein fehlgeleiteter Agent kann Datenbanken löschen, fehlerhaften Code ausliefern oder vertrauliche Informationen preisgeben.

Die Anforderung, jeden einzelnen Befehl manuell zu genehmigen, reduziert dieses Risiko, aber oft nur vorübergehend. Wenn sich Genehmigungen häufen, hören Nutzer damit auf, sie sorgfältig zu prüfen. Das verschärft sich, wenn Entwickler:innen mehrere Agents parallel ausführen und zwischen verschiedenen Genehmigungsdialogen hin- und herspringen müssen. Das Ergebnis ist Genehmigungsmüdigkeit, die den Zweck von Genehmigungen im Kern untergräbt.

In den letzten drei Monaten sind wir diesem Problem begegnet, indem wir Agent-Sandboxing auf macOS, Linux und Windows eingeführt haben. Sandboxed Agents laufen frei in einer kontrollierten Umgebung und fordern nur dann eine Genehmigung an, wenn sie diese Umgebung verlassen müssen, meist um auf das Internet zuzugreifen.

Dadurch werden Unterbrechungen drastisch reduziert. Sandboxed Agents müssen 40 % seltener angehalten werden als nicht gesandboxte, was Nutzern Stunden manueller Prüfung und Genehmigung erspart.

Sandboxed Agents müssen 40 % seltener angehalten werden als nicht gesandboxteSandboxed Agents müssen 40 % seltener angehalten werden als nicht gesandboxte

Unsere Ziele für die Sandbox

Wir haben unsere Arbeit an der Sandbox mit dem Ziel begonnen, Unterbrechungen zu vermeiden und gleichzeitig die Sicherheit zu verbessern. Wir wollten den Agents ausreichend Spielraum einräumen, damit sie effektiv arbeiten können, ihnen aber Berechtigungen verweigern, die Risiken mit sich bringen.

Dieses Gleichgewicht zu finden, ist schwieriger, als es scheint. Viele Terminalbefehle erfordern unerwartete Berechtigungen, selbst für grundlegende Test- oder Build-Schritte. Eine naive Sandbox würde diese blockieren und den Workflow des Agents unterbrechen. Eine nutzbare Sandbox zu entwerfen, bedeutet, die Abwägungen zwischen Sicherheit und Benutzerfreundlichkeit sorgfältig zu gestalten – innerhalb der Rahmenbedingungen, die jedes Betriebssystem setzt.

Implementierung

Wir stellen eine einheitliche Sandbox-API bereit, die auf jeder Plattform unterschiedlich implementiert ist. macOS, Linux und Windows bieten verschiedene Sandbox-Primitiven, die die zugrunde liegenden Designentscheidungen maßgeblich beeinflusst haben.

macOS

Wir haben vier Sandboxing-Ansätze unter macOS bewertet: App Sandbox, Container, virtuelle Maschinen und Seatbelt. App Sandbox ist für den Mac App Store konzipiert und würde erfordern, dass Cursor jede Binärdatei signiert, die ein Agent ausführen könnte. Das hätte die Komplexität erheblich erhöht und neue Angriffsvektoren für Missbrauch eröffnet, da von Agents generierte oder veränderte Binärdateien das Vertrauen von Cursor erben könnten. Container würden uns auf Linux-Binärdateien beschränken, und virtuelle Maschinen verursachen inakzeptable Startlatenz und Speicher-Overhead.

Damit blieb Seatbelt, angesprochen über sandbox-exec. Es wurde 2007 eingeführt und 2016 als veraltet markiert, wird aber immer noch von kritischen Drittanbieteranwendungen wie Chrome verwendet. Es ermöglicht das Ausführen eines Befehls unter einem Sandbox-Profil, das das Verhalten eines gesamten Unterprozessbaums einschränkt.

Das Profil definiert Berechtigungen mit feiner Granularität und beschränkt Systemaufrufe sowie Lese- oder Schreibzugriffe auf bestimmte Dateien und Verzeichnisse über eine eigenwillige Richtliniensprache. Wir erzeugen diese Richtlinie zur Laufzeit dynamisch auf Basis von Einstellungen auf Workspace- und Admin-Ebene sowie der .cursorignore des Benutzers.

(deny file-write* (regex "^.*\/\\\.vscode($|\/.*)")
)
(deny file-write* (require-all
    (regex "^.*\/\\\.cursor($|\/.*)")
    (require-not (regex "^.*\/\\\.cursor/(rules|commands|worktrees|skills|agents)($|\/.*)")))
)
(deny file-write* (regex "^.*\\\.code-workspace$"))
(deny file-write* (regex "^.*\/\\\.cursorignore$"))
(deny file-write* (regex "^.*\/\\\.git/config$"))
(deny file-write* (regex "^.*\/\\\.git/hooks($|\/.*)")
)
(deny file-write* (regex "^(/private)?/var/folders/.*-cursor(-[a-z]+)?-zsh($|\/.*)")
)

Linux

Linux ist gleichzeitig einfacher und schwieriger als macOS. Der Kernel stellt die benötigten Primitiven über Landlock und seccomp zur Verfügung, aber der Userspace ist dafür verantwortlich, sie zu einer nutzbaren Sandbox zu kombinieren. Zwar kombinieren mehrere Open-Source-Projekte diese Mechanismen effektiv, aber keines unterstützt Funktionen wie .cursorignore.

Wir haben uns entschieden, Landlock und seccomp direkt zu verwenden. Seccomp blockiert unsichere Systemaufrufe, während Landlock Beschränkungen für das Dateisystem durchsetzt, wodurch wir ignorierte Dateien für den Sandbox-Prozess vollständig unzugänglich machen können. Wir mappen die Arbeitsbereiche der Nutzer in ein Overlay-Dateisystem und überschreiben ignorierte Dateien mit Landlock-geschützten Kopien, die weder gelesen noch verändert werden können.

Das Finden und erneute Einhängen dieser Dateien ist der langsamste Teil des Linux-Sandboxings. Es wäre einfacher, Dateisystemoperationen – wie unter macOS – erst bei Bedarf zu filtern, aber Linux stellt im seccomp-BPF-Kontext keinen einfachen Zugriff auf den Dateipfad bereit.

Windows

Unter Windows führen wir unsere Linux-Sandbox innerhalb von WSL2 aus. Eine vergleichbare native Windows-Sandbox zu entwickeln, ist deutlich schwieriger, da die meisten vorhandenen Sandbox-Primitive auf Browser zugeschnitten sind und allgemeine Entwicklerwerkzeuge nicht unterstützen. Wir arbeiten mit Microsoft zusammen, um sicherzustellen, dass die erforderlichen Primitive zur Verfügung stehen.

Agents beibringen, wie sie die Sandbox verwenden

Eine Sandbox ist nur dann effektiv, wenn Agents vorhersagen können, welche Befehle innerhalb der Sandbox erfolgreich sein werden, und erkennen, wann eine Eskalation der Berechtigungen erforderlich ist. Die Modelle sandbox-bewusst zu machen, erforderte Änderungen am Agent-Harness.

Wir haben damit begonnen, die Shell-Tool-Beschreibungen zu aktualisieren, um die Sandbox-Einschränkungen zu erklären: ob Befehle je nach Benutzereinstellungen mit Zugriff auf Dateisystem, Git oder Netzwerk ausgeführt werden und wie der Agent bei Bedarf erhöhte Berechtigungen anfordern kann. Einen grundlegenden Harness-Change zu finden, mit dem wir zufrieden waren, erforderte viel manuelles Testen: Wir führten einige typische Rollouts aus, beobachteten, wo Dinge anders liefen als erwartet, passten den Prompt an und führten die Rollouts erneut aus.

Anschließend haben wir die Auswirkungen dieser Änderungen mit unserem internen Benchmark, Cursor Bench, ausgewertet, indem wir Agents mit und ohne aktiviertes Sandboxing verglichen. Wir bemerkten schnell einen häufigen Fehlermodus: Der Agent versuchte wiederholt denselben Terminalbefehl auszuführen, ohne die Berechtigungen zu ändern.

Um dem zu begegnen, haben wir aktualisiert, wie Shell-Tool-Ergebnisse gerendert werden: Die Sandbox-Einschränkung, die für einen Fehler verantwortlich ist, wird nun explizit hervorgehoben, und in bestimmten Fällen wird dem Agent empfohlen, die Berechtigungen zu eskalieren. Seit wir diese Hinweise ausgeliefert haben, erholen sich Agents deutlich robuster von Sandbox-bezogenen Fehlern, und die Offline-Eval-Performance hat sich signifikant verbessert.

Offline-Evals zeigen jedoch nur einen kleinen Teil des Gesamtbildes. Um zusätzliche Sicherheit zu gewinnen, dass Sandboxing die User Experience nicht verschlechtern würde, haben wir die Sandbox schrittweise in der Produktion ausgerollt. Das Feedback, das wir intern wie extern erhalten haben, hat uns das Vertrauen gegeben, das Feature freizugeben. Inzwischen sehen wir, dass ein Drittel der Requests auf unterstützten Plattformen mit der Sandbox laufen, und wir haben viele Enterprise-Kunden wie NVIDIA an Bord geholt.

Wenn Agents von der Code-Generierung zum Betrieb von Produktivsystemen übergehen, sind klare Ausführungsgrenzen entscheidend. Unsere aktuelle Implementierung ist ein Schritt in diese Richtung. Für die Zukunft sind wir besonders gespannt auf Sandbox-native Agents, die auf den Einschränkungen ihrer Umgebung trainiert sind. Diesen Agents kann die Freiheit gegeben werden, Skripte und Programme direkt zu schreiben, anstatt nur auf das Aufrufen von Tools beschränkt zu sein.

Wenn du daran interessiert bist, an tiefgreifenden technischen Problemen rund um die Zukunft des Programmierens zu arbeiten, melde dich unter hiring@cursor.com.

Kategorie: Forschung

Autors: Ani Betts, Yash Gaitonde & Alex Haugland

Implementierung einer sicheren Sandbox für lokale Agents · Cursor