Zurück zu den Updates
New releaseAug 8, 2026

sandbox-runtime v0.0.71

Ein leichtgewichtiges Sandboxing-Tool zur Durchsetzung von Dateisystem- und Netzwerkbeschränkungen für beliebige Prozesse auf Betriebssystemebene, ohne dass ein Container erforderlich ist.

Teilen

Anthropic Sandbox Runtime (srt)

Ein leichtgewichtiges Sandboxing-Tool zur Durchsetzung von Dateisystem- und Netzwerkbeschränkungen für beliebige Prozesse auf Betriebssystemebene, ohne dass ein Container erforderlich ist.

srt verwendet native OS-Sandboxing-Primitive (sandbox-exec unter macOS, bubblewrap unter Linux) und proxybasierte Netzwerkfilterung. Es kann verwendet werden, um das Verhalten von Agenten, lokalen MCP-Servern, Bash-Befehlen und beliebigen Prozessen in einer Sandbox auszuführen.

Beta-Forschungsvorschau

Das Sandbox-Runtime ist eine Forschungsvorschau, die für Claude Code entwickelt wurde, um sicherere KI-Agenten zu ermöglichen. Es wird als frühe Open-Source-Vorschau bereitgestellt, um dem breiteren Ökosystem zu helfen, sicherere agentische Systeme zu entwickeln. Da es sich um eine frühe Forschungsvorschau handelt, können sich APIs und Konfigurationsformate weiterentwickeln. Wir freuen uns über Feedback und Beiträge, um KI-Agenten standardmäßig sicherer zu machen!

Installation```bash

npm install -g @anthropic-ai/sandbox-runtime

## Grundlegende Verwendung```bash
# Network restrictions
$ srt "curl anthropic.com"
Running: curl anthropic.com
<html>...</html>  # Request succeeds

$ srt "curl example.com"
Running: curl example.com
Connection blocked by network allowlist  # Request blocked

# Filesystem restrictions
$ srt "cat README.md"
Running: cat README.md
# Anthropic Sandb...  # Current directory access allowed

$ srt "cat ~/.ssh/id_rsa"
Running: cat ~/.ssh/id_rsa
cat: /Users/ollie/.ssh/id_rsa: Operation not permitted  # Specific file blocked

Übersicht

Dieses Paket bietet eine eigenständige Sandbox-Implementierung, die sowohl als CLI-Werkzeug als auch als Bibliothek verwendet werden kann. Es ist mit einer Secure-by-Default-Philosophie konzipiert, die auf typische Anwendungsfälle von Entwicklern zugeschnitten ist: Prozesse starten mit minimalen Zugriffsrechten, und Sie öffnen gezielt nur die Löcher, die Sie benötigen.

Wichtige Funktionen:

  • Netzwerkbeschränkungen: Steuern, welche Hosts/Domains über HTTP/HTTPS und andere Protokolle erreicht werden können
  • Dateisystembeschränkungen: Steuern, welche Dateien/Verzeichnisse gelesen/geschrieben werden können
  • Unix-Socket-Beschränkungen: Steuern des Zugriffs auf lokale IPC-Sockets
  • Verletzungsüberwachung: Auf macOS können Sie auf den Sandbox-Verletzungsprotokollspezicher des Systems für Echtzeitwarnungen zugreifen

Beispielanwendungsfall: Sandboxing von MCP-Servern

Ein wichtiger Anwendungsfall ist das Sandboxing von Model Context Protocol (MCP)-Servern, um deren Fähigkeiten einzuschränken. Zum Beispiel, um den Dateisystem-MCP-Server zu sandboxen:

Ohne Sandboxing (.mcp.json):```json { "mcpServers": { "filesystem": { "command": "npx", "args": ["-y", "@modelcontextprotocol/server-filesystem"] } } }

**Mit Sandboxing** (`.mcp.json`):```json
{
  "mcpServers": {
    "filesystem": {
      "command": "srt",
      "args": ["npx", "-y", "@modelcontextprotocol/server-filesystem"]
    }
  }
}

Konfiguriere dann die Einschränkungen in ~/.srt-settings.json:```json { "filesystem": { "denyRead": [], "allowWrite": ["."], "denyWrite": ["~/sensitive-folder"] }, "network": { "allowedDomains": [], "deniedDomains": [] } }

Jetzt wird der MCP-Server daran gehindert, in den verweigerten Pfad zu schreiben:```
> Write a file to ~/sensitive-folder
✗ Error: EPERM: operation not permitted, open '/Users/ollie/sensitive-folder/test.txt'

So funktioniert es

Die Sandbox nutzt Betriebssystem-Grundprimitive, um Einschränkungen durchzusetzen, die für den gesamten Prozessbaum gelten:

  • macOS: Verwendet sandbox-exec mit dynamisch generierten Seatbelt-Profilen
  • Linux: Verwendet bubblewrap zur Containerisierung mit Isolierung des Netzwerk-Namespace
  • Windows: Führt den in der Sandbox laufenden Prozess unter einem dedizierten lokalen Benutzerkonto srt-sandbox aus, mit einem Windows Filtering Platform Egress-Fence, der an die SID dieses Kontos gekoppelt ist, und expliziten ACEs pro Sitzung auf dem Arbeitsverzeichnis

0d1c612947c798aef48e6ab4beb7e8544da9d41a-4096x2305

Duales Isolationsmodell

Sowohl die Dateisystem- als auch die Netzwerkisolierung sind für ein effektives Sandboxing erforderlich. Ohne Dateiisolierung könnte ein kompromittierter Prozess SSH-Schlüssel oder andere sensible Dateien exfiltrieren. Ohne Netzwerkisolierung könnte ein Prozess die Sandbox verlassen und uneingeschränkten Netzwerkzugriff erlangen.

Dateisystem-Isolierung erzwingt Lese- und Schreibbeschränkungen:

  • Lesen (Deny-then-Allow-Muster): Standardmäßig ist der Lesezugriff überall erlaubt. Sie können breite Bereiche (z. B. /Users) verweigern und dann bestimmte Pfade darin wieder erlauben (z. B. .). allowRead hat Vorrang vor denyRead — im Gegensatz zum Schreiben, wo denyWrite Vorrang vor allowWrite hat.
  • Schreiben (Nur-Allow-Muster): Standardmäßig ist der Schreibzugriff überall verweigert. Sie müssen Pfade explizit erlauben (z. B. ., /tmp). Eine leere Allow-Liste bedeutet keinen Schreibzugriff.

Netzwerk-Isolierung (Nur-Allow-Muster): Standardmäßig ist der gesamte Netzwerkzugriff verweigert. Sie müssen Domains explizit erlauben. Eine leere allowedDomains-Liste bedeutet keinen Netzwerkzugriff. Netzwerkverkehr wird über Proxyserver geleitet, die auf dem Host laufen:

  • Linux: Anfragen werden über das Dateisystem über einen Unix-Domain-Socket geleitet. Der Netzwerk-Namespace des in der Sandbox laufenden Prozesses wird vollständig entfernt, sodass der gesamte Netzwerkverkehr über die auf dem Host laufenden Proxys geleitet werden muss (die auf Unix-Sockets lauschen, die in die Sandbox bind-mounted sind)

  • macOS: Das Seatbelt-Profil erlaubt die Kommunikation nur mit einem bestimmten Localhost-Port. Die Proxys lauschen auf diesem Port und schaffen so einen kontrollierten Kanal für den gesamten Netzwerkzugriff

  • Windows: Ein maschinenweiter WFP-Filtersatz blockiert alle ausgehenden Verbindungen, die vom Konto srt-sandbox ausgehen, mit Ausnahme von Loopback zum Proxy-Portbereich. Die Proxys lauschen innerhalb dieses Bereichs und schaffen so einen kontrollierten Kanal für den gesamten Netzwerkzugriff

Sowohl HTTP/HTTPS (über HTTP-Proxy) als auch anderer TCP-Verkehr (über SOCKS5-Proxy) werden von diesen Proxys vermittelt, die Ihre Domain-Allowlisten und -Denylisten durchsetzen.

Weitere Details zum Sandboxing in Claude Code finden Sie unter:

Architektur```

src/ ├── index.ts # Library exports ├── cli.ts # CLI entrypoint (srt command) ├── utils/ # Shared utilities │ ├── debug.ts # Debug logging │ ├── settings.ts # Settings reader (permissions + sandbox config) │ ├── platform.ts # Platform detection │ └── exec.ts # Command execution utilities └── sandbox/ # Sandbox implementation ├── sandbox-manager.ts # Main sandbox manager ├── sandbox-schemas.ts # Zod schemas for validation ├── sandbox-violation-store.ts # Violation tracking ├── sandbox-utils.ts # Shared sandbox utilities ├── http-proxy.ts # HTTP/HTTPS proxy for network filtering ├── socks-proxy.ts # SOCKS5 proxy for network filtering ├── linux-sandbox-utils.ts # Linux bubblewrap sandboxing ├── macos-sandbox-utils.ts # macOS sandbox-exec sandboxing └── windows-sandbox-utils.ts # Windows srt-win sandboxing

## Verwendung

### Als CLI-Werkzeug

Der Befehl `srt` (Anthropic Sandbox Runtime) umschließt jeden Befehl mit Sicherheitsgrenzen:```bash
# Run a command in the sandbox
srt echo "hello world"

# With debug logging
srt --debug curl https://example.com

# Specify custom settings file
srt --settings /path/to/srt-settings.json npm install

Als Bibliothek```typescript

import { SandboxManager, type SandboxRuntimeConfig, } from '@anthropic-ai/sandbox-runtime' import { spawn } from 'child_process'

// Define your sandbox configuration const config: SandboxRuntimeConfig = { network: { allowedDomains: ['example.com', 'api.github.com'], deniedDomains: [], }, filesystem: { denyRead: ['~/.ssh'], allowWrite: ['.', '/tmp'], denyWrite: ['.env'], }, }

// Initialize the sandbox (starts proxy servers, etc.) await SandboxManager.initialize(config)

// Wrap a command with sandbox restrictions const sandboxedCommand = await SandboxManager.wrapWithSandbox( 'curl https://example.com', )

// Execute the sandboxed command const child = spawn(sandboxedCommand, { shell: true, stdio: 'inherit' })

// Handle exit and cleanup after child process completes child.on('exit', async code => { console.log(Command exited with code ${code}) // Cleanup when done (optional, happens automatically on process exit) await SandboxManager.reset() })

**Zuordnung von Verstößen (`commandId` / `commandText`).** Verstöße, die während der Ausführung eines umschlossenen Befehls beobachtet werden (Seatbelt-Protokollzeilen, Seccomp-Ereignisse, Proxy-Ablehnungen), werden unter einem Zuordnungsschlüssel gespeichert, und `annotateStderrWithSandboxFailures(key, stderr)` / `getViolationsForCommand(key)` schlagen sie über denselben Schlüssel nach. Standardmäßig ist der Schlüssel die umschlossene Zeichenfolge selbst. Übergeben Sie stattdessen eine undurchsichtige, pro Aufruf vergebene `commandId` (z. B. eine Tool-Use-ID), um danach zu schlüsseln — empfohlen: Schlüssel werden anhand ihrer ersten 100 Zeichen verglichen, sodass lange Befehle mit gemeinsamem Präfix andernfalls gegenseitig zugeordnet würden und eine erneute Ausführung desselben Texts die Ereignisse des früheren Laufs erben würde. Wenn die Zeichenfolge, die Sie *ausführen*, nicht der Befehl ist, den der Aufruf *darstellt* (z. B. wenn Sie ein zusammengesetztes `source <snapshot> && eval '<cmd>'` umschließen), übergeben Sie außerdem `commandText: '<cmd>'`: Es ist das, wogegen die `ignoreViolations`-Befehlsmuster abgeglichen werden und was jeder Verstoß als sein `command` meldet.```typescript
const wrapped = await SandboxManager.wrapWithSandbox(
  assembledCommand, // what actually runs
  undefined,
  undefined,
  undefined,
  { commandId: invocationId, commandText: rawCommand },
)
// ... run it ...
const annotated = SandboxManager.annotateStderrWithSandboxFailures(invocationId, stderr)

Verfügbare Exporte```typescript

// Main sandbox manager export { SandboxManager } from '@anthropic-ai/sandbox-runtime'

// Violation tracking export { SandboxViolationStore } from '@anthropic-ai/sandbox-runtime'

// TypeScript types export type { SandboxRuntimeConfig, NetworkConfig, FilesystemConfig, IgnoreViolationsConfig, SandboxAskCallback, FsReadRestrictionConfig, FsWriteRestrictionConfig, NetworkRestrictionConfig, } from '@anthropic-ai/sandbox-runtime'

## Konfiguration

### Speicherort der Einstellungsdatei

Standardmäßig sucht die Sandbox-Laufzeitumgebung nach der Konfiguration unter `~/.srt-settings.json`. Sie können einen benutzerdefinierten Pfad mit dem Flag `--settings` angeben:```bash
srt --settings /path/to/srt-settings.json <command>

Vollständiges Konfigurationsbeispiel```json

{ "network": { "allowedDomains": [ "github.com", ".github.com", "lfs.github.com", "api.github.com", "npmjs.org", ".npmjs.org" ], "deniedDomains": ["malicious.com"], "allowUnixSockets": ["/var/run/docker.sock"], "allowLocalBinding": false }, "filesystem": { "denyRead": ["~/.ssh"], "allowRead": [], "allowWrite": [".", "src/", "test/", "/tmp"], "denyWrite": [".env", "config/production.json"] }, "ignoreViolations": { "*": ["/usr/bin", "/System"], "git push": ["/usr/bin/nc"], "npm": ["/private/tmp"] }, "enableWeakerNestedSandbox": false, "enableWeakerNetworkIsolation": false, "allowAppleEvents": false }

### Konfigurationsoptionen

#### Netzwerkkonfiguration

Verwendet ein **Allow-only-Prinzip** – der gesamte Netzwerkzugriff ist standardmäßig verweigert.

- `network.allowedDomains` – Array der erlaubten Domänen (unterstützt Platzhalter wie `*.example.com`). Leeres Array = kein Netzwerkzugriff. Ein optionales `:port`-Suffix (`api.example.com:443`, `*.example.com:8443`) schränkt einen Eintrag auf diesen Zielport ein; Einträge ohne Port entsprechen jedem Port.
  - IPv6-Literale müssen eingeklammert sein, RFC-3986-Stil: `[::1]`, `[2001:db8::1]:443`. Ein nicht eingeklammerter Eintrag mit mehreren Doppelpunkten wird als mehrdeutig abgelehnt (`2001:db8::1:443` ist selbst eine gültige Adresse).
- `network.deniedDomains` – Array der gesperrten Domänen (wird zuerst geprüft, hat Vorrang vor `allowedDomains`). Gleiches `:port`-Suffix, und ein bloßes `*` (oder `*:22`) wird akzeptiert, um alle Verbindungen zu verweigern.
- `network.deniedDomainReasons` – Optionale Map, die einen `deniedDomains`-Eintrag (durch exakten Zeichenkettenabgleich) einer an das Modell gerichteten Begründung zuordnet; diese erscheint in der `<sandbox_violations>`-Zeile, wenn dieser Eintrag eine Verbindung verweigert – gibt an, was blockiert wird, und die zulässige Alternative (z. B. `{"github.com:22": "SSH pushes to GitHub are blocked; use an https:// remote"}`). Einträge ohne Begründung liefern eine generische Meldung. Für SSH-Ziele (Port 22) wird die Begründung auch in-band übermittelt: Ein SSH-Client, der über einen SOCKS-ProxyCommand ohne Authentifizierung getunnelt wird (z. B. BSD `nc -X 5`), erhält vor dem Schlüsselaustausch eine SSH-Verbindungstrennung, deren Beschreibung die Begründung ist und die OpenSSH wörtlich ausgibt – halten Sie solche Begründungen unter ~400 ASCII-Zeichen, mit dem Imperativ am Anfang, da OpenSSH kürzt und Nicht-ASCII-Zeichen escaped.
- `network.allowLocalBinding` – Erlaubt das Binden an lokale Ports (boolesch, Standard: false)

**TLS-Terminierung** (`network.tlsTerminate`, experimentell): Wenn gesetzt, werden HTTPS-CONNECTs prozessintern terminiert, sodass SRT die entschlüsselten Anfragen sehen (und über `network.filterRequest` filtern) kann. Der sandboxierte Prozess wird auf ein Trust-Bundle verwiesen, das die MITM-CA (`caCertPath`/`caKeyPath` oder eine kurzlebige CA, falls weggelassen) sowie die regulären Roots des Hosts enthält, sodass sowohl vom Proxy ausgestellte Zertifikate als auch echte Upstream-Zertifikate verifiziert werden.

- `network.tlsTerminate.excludeDomains` – Domänenmuster (gleiche Syntax wie `allowedDomains`), die **nicht** terminiert werden. Passende CONNECTs werden stattdessen opak getunnelt: Sie unterliegen weiterhin der Domänen-Allowlist, aber der Client innerhalb der Sandbox führt seinen eigenen TLS-Handshake mit dem echten Upstream durch, und `filterRequest` / Credential-Injection gelten nicht für deren HTTPS-Datenverkehr. Verwenden Sie dies für die zwei Fälle, bei denen TLS-Terminierung grundsätzlich scheitert:
  - **mTLS-Upstreams** – nur der Client innerhalb der Sandbox besitzt das Clientzertifikat, daher kann der Proxy die Verbindung nicht in seinem Namen neu aufbauen.
  - **Clients mit Zertifikats-Pinning** – Clients, die die Identität des Upstreams selbst überprüfen (benutzerdefinierte CAs, SAN-Pinning) und das MITM-Zertifikat ablehnen.
- `network.tlsTerminate.extraCaCertPaths` – Pfade zu PEM-CA-Zertifikatsdateien, die an dieses Trust-Bundle angehängt werden, nach der MITM-CA und den regulären Roots des Hosts. Ausgeschlossene (nicht terminierte) Hosts werden vom Client innerhalb der Sandbox verifiziert, und die von SRT gesetzten Vertrauens-Umgebungsvariablen (`SSL_CERT_FILE`, `GIT_SSL_CAINFO`, ...) _ersetzen_ die eigene Vertrauenskonfiguration jedes Tools. Daher muss eine standortlokale Root-CA (z. B. eine interne mTLS-CA) im Bundle enthalten sein, andernfalls können diese Hosts nie verifiziert werden. Nur die `CERTIFICATE`-Blöcke jeder Datei werden in das Bundle kopiert (alles andere, z. B. ein privater Schlüssel in einer kombinierten PEM-Datei, wird nie für die Sandbox exponiert); Dateien, die fehlen, nicht lesbar sind oder keinen PEM-`CERTIFICATE`-Block enthalten, werden übersprungen. Daher ist es sicher, Pfade aufzulisten, die nur auf manchen Hosts existieren.```json
{
  "network": {
    "allowedDomains": ["*.example.com", "internal-mtls.example.net"],
    "deniedDomains": [],
    "tlsTerminate": {
      "excludeDomains": ["internal-mtls.example.net"],
      "extraCaCertPaths": ["/etc/internal-mtls-roots.pem"]
    }
  }
}

Unix-Socket-Einstellungen (plattformspezifisches Verhalten):

SettingmacOSLinux
allowUnixSockets: string[]Zulassungsliste der Socket-PfadeIgnoriert (seccomp kann nicht nach Pfad filtern)
allowAllUnixSockets: booleanAlle Sockets zulassenSeccomp-Blockierung deaktivieren

Unix-Sockets sind auf beiden Plattformen standardmäßig blockiert.

  • macOS: Verwende allowUnixSockets, um bestimmte Pfade zuzulassen (z. B. ["/var/run/docker.sock"]), oder allowAllUnixSockets: true, um alle zuzulassen.
  • Linux: Die Blockierung verwendet seccomp-Filter (nur x64/arm64). Wenn seccomp nicht verfügbar ist, sind Sockets uneingeschränkt und eine Warnung wird angezeigt. Verwende allowAllUnixSockets: true, um die Blockierung explizit zu deaktivieren.

Dateisystem-Konfiguration

Verwendet zwei verschiedene Muster:

Lese-Beschränkungen (Verweigern-dann-Erlauben-Muster) – alle Lesevorgänge sind standardmäßig erlaubt:

  • filesystem.denyRead – Array von Pfaden, für die Lesezugriff verweigert wird. Leeres Array = voller Lesezugriff.
  • filesystem.allowRead – Array von Pfaden, für die Lesezugriff in verweigerten Bereichen wieder erlaubt wird (hat Vorrang vor denyRead). Hinweis: Dies ist das Gegenteil vom Schreiben, wo denyWrite Vorrang vor allowWrite hat.

Schreib-Beschränkungen (Nur-Erlauben-Muster) – alle Schreibvorgänge sind standardmäßig verweigert:

  • filesystem.allowWrite – Array von Pfaden, für die Schreibzugriff erlaubt wird. Leeres Array = kein Schreibzugriff.
  • filesystem.denyWrite – Array von Pfaden, für die Schreibzugriff innerhalb erlaubter Pfade verweigert wird (hat Vorrang vor allowWrite)

Pfad-Syntax (macOS):

Pfade unterstützen auf macOS Git-ähnliche Glob-Muster, ähnlich der .gitignore-Syntax:

  • * – Entspricht allen Zeichen außer / (z. B. entspricht *.ts foo.ts, aber nicht foo/bar.ts)
  • ** – Entspricht allen Zeichen einschließlich / (z. B. entspricht src/**/*.ts allen .ts-Dateien in src/)
  • ? – Entspricht genau einem einzelnen Zeichen außer / (z. B. entspricht file?.txt file1.txt)
  • [abc] – Entspricht jedem Zeichen aus der Menge (z. B. entspricht file[0-9].txt file3.txt)

Beispiele:

  • "allowWrite": ["src/"] – Schreiben in das gesamte Verzeichnis src/ erlauben
  • "allowWrite": ["src/**/*.ts"] – Schreiben in alle .ts-Dateien in src/ und Unterverzeichnissen erlauben
  • "denyRead": ["~/.ssh"] – Lesen des SSH-Verzeichnisses verweigern
  • "denyRead": ["/Users"], "allowRead": ["."] – Lesen in ganz /Users verweigern, aber das aktuelle Verzeichnis wieder erlauben
  • "denyWrite": [".env"] – Schreiben in die Datei .env verweigern (auch wenn das aktuelle Verzeichnis erlaubt ist)

Pfad-Syntax (Linux):

Linux unterstützt derzeit kein Glob-Matching. Verwende ausschließlich literale Pfade:

  • "allowWrite": ["src/"] – Schreiben in das Verzeichnis src/ erlauben
  • "denyRead": ["/home/user/.ssh"] – Lesen des SSH-Verzeichnisses verweigern
  • "denyRead": ["/home"], "allowRead": ["."] – Lesen in ganz /home verweigern, aber das aktuelle Verzeichnis wieder erlauben

Alle Plattformen:

  • Pfade können absolut (z. B. /home/user/.ssh) oder relativ zum aktuellen Arbeitsverzeichnis (z. B. ./src) sein
  • ~ wird zum Home-Verzeichnis des Benutzers expandiert

Weitere Konfiguration

  • ignoreViolations – Objekt, das Befehlsmuster auf Arrays von Pfaden abbildet, in denen Verstöße ignoriert werden sollen
  • enableWeakerNestedSandbox – Schwächeren Sandbox-Modus für Docker-Umgebungen aktivieren (boolesch, Standard: false)
  • enableWeakerNetworkIsolation – Zugriff auf com.apple.trustd.agent in der macOS-Sandbox erlauben (boolesch, Standard: false). Dies wird für Go-Programme (gh, gcloud, terraform, kubectl usw.) benötigt, um TLS-Zertifikate zu verifizieren, wenn httpProxyPort mit einem MITM-Proxy und eigener CA verwendet wird. Sicherheitswarnung: Die Aktivierung eröffnet einen potenziellen Vektor für Datenexfiltration über den trustd-Dienst.
  • allowAppleEvents – Das Senden von Apple Events und Launch-Services-Open-Anfragen aus der macOS-Sandbox erlauben (boolesch, Standard: false). Ohne dies schlagen Befehle wie open, osascript und alles, was URLs öffnet oder andere Apps per AppleScript steuert, mit AppleScript-Fehler -600 („Anwendung läuft nicht“) oder LaunchServices-Fehlern (-10822, -54) fehl. Sicherheitswarnung: Die Aktivierung bedeutet, dass die Sandbox keine Codeausführungs-Isolation mehr bietet. Ein sandboxierter Befehl kann ohne Benutzeraufforderung andere Anwendungen über open starten, und alles, was er startet, läuft außerhalb der Dateisystem- und Netzwerkbeschränkungen der Sandbox; das Steuern bereits laufender Apps über Apple Events ist zusätzlich durch die TCC-Automatisierungszustimmung des Benutzers pro App beschränkt. Einbettende Anwendungen sollten diese Option nur aus vertrauenswürdiger Benutzerkonfiguration beziehen – niemals aus projektlokalen Dateien in einem ausgecheckten Repository, da ein von Angreifern erstelltes Projekt so seine eigenen Sandbox-Berechtigungen erhöhen könnte.

Häufige Konfigurationsrezepte

GitHub-Zugriff erlauben (alle notwendigen Endpunkte):```json { "network": { "allowedDomains": [ "github.com", "*.github.com", "lfs.github.com", "api.github.com" ], "deniedDomains": [] }, "filesystem": { "denyRead": [], "allowWrite": ["."], "denyWrite": [] } }

**Auf bestimmte Verzeichnisse beschränken:**```json
{
  "network": {
    "allowedDomains": [],
    "deniedDomains": []
  },
  "filesystem": {
    "denyRead": ["~/.ssh"],
    "allowWrite": [".", "src/", "test/"],
    "denyWrite": [".env", "secrets/"]
  }
}

Nur-Workspace-Dateisystemzugriff (Lesezugriffe außerhalb des Workspace verweigern):```json { "network": { "allowedDomains": [], "deniedDomains": [] }, "filesystem": { "denyRead": ["/Users"], "allowRead": ["."], "allowWrite": ["."], "denyWrite": [] } }

Dies verweigert das Lesen von allem unter `/Users` (oder `/home` unter Linux) und erlaubt dann das aktuelle Arbeitsverzeichnis wieder. Systempfade (`/usr`, `/lib`, usw.) bleiben lesbar.

### Häufige Probleme und Tipps

**Jest ausführen:** Verwenden Sie das Flag `--no-watchman`, um Sandbox-Verstöße zu vermeiden:```bash
srt "jest --no-watchman"

Watchman greift auf Dateien außerhalb der Sandbox-Grenzen zu, was Berechtigungsfehler auslöst. Wenn du es deaktivierst, kann Jest stattdessen mit dem integrierten Datei-Watcher ausgeführt werden.

Plattformunterstützung

  • macOS: Verwendet sandbox-exec mit benutzerdefinierten Profilen (keine zusätzlichen Abhängigkeiten)
  • Linux: Verwendet bubblewrap (bwrap) zur Containerisierung
  • Windows: Alpha – verwendet einen gebündelten srt-win.exe-Helfer (keine zusätzlichen Abhängigkeiten). Siehe Windows (Alpha) unten für Einrichtung, Sicherheitsmodell und bekannte Einschränkungen

Plattformspezifische Abhängigkeiten

Linux benötigt:

  • bubblewrap – Container-Laufzeit
    • Ubuntu/Debian: apt-get install bubblewrap
    • Fedora: dnf install bubblewrap
    • Arch: pacman -S bubblewrap
  • socat – Socket-Relay für Proxy-Bridging
    • Ubuntu/Debian: apt-get install socat
    • Fedora: dnf install socat
    • Arch: pacman -S socat
  • ripgrep – Schnelles Suchwerkzeug zur Erkennung von Deny-Pfaden
    • Ubuntu/Debian: apt-get install ripgrep
    • Fedora: dnf install ripgrep
    • Arch: pacman -S ripgrep

Hinweis für Ubuntu 24.04+: Diese Versionen aktivieren kernel.apparmor_restrict_unprivileged_userns standardmäßig, was unshare(CLONE_NEWUSER) erlaubt, aber dem resultierenden Namespace Capabilities entzieht. Sowohl bubblewrap als auch die seccomp-Isolationsschicht benötigen Capability-tragende User-Namespaces. Deaktiviere die Einschränkung mit:```bash sudo sysctl -w kernel.apparmor_restrict_unprivileged_userns=0

oder fügen Sie ein AppArmor-Profil hinzu, das den relevanten Binärdateien `userns` gewährt.

**Optionale Linux-Abhängigkeiten (für den Seccomp-Fallback):**

Das Paket enthält vorab generierte Seccomp-BPF-Filter für x86-64- und ARM-Architekturen. Diese Abhängigkeiten werden nur benötigt, wenn Sie eine andere Architektur verwenden, für die keine vorab generierten Filter verfügbar sind:

- `gcc` oder `clang` – C-Compiler
- `libseccomp-dev` – Entwicklungsdateien der Seccomp-Bibliothek
  - Ubuntu/Debian: `apt-get install gcc libseccomp-dev`
  - Fedora: `dnf install gcc libseccomp-devel`
  - Arch: `pacman -S gcc libseccomp`

**macOS erfordert:**

- `ripgrep` – Schnelles Suchwerkzeug zur Erkennung von Deny-Pfaden
  - Installation über Homebrew: `brew install ripgrep`
  - Oder herunterladen von: https://github.com/BurntSushi/ripgrep/releases

**Windows erfordert:**

- Keine zusätzlichen Abhängigkeiten. Das Hilfsprogramm `srt-win.exe` (x64 und arm64) ist im npm-Paket enthalten. Ein einmaliger Schritt `windows-install` mit erhöhten Rechten ist erforderlich – siehe unten.

## Windows (alpha)

Windows-Support ist **Alpha**. Der sandboxierte Prozess läuft unter einem dedizierten lokalen Benutzerkonto `srt-sandbox`, das durch native Windows-Sicherheitsprimitive vom aufrufenden Benutzer isoliert ist – eine Windows Filtering Platform (WFP)-Egress-Abgrenzung, die an die SID des Sandbox-Kontos gebunden ist, sowie pro Sitzung explizite ACEs, die dieser SID den Zugriff auf konfigurierte Dateisystempfade gewähren oder verweigern.

### Einrichtung

Einmal pro Maschine ausführen (selbst erhöhend; eine UAC-Eingabeaufforderung):```powershell
npx @anthropic-ai/sandbox-runtime windows-install

Dies richtet das lokale Benutzerkonto srt-sandbox ein (mit einem zufälligen Passwort, das DPAPI-verschlüsselt unter %LOCALAPPDATA%\sandbox-runtime\state.db gespeichert wird), die lokale Gruppe sandbox-runtime-users und installiert einen maschinenweiten WFP-Filtersatz, der auf der SID von srt-sandbox basiert. Er ist idempotent — eine erneute Ausführung rotiert das Passwort des Sandbox-Kontos und gleicht den Filtersatz ab.

Es ist keine Abmeldung erforderlich. Die WFP-Filter basieren auf der SID des dedizierten Sandbox-Kontos, sodass Ihr eigenes Netzwerk, Dienste und alle anderen Sicherheitsprinzipale auf dem Rechner nicht betroffen sind.

Nach der Installation funktionieren SandboxManager.initialize() und die srt-CLI wie auf anderen Plattformen. initialize() prüft, ob das Sandbox-Konto und die WFP-Sperre aktiv sind, und schlägt andernfalls mit einer umsetzbaren Fehlermeldung fehl.

Programmatische Installation/Deinstallation werden als installWindowsSandbox() / uninstallWindowsSandbox() exportiert.

Sicherheitsmodell

Der Sandbox-Befehl wird als das Konto srt-sandbox ausgeführt, nicht als der aufrufende Benutzer. Der gebündelte Helfer srt-win.exe führt einen Zwei-Hop-Start durch: Der Broker ruft CreateProcessWithLogonW auf, um einen Runner als srt-sandbox zu starten, und der Runner startet das Ziel mit einem eingeschränkten Token innerhalb eines Job-Objekts. Der Kindprozess erbt das isolierte Profil des Sandbox-Kontos (%USERPROFILE%, %TEMP%, HKCU) sowie eine frische Umgebung, die nur mit dem PATH des Brokers und den generierten Proxy-Variablen überlagert wird.

Die Ausführung unter einer eigenen Benutzer-SID schließt strukturell die Klasse von Surrogat-Spawn-Ausbrüchen (Taskplaner, PROC_THREAD_ATTRIBUTE_PARENT_PROCESS auf einen dem Broker gehörenden Prozess, BITS, prozessexternes COM mit RunAs="Interactive User"): Jeder Prozess, den der Kindprozess auf anderem Wege erzeugen kann, trägt weiterhin die srt-sandbox-SID, bleibt also der WFP-Ausgangssperre unterworfen und hat keine Rechte an den Dateien des aufrufenden Benutzers.

Netzwerkisolation ist ein WFP-Satz aus zwei Filtern auf FWPM_LAYER_ALE_AUTH_CONNECT_V4/V6: ein PERMIT für Loopback-Ziele im konfigurierten Proxy-Portbereich (Standard 60080–60089) und ein BLOCK für jede Verbindung, deren Token die srt-sandbox-SID trägt. Der Sandbox-Prozess erreicht das Internet nur über die JS-HTTP/SOCKS5-Proxys, die in diesem Bereich lauschen; ein Prozess, der seine Proxy-Umgebung entfernt und direkt verbindet, wird im Kernel blockiert.

Dateisystem-Isolation wird durch diskretionäre NTFS-ACLs durchgesetzt. Das Konto srt-sandbox hat von Haus aus keine Rechte an den Dateien des aufrufenden Benutzers. Daher schreibt die Sandbox bei initialize() additive, vererbende explizite ACEs nur für die srt-sandbox-SID — sie überschreibt oder ersetzt niemals den vorhandenen Sicherheitsdeskriptor eines Pfads:

  • filesystem.allowWrite → einen vererbenden MODIFY-ALLOW-ACE (READ|WRITE|EXECUTE|DELETE, wobei FILE_DELETE_CHILD vorenthalten wird). Der Sandbox-Prozess kann Dateien im Arbeitsbaum erstellen, ändern und löschen; das Vorenthalten von FILE_DELETE_CHILD in der Gewährung ist Defense-in-Depth für die unten genannten Deny-Stempel, kein Schutz der Baumwurzel.
  • filesystem.allowRead → einen vererbenden READ|EXECUTE-ALLOW-ACE
  • filesystem.denyRead / filesystem.denyWrite → einen vererbenden DENY-ACE auf dem Ziel sowie einen vererbenden FILE_DELETE_CHILD-DENY auf dessen Elternverzeichnis — zusammen mit dem vorenthaltenen FILE_DELETE_CHILD in der Gewährung für den Arbeitsbaum verhindert dies, dass der Sandbox-Prozess einen gesperrten Pfad über sein Elternverzeichnis umbenennt oder löscht

reset() entfernt jeden ACE, den diese Sitzung hinzugefügt hat (über state.db mit Referenzzählung über parallele Hosts hinweg; ein Crash-Recovery-Durchlauf beim nächsten initialize() räumt nach einem unsauberen Beenden auf). Verzeichnisziele werden unterstützt (die ACEs werden auf den gesamten Teilbaum vererbt). Glob-Muster werden zum Zeitpunkt von initialize() zu konkreten Pfaden expandiert — ein später erscheinender passender Pfad ist nicht abgedeckt.

TLS-Terminierung unter Windows

network.tlsTerminate erfordert, dass die MITM-CA im Zertifikatsspeicher CurrentUser\Root des Sandbox-Benutzers vorhanden ist (Schannel — das TLS-Backend, das von System32\curl.exe, PowerShell Invoke-WebRequest, .NET und git mit Standard-Backend verwendet wird — vertraut nur dem Betriebssystem-Speicher, nicht Umgebungsvariablen). Dies ist ein Schritt zur Installationszeit, getrennt von windows-install:```typescript import { windowsTrustCa } from '@anthropic-ai/sandbox-runtime' windowsTrustCa('/path/to/mitm-ca.crt') // or: srt-win user trust-ca

`initialize()` vergleicht den Fingerabdruck der Sitzungs-CA mit der installierten und schlägt bei Abweichung mit einer aussagekräftigen Fehlermeldung fehl, sodass eine veraltete Installations-CA TLS innerhalb der Sandbox nicht stillschweigend brechen kann.

OpenSSL-basierte Clients (msys2 `curl`, `git -c http.sslBackend=openssl`, Node, Python, cargo) werden durch die Vertrauensschicht der Umgebungsvariablen abgedeckt: Dasselbe Vertrauenspaket, das unter macOS/Linux verwendet wird, wird über `NODE_EXTRA_CA_CERTS`, `SSL_CERT_FILE`, `CURL_CA_BUNDLE`, `GIT_SSL_CAINFO`, `CARGO_HTTP_CAINFO` usw. in die Sandbox übergeben, und der Paketpfad wird der `allowRead`-Gewährung der Sitzung hinzugefügt, damit das Sandbox-Konto es öffnen kann.

### Windows-spezifische Konfiguration

Die plattformübergreifenden Blöcke `filesystem` und `network` gelten wie oben beschrieben. Windows-spezifische Einstellungen befinden sich unter `windows`:

- `windows.proxyPortRange` — `[low, high]` inklusiver Portbereich, an den die JS-Proxys innerhalb binden. **Muss mit** dem Bereich übereinstimmen, der an `windows-install --proxy-port-range` übergeben wird (Standard `[60080, 60089]`) — die WFP-Loopback-PERMIT-Regel deckt nur diesen Bereich ab.
- `windows.sublayerGuid` — WFP-Sublayer-GUID, unter der die Filter installiert wurden. Weglassen, um den zur Kompilierzeit festgelegten Standardwert zu verwenden; nur setzen, wenn Enterprise-Tooling die Filter unter einem benutzerdefinierten Sublayer installiert hat.
- `windows.srtWin.path` — Pfad zur `srt-win`-Binärdatei. Weglassen, um die gebündelte `vendor/srt-win/<arch>/srt-win.exe` aufzulösen. Setzen, wenn die CLI von `srt-win` in eine Multicall-Binärdatei eingebettet wird; Spawn-Aufrufe übergeben dann `--srt-win` als `argv[1]`, damit der Dispatcher des Einbettenden an `srt_win::run_from_args` weiterleiten kann.

### Bekannte Einschränkungen

- **Zertifikatssperrung unter Schannel.** Der CRL/OCSP-Abruf von CryptoAPI erfolgt über WinHTTP mit dem Token des Aufrufers und ignoriert die Proxy-Umgebung, sodass er von der WFP-Egress-Sperre blockiert wird. Tools, die Schannel mit standardmäßig aktivierter Sperrprüfung verwenden, schlagen mit `CRYPT_E_REVOCATION_OFFLINE` (`0x80092013`) fehl, es sei denn, die Sperrprüfung wird pro Tool deaktiviert: `curl --ssl-no-revoke`, `git -c http.schannelCheckRevoke=false`, `CARGO_HTTP_CHECK_REVOKE=false`. `Invoke-WebRequest`, .NET `HttpClient` und `gh` prüfen die Sperrung standardmäßig nicht und sind nicht betroffen. Ein CRL-Verteilungspunkt, der vom Loopback-Proxy bereitgestellt wird, ist geplant, um diesen Workaround zu entfernen.
- **Pro-Benutzer-Installationen von Tools sind nicht erreichbar.** Der Sandbox-Prozess läuft als `srt-sandbox` und nicht als dein Benutzerkonto, daher werden Tools, die unter deinem Profil installiert sind (per nvm/fnm verwaltetes Node, `winget`-/Scoop-Pakete pro Benutzer, `pip install --user`, `%LOCALAPPDATA%\Programs\…`), über den geerbten `PATH` aufgelöst, können aber vom Sandbox-Konto nicht geöffnet werden. Bevorzuge maschinenweite Installationen (`Program Files`, `choco`/`winget --scope machine`) oder füge die jeweiligen Profilpfade zu `filesystem.allowRead` hinzu.
- **Pro-Ausführung-Überschreibungen von `filesystem.allowRead`/`filesystem.allowWrite` werden nicht unterstützt.** `allowRead`/`allowWrite` auf Sitzungsebene (in der an `initialize()` übergebenen Konfiguration) funktionieren wie oben beschrieben; die Übergabe pro Befehl in `wrapWithSandbox`'s `customConfig` wirft eine Ausnahme – Berechtigungen werden sitzungsweit über `srt-win acl grant` bei `initialize()` angewendet, und `srt-win exec` setzt lediglich Pro-Ausführung-Verweigerungen um.
- **`proxyAuthToken` ist in der Befehlszeile des Runners sichtbar.** Die Proxy-Umgebung (einschließlich `HTTP_PROXY=http://srt:<token>@127.0.0.1:…`) wird dem Zwei-Hop-Runner über `--env`-Argumente auf der argv von `srt-win exec` übergeben, sodass das Token von jedem lokalen Sicherheitsprinzipal gelesen werden kann, der den Runner-Prozess mit `PROCESS_QUERY_LIMITED_INFORMATION` öffnen kann. Das Token existiert, damit der Sandbox-Prozess sich gegenüber dem Loopback-Proxy authentifizieren kann; es ist also kein Geheimnis gegenüber der Sandbox selbst. Auf einem Einzelbenutzer-Entwicklungsrechner ist das in der Regel akzeptabel, aber auf einem gemeinsam genutzten Host solltest du die Proxy-Allowlist als für andere Prinzipale derselben Sitzung erreichbar behandeln.
- **DNS-Auflösung über den System-Resolver ist nicht eingeschränkt.** `getaddrinfo()` wird vom `Dnscache`-Dienst bedient, der als `NETWORK SERVICE` läuft, sodass die Namensauflösung gelingt, obwohl der anschließende `connect()`-Aufruf aus dem Sandbox-Prozess blockiert wird. Tools, die ihr eigenes UDP/53 verwenden (`nslookup`, `dig`), sind eingeschränkt. Dies entspricht dem macOS-Verhalten.

### Deinstallation```powershell
npx @anthropic-ai/sandbox-runtime windows-uninstall

Entfernt die WFP-Filtergruppe, das Konto srt-sandbox und sein Profil, die Gruppe sandbox-runtime-users und löscht den Anmelde-/Einrichtungsmarker aus state.db (eine UAC-Eingabeaufforderung). %LOCALAPPDATA%\sandbox-runtime\state.db selbst bleibt erhalten (es ist nur für den Broker mit ACL gekennzeichnet); löschen Sie das Verzeichnis manuell für eine vollständige Bereinigung.

Entwicklung```bash

Install dependencies

npm install

Build the project

npm run build

Run tests

npm test

Type checking

npm run typecheck

Lint code

npm run lint

Format code

npm run format

### Seccomp-Binaries erstellen

Der BPF-Filter und der `apply-seccomp`-Lader werden aus C-Quellcode in `vendor/seccomp-src/` mittels `npm run build:seccomp` kompiliert (nur Linux; benötigt `gcc` und `libseccomp-dev`). CI führt ihn vor den Tests auf jeder Linux-Architektur aus, und der Release-Workflow baut beide Architekturen und bindet sie in das veröffentlichte Paket ein.

## Implementierungsdetails

### Netzwerkisolationsarchitektur

Die Sandbox führt HTTP- und SOCKS5-Proxyserver auf dem Host-Rechner aus, die alle Netzwerkanfragen basierend auf den Berechtigungsregeln filtern:

1. **HTTP/HTTPS-Datenverkehr**: Ein HTTP-Proxyserver fängt Anfragen ab und validiert sie gegen erlaubte/blockierte Domains
2. **Anderer Netzwerkverkehr**: Ein SOCKS5-Proxy behandelt alle anderen TCP-Verbindungen (SSH, Datenbankverbindungen usw.)
3. **Berechtigungsdurchsetzung**: Die Proxys setzen die `permissions`-Regeln aus deiner Konfiguration durch

**Plattformspezifische Proxy-Kommunikation:**

- **Linux**: Anfragen werden über das Dateisystem über Unix-Domain-Sockets geleitet (mittels `socat` zur Überbrückung). Der Netzwerk-Namespace wird aus dem Bubblewrap-Container entfernt, sodass sämtlicher Netzwerkverkehr durch die Proxys laufen muss.

- **macOS**: Das Seatbelt-Profil erlaubt nur die Kommunikation mit bestimmten Localhost-Ports, auf denen die Proxys lauschen. Der gesamte andere Netzwerkzugriff ist blockiert.

- **Windows**: Ein WFP-`ALE_AUTH_CONNECT`-Filter blockiert jeden ausgehenden Verbindungsaufbau vom `srt-sandbox`-Konto, außer Loopback zum konfigurierten Proxy-Portbereich. Die Proxys binden innerhalb dieses Bereichs. Umgebungsvariablen (`HTTP_PROXY`, `HTTPS_PROXY`, `ALL_PROXY`, …) weisen die Tools auf die Proxys hin, aber der WFP-Filter ist die Grenze – ein Prozess, der sie ignoriert oder entfernt, ist weiterhin eingezäunt.

### Dateisystemisolierung

Dateisystembeschränkungen werden auf Betriebssystemebene durchgesetzt:

- **macOS**: Verwendet `sandbox-exec` mit dynamisch generierten Seatbelt-Profilen, die erlaubte Lese-/Schreibpfade festlegen
- **Linux**: Verwendet `bubblewrap` mit Bind-Mounts und markiert Verzeichnisse je nach Konfiguration als schreibgeschützt oder lesbar/schreibbar
- **Windows**: Schreibt additive `(OI)(CI)` explizite ACEs für die `srt-sandbox`-SID auf die konfigurierten Pfade (ALLOW bei `allowRead`/`allowWrite`, DENY bei `denyRead`/`denyWrite`) und entfernt sie anschließend bei `reset()`

**Standard-Dateisystemberechtigungen:**

- **Lesen** (Erst verweigern, dann erlauben): Standardmäßig überall erlaubt. Du kannst große Bereiche verweigern und dann bestimmte Pfade darin wieder erlauben. `allowRead` hat Vorrang vor `denyRead`.

  - Beispiel: `denyRead: ["~/.ssh"]`, um den Zugriff auf SSH-Schlüssel zu blockieren
  - Beispiel: `denyRead: ["/Users"], allowRead: ["."]`, um ganz `/Users` außer dem Arbeitsbereich zu blockieren
  - Leeres `denyRead: []` = voller Lesezugriff (nichts verweigert)

- **Schreiben** (Nur erlauben): Standardmäßig überall verweigert. Du musst Pfade explizit erlauben.
  - Beispiel: `allowWrite: [".", "/tmp"]`, um Schreibzugriffe auf das aktuelle Verzeichnis und /tmp zu erlauben
  - Leeres `allowWrite: []` = kein Schreibzugriff (nichts erlaubt)
  - `denyWrite` erzeugt Ausnahmen innerhalb erlaubter Pfade (Verweigern hat Vorrang)

**Die Priorität ist für Lesen und Schreiben bewusst entgegengesetzt:** `allowRead` überschreibt `denyRead`, während `denyWrite` `allowWrite` überschreibt. So kannst du lesbare Bereiche innerhalb verweigerter Gebiete und geschützte Bereiche innerhalb beschreibbarer Gebiete aussparen.

### Pflicht-Verweispfade (Automatisch geschützte Dateien)

Bestimmte sensible Dateien und Verzeichnisse sind **immer gegen Schreibzugriffe blockiert**, selbst wenn sie innerhalb eines erlaubten Schreibpfads liegen. Dies bietet Verteidigung in der Tiefe gegen Sandbox-Ausbrüche und Konfigurationsmanipulation.

**Immer blockierte Dateien:**

- Shell-Konfigurationsdateien: `.bashrc`, `.bash_profile`, `.zshrc`, `.zprofile`, `.profile`
- Git-Konfigurationsdateien: `.gitconfig`, `.gitmodules`
- Andere sensible Dateien: `.ripgreprc`, `.mcp.json`

**Immer blockierte Verzeichnisse:**

- IDE-Verzeichnisse: `.vscode/`, `.idea/`
- Claude-Konfigurationsverzeichnisse: `.claude/commands/`, `.claude/agents/`
- Git-Hooks und -Konfiguration: `.git/hooks/`, `.git/config`

Diese Pfade werden automatisch blockiert – du musst sie nicht zu `denyWrite` hinzufügen. Selbst mit `allowWrite: ["."]` schlägt beispielsweise das Schreiben auf `.bashrc` oder `.git/hooks/pre-commit` fehl:```bash
$ srt 'echo "malicious" >> .bashrc'
/bin/bash: .bashrc: Operation not permitted

$ srt 'echo "bad" > .git/hooks/pre-commit'
/bin/bash: .git/hooks/pre-commit: Operation not permitted

Hinweis (Linux): Unter Linux blockieren Mandatory-Deny-Pfade nur Dateien, die bereits existieren. Nicht vorhandene Dateien in diesen Mustern können durch den Bind-Mount-Ansatz von bubblewrap nicht blockiert werden. macOS verwendet Glob-Muster, die sowohl bestehende als auch neue Dateien blockieren.

Linux-Suchtiefe: Unter Linux verwendet die Sandbox ripgrep, um in Unterverzeichnissen innerhalb erlaubter Schreibpfade nach gefährlichen Dateien zu suchen. Standardmäßig durchsucht sie aus Leistungsgründen bis zu 3 Ebenen tief. Du kannst dies mit mandatoryDenySearchDepth konfigurieren:```json { "mandatoryDenySearchDepth": 5, "filesystem": { "allowWrite": ["."] } }

- Standard: `3` (durchsucht bis zu 3 Ebenen tief)
- Bereich: `1` bis `10`
- Höhere Werte bieten mehr Schutz, aber langsamere Leistung
- Dateien im aktuellen Arbeitsverzeichnis (CWD, Tiefe 0) sind unabhängig von dieser Einstellung immer geschützt

### Unix-Socket-Einschränkungen (Linux)

Unter Linux nutzt die Sandbox **seccomp BPF (Berkeley Packet Filter)**, um die Erstellung von Unix-Domain-Sockets auf Syscall-Ebene zu blockieren. Dies bietet eine zusätzliche Sicherheitsebene, die verhindert, dass Prozesse neue Unix-Domain-Sockets für lokale IPC erzeugen (sofern nicht ausdrücklich erlaubt).

**So funktioniert es:**

1. **Eingebauter BPF-Filter**: Das Paket enthält eine statische `apply-seccomp`-Binärdatei für x64 und arm64 mit dem kompilierten seccomp-BPF-Filter. Der Filter ist architekturspezifisch, aber libc-unabhängig, sodass die Binärdatei sowohl mit glibc als auch mit musl funktioniert.

2. **Laufzeiterkennung**: Die Sandbox erkennt automatisch die Architektur Ihres Systems und verwendet die passende `apply-seccomp`-Binärdatei.

3. **Syscall-Filterung**: Der BPF-Filter fängt den Syscall `socket()` ab und blockiert die Erstellung von `AF_UNIX`-Sockets, indem er `EPERM` zurückgibt. Dadurch wird verhindert, dass sandboxed Code neue Unix-Domain-Sockets erstellt.

4. **Zweistufige Anwendung mithilfe der apply-seccomp-Binärdatei**:
   - Das äußere bwrap erstellt die Sandbox mit Dateisystem-, Netzwerk- und PID-Namespace-Einschränkungen
   - Netzwerk-Brückenprozesse (socat) starten innerhalb der Sandbox (benötigen Unix-Sockets)
   - apply-seccomp erstellt einen verschachtelten User+PID+Mount-Namespace und hängt `/proc` neu ein
   - Innerhalb des verschachtelten Namespace fungiert apply-seccomp als PID 1 (nicht-dumpbarer Init/Reaper)
   - apply-seccomp forkt, wendet den seccomp-Filter über `prctl()` an und führt den Benutzerbefehl per exec aus
   - Der Benutzerbefehl läuft mit allen Sandbox-Einschränkungen sowie der Blockierung der Unix-Socket-Erstellung

**PID-Namespace-Isolation**: Der verschachtelte PID-Namespace stellt sicher, dass der Benutzerbefehl keinen Prozess sehen oder adressieren kann, der ohne den seccomp-Filter läuft (bwrap-Init, der Shell-Wrapper oder die socat-Helfer). Dadurch bleibt die seccomp-Grenze unabhängig von `kernel.yama.ptrace_scope` intakt, da ungefilterte Helfer weder über `ptrace` noch über `/proc/N/mem` erreichbar sind. Das innere PID 1 setzt `PR_SET_DUMPABLE=0`, sodass es ebenfalls nicht ptracebar ist. Wenn die Erstellung des verschachtelten Namespace fehlschlägt, bricht apply-seccomp ab, anstatt ohne Isolation zu laufen.

**Sicherheitseinschränkungen**: Der Filter blockiert `socket(AF_UNIX, ...)` sowie die Syscalls `io_uring_setup`/`io_uring_enter`/`io_uring_register` (die letzteren drei, weil `IORING_OP_SOCKET` unter Linux 5.19+ andernfalls die `socket()`-Regel umgehen würde). Er verhindert keine Operationen an Unix-Socket-Dateideskriptoren, die von Elternprozessen geerbt oder über `SCM_RIGHTS` übergeben wurden. Für die meisten Sandboxing-Szenarien reicht das Blockieren der Socket-Erstellung aus, um unbefugte IPC zu verhindern.

**Keine Laufzeitabhängigkeiten**: Vorkompilierte statische apply-seccomp-Binärdateien und vorgenerierte BPF-Filter sind für x64 und arm64 enthalten. Zur Laufzeit sind keine Kompilierungswerkzeuge oder externen Abhängigkeiten erforderlich.

**Architekturunterstützung**: x64 und arm64 werden mit vorkompilierten Binärdateien vollständig unterstützt. Andere Architekturen werden derzeit nicht unterstützt. Um Sandboxing ohne Unix-Socket-Blockierung auf nicht unterstützten Architekturen zu nutzen, setzen Sie `allowAllUnixSockets: true` in Ihrer Konfiguration.

### Erkennung und Überwachung von Verstößen

Wenn ein in der Sandbox ausgeführter Prozess versucht, auf eine eingeschränkte Ressource zuzugreifen:

1. **Blockiert den Vorgang** auf Betriebssystemebene (gibt einen `EPERM`-Fehler zurück)
2. **Protokolliert den Verstoß** (plattformspezifische Mechanismen)
3. **Benachrichtigt den Benutzer** (in Claude Code wird dadurch eine Berechtigungsabfrage ausgelöst)

**macOS**: Die Sandbox-Laufzeit greift auf den Log-Speicher des macOS-Systems für Sandbox-Verstöße zu. Dies liefert Echtzeit-Benachrichtigungen mit detaillierten Informationen darüber, was versucht wurde und warum es blockiert wurde. Dies ist derselbe Mechanismus, den Claude Code zur Erkennung von Verstößen verwendet.```bash
# View sandbox violations in real-time
log stream --predicate 'process == "sandbox-exec"' --style syslog

Linux: Bubblewrap bietet keine integrierte Meldung von Verstößen. Verwenden Sie strace, um Systemaufrufe zu verfolgen und blockierte Vorgänge zu identifizieren:```bash

Trace all denied operations

strace -f srt 2>&1 | grep EPERM

Trace specific file operations

strace -f -e trace=open,openat,stat,access srt 2>&1 | grep EPERM

Trace network operations

strace -f -e trace=network srt 2>&1 | grep EPERM

### Erweitert: Eigener Proxy

Für anspruchsvollere Netzwerkfilterung können Sie die Sandbox so konfigurieren, dass sie Ihren eigenen Proxy anstelle der integrierten verwendet. Dies ermöglicht:

- **Verkehrsinspektion**: Verwenden Sie Tools wie [mitmproxy](https://mitmproxy.org/), um Datenverkehr zu überwachen und zu verändern
- **Individuelle Filterlogik**: Implementieren Sie komplexe Regeln, die über einfache Domain-Allowlists hinausgehen
- **Audit-Protokollierung**: Protokollieren Sie alle Netzwerkanfragen für Compliance oder Fehlersuche

**Beispiel mit mitmproxy:**```bash
# Start mitmproxy with custom filtering script
mitmproxy -s custom_filter.py --listen-port 8888

Hinweis: Eine benutzerdefinierte Proxy-Konfiguration wird im neuen Konfigurationsformat noch nicht unterstützt. Diese Funktion wird in einer zukünftigen Version hinzugefügt.

Wichtiger Sicherheitshinweis: Selbst mit Domain-Allowlists können Exfiltration-Vektoren existieren. Wenn Sie beispielsweise github.com erlauben, kann ein Prozess in jedes Repository pushen. Mit einem benutzerdefinierten MITM-Proxy und ordnungsgemäßer Zertifikatseinrichtung können Sie bestimmte API-Aufrufe überprüfen und filtern, um dies zu verhindern.

Sicherheitsgrenzen

  • Einschränkungen der Netzwerk-Sandbox: Das Netzwerkfilterungssystem funktioniert, indem es die Domains einschränkt, mit denen Prozesse sich verbinden dürfen. Es untersucht ansonsten nicht den Datenverkehr, der durch den Proxy fließt, und Benutzer sind dafür verantwortlich, sicherzustellen, dass sie in ihrer Richtlinie nur vertrauenswürdige Domains zulassen.
Benutzer sollten sich der potenziellen Risiken bewusst sein, die durch das Zulassen breiter Domains wie `github.com` entstehen, die Datenexfiltration ermöglichen können. Außerdem kann es in einigen Fällen möglich sein, die Netzwerkfilterung durch [Domain Fronting](https://en.wikipedia.org/wiki/Domain_fronting) zu umgehen.
  • Privilegienausweitung über Unix-Sockets: Die Konfiguration allowUnixSockets kann versehentlich Zugriff auf leistungsstarke Systemdienste gewähren, die zu Sandbox-Umgehungen führen können. Wenn sie beispielsweise verwendet wird, um Zugriff auf /var/run/docker.sock zu erlauben, würde dies effektiv Zugriff auf das Hostsystem durch Ausnutzung des Docker-Sockets gewähren. Benutzer werden ermutigt, sorgfältig zu überlegen, welche Unix-Sockets sie durch die Sandbox zulassen.
  • Erweiterung von Dateisystemberechtigungen: Übermäßig breite Schreibberechtigungen im Dateisystem können Privilege-Escalation-Angriffe ermöglichen. Das Zulassen von Schreibzugriffen auf Verzeichnisse, die ausführbare Dateien in $PATH enthalten, Systemkonfigurationsverzeichnisse oder Benutzer-Shell-Konfigurationsdateien (.bashrc, .zshrc) kann zur Codeausführung in anderen Sicherheitskontexten führen, wenn andere Benutzer oder Systemprozesse auf diese Dateien zugreifen.
  • Linux-Sandbox-Stärke: Die Linux-Implementierung bietet eine starke Dateisystem- und Netzwerkisolation, enthält jedoch einen Modus enableWeakerNestedSandbox, der es ermöglicht, innerhalb von Docker-Umgebungen ohne privilegierte Namespaces zu funktionieren. Diese Option schwächt die Sicherheit erheblich und sollte nur in Fällen verwendet werden, in denen andernfalls eine zusätzliche Isolation erzwungen wird.
  • Schwächere Netzwerkisolation (macOS): Die Option enableWeakerNetworkIsolation aktiviert erneut den Zugriff auf com.apple.trustd.agent, der für Go-Programme erforderlich ist, um TLS-Zertifikate über das macOS-Security-Framework zu verifizieren. Dies öffnet einen potenziellen Datenexfiltrationsvektor über den trustd-Dienst und sollte nur aktiviert werden, wenn Go-TLS-Verifizierung erforderlich ist (z. B. bei Verwendung von httpProxyPort mit einem MITM-Proxy und benutzerdefinierter CA).
  • Apple Events (macOS): Die Option allowAppleEvents aktiviert erneut das Senden von Apple Events und Launch-Services-Öffnungsanfragen ((allow appleevent-send), (allow lsopen) und Mach-Lookups für com.apple.coreservices.appleevents, com.apple.CoreServices.coreservicesd und com.apple.coreservices.quarantine-resolver), die open, osascript und URL-öffnende Helfer benötigen. Wenn diese erlaubt sind, kann ein sandboxed Befehl beliebige Anwendungen ohne Benutzeraufforderung starten, und gestartete Anwendungen laufen vollständig außerhalb der Sandbox – diese Option entfernt also die Codeausführungsisolation, nicht nur schwächt sie. Das Skripten bereits laufender Anwendungen über Apple Events wird zusätzlich durch die TCC-Automatisierungszustimmung von macOS eingeschränkt, das Starten über open jedoch nicht. Aktivieren Sie dies nur, wenn Befehle innerhalb der Sandbox tatsächlich URLs oder Anwendungen öffnen müssen.

Bekannte Einschränkungen und zukünftige Arbeiten

Linux-Proxy-Umgehung: Verwendet derzeit Umgebungsvariablen (HTTP_PROXY, HTTPS_PROXY, ALL_PROXY), um Datenverkehr durch Proxys zu leiten. Dies funktioniert für die meisten Anwendungen, kann jedoch von Programmen ignoriert werden, die diese Variablen nicht respektieren, was dazu führt, dass sie sich nicht mit dem Internet verbinden können.

Zukünftige Verbesserungen:

  • Proxychains-Unterstützung: Hinzufügen von Unterstützung für proxychains mit LD_PRELOAD unter Linux, um Netzwerkaufrufe auf einer niedrigeren Ebene abzufangen und die Umgehung zu erschweren

  • Linux-Verletzungsüberwachung: Implementierung einer automatischen strace-basierten Verletzungserkennung für Linux, integriert in den Verletzungsspeicher. Derzeit müssen Linux-Benutzer strace manuell ausführen, um Verletzungen zu sehen, im Gegensatz zu macOS, das eine automatische Verletzungsüberwachung über den System-Logspeicher hat.

Kategorien