Skip to content
KitploitKITPLOIT
ToolsExploitsBlog
Einreichen
ToolsExploitsBlog
Einreichen

Hacking-, PenTest- und Cybersicherheits-Tools für Ihr Sicherheitsarsenal!

Kitploit ist ein Verzeichnis von Hacking-, Cybersicherheits- und Pentesting-Tools. Entdecken Sie die neuesten Projekt-Updates, um Schwachstellen zu finden, Systeme zu analysieren, Tests zu automatisieren und Ihre Sicherheit zu stärken.

··Feeds·Kontakt·Datenschutz·© 2026 Kitploit

Tool-Verzeichnis

Kategorien

Alle Kategorien anzeigen
Loading categories
cplt — Sandbox für KI-Coding-Agents. Führt Copilot CLI, Claude Code, OpenCode, Gemini CLI, Antigravity, Pi, goose oder eine einfache Shell in einer Sandbox auf Kernel-Ebene aus, mit git- und gh-Guards und einer im Repository festgeschriebenen Sandbox-Richtlinie. | Kitploit
Tools/GitHubGitHub/navikt/cplt
DefensivwerkzeugeDynamische Analyse (Sandboxing)KonfigurationsprüfungSicherheitsvirtualisierungDevSecOpsCommand and ControlDienstprogramme & FrameworksSecret-ErkennungLieferkettensicherheitKI-Sicherheit
GitHub
1212393vor 1 TagVon Kitploit geprüft

Beliebteste

Alle anzeigen →

Entdecken Sie die meistgenutzten Tools unserer Community.

Alle Tools erkunden

Durchsuchen Sie unsere Tool-Sammlung

Alle Tools anzeigen →
navikt/cplt

cplt

Sandbox für KI-Coding-Agents. Führt Copilot CLI, Claude Code, OpenCode, Gemini CLI, Antigravity, Pi, goose oder eine einfache Shell in einer Sandbox auf Kernel-Ebene aus, mit git- und gh-Guards und einer im Repository festgeschriebenen Sandbox-Richtlinie.

Repository anzeigenWebseite
Teilen

cplt

CI Release License: MIT macOS Linux

Vom Kernel erzwungene Sandbox für KI-Coding-Agenten. cplt umhüllt GitHub Copilot CLI, OpenCode, Gemini CLI, Antigravity CLI, Pi, Claude Code, goose, DeepSeek Harness oder jede beliebige Shell, sodass der Agent Code schreiben kann, aber keine Anmeldedaten stehlen, auf main pushen, PRs mergen oder Secrets exfiltrieren kann.

  • macOS: Apple Seatbelt/SBPL über sandbox-exec
  • Linux: Landlock LSM + seccomp-BPF + optionale Bubblewrap-Namespace-Isolation (Kernel 5.13+, vollständige Netzwerkfilterung ab 6.7+)
  • Windows: keine native Unterstützung. Es gibt kein Windows-Sandbox-Backend. Führe cplt in WSL2 aus, wo es eine gewöhnliche Linux-Installation ist und der Microsoft-Kernel Landlock mitliefert. Siehe Windows (WSL2) setup.

cplt banner

Warum cplt?

KI-Agenten führen beliebigen Code aus. Ein kompromittierter Agent, sei es durch Prompt-Injection, einen Supply-Chain-Angriff oder einen bösartigen MCP-Server, kann ~/.ssh lesen, auf main pushen, PRs mergen oder deinen Code exfiltrieren – es sei denn, das Betriebssystem selbst sagt Nein.

cplt bietet dir Durchsetzung auf Kernel-Ebene mit teamkonfigurierbarer Policy:

  • Policy pro Repository in .cplt.toml, in die Versionskontrolle eingecheckt, sodass sie manipulationssicher und auditierbar ist
  • Standardmäßiges Verweigern für Anmeldedaten, Secrets und sensible Dateien
  • Git- und gh-Interception auf Befehlsebene: Pushes auf den Standard-Branch, Force-Pushes, Merges und Releases werden blockiert, Feature-Branches bleiben offen
  • Ausgehende Netzwerkfilterung mit einem Audit-Log
  • Kein Docker, keine VMs. Eine einzige Binärdatei, die auf einem abgesicherten Laptop läuft
  • Zero-Config-Start für Entwickler, mit Notausgängen, wenn ein Build wirklich einen braucht

Inhaltsverzeichnis

  • Schnellstart
  • Was es blockiert
  • Wie cplt im Vergleich abschneidet
  • Installation
  • Verwendung
  • Konfiguration
  • Architektur
  • Sicherheit
  • Netzwerk und Proxy
  • Befehlswächter
  • Bekannte Auswirkungen
  • Einschränkungen
  • Mitwirken
  • Referenzen

Detaillierte Dokumentation: Konfiguration · Proxy & Domain-Filterung · gh-Befehlswächter · git-Befehlswächter · Bekannte Auswirkungen · Sicherheitsdetails · Sicherheitsmodell

Schnellstart```bash

brew install navikt/tap/cplt # macOS. On Debian or Ubuntu, see apt below cplt --shell-install # make 'copilot' run sandboxed (persistent) # --agent opencode for any other agent cplt doctor # check your environment cplt -- -p "fix the tests" # run Copilot in sandbox

root@kitploit:~
Andere Agenten und Sandbox-Befehle:```bash
cplt --agent opencode                       # OpenCode (Copilot subscription)
cplt --agent opencode --pass-env ANTHROPIC_API_KEY  # third-party provider
cplt --agent shell                          # interactive sandboxed shell (no AI)
cplt exec -- npm install                    # sandbox any command directly
cplt exec -c "npm install && npm test"      # compound commands in sandbox
alias npm="cplt exec -- npm"               # sandboxed npm for every invocation

Team-Rollout```bash

1. Generate per-repo policy

cplt init --write

2. Developers approve on first run

cplt trust accept --all

3. Tune the command guards (both block by default)

cplt config set git_guard.protect_default_branch_only false # block every push, not just main cplt config set git_guard.mode warn # observe instead of blocking

root@kitploit:~
## Was es blockiert

Die Sandbox blockiert den Zugriff auf Anmeldedaten und Secrets im Kernel. Kommando-Guards blockieren destruktive Operationen. Jede Einschränkung gilt für den Agenten und für jeden Prozess, den er startet.

| Ressource | Status | Hinweise |
| --- | --- | --- |
| Lesen/Schreiben des Projektverzeichnisses | ✅ Erlaubt | |
| Lesen/Schreiben/Löschen von `.env*`, `.pem`, `.key` im Projekt | 🔒 Kernel-blockiert | Verhindert Secret-Exfiltration und -Zerstörung. `--allow-env-files` hebt dies auf |
| Schreiben von `.git/hooks`, `.git/config`, `.gitmodules` | 🔒 Kernel-blockiert (macOS), ⚠️ teilweise auf Linux | Verhindert Persistenz über Git-Hooks, hooksPath-Umleitung, Submodul-Hijacking. **Linux:** Landlock kann einen Unterpfad innerhalb eines erlaubten Baums nicht verweigern, daher bleiben diese auf dem reinen Landlock-Pfad beschreibbar. `bwrap` bindet `.git/hooks` schreibgeschützt neu ein, lässt aber `.git/config` und `.gitmodules` bewusst beschreibbar, sodass `core.hooksPath` eine Persistenzroute bleibt, siehe [Linux-Einschränkungen](https://github.com/navikt/cplt/blob/main/docs/security.md#linux). Gilt für **jeden** beschreibbaren Root, das Projekt und jede `allow.write`-Gewährung, einschließlich eines gewährten Worktrees oder Bare-Repos, dessen echte Hooks außerhalb von `<root>/.git` liegen |
| Ausführung aus `/tmp`, `/var/folders` | 🔒 Kernel-blockiert | Verhindert Write-then-Exec. Das Scratch-Verzeichnis leitet TMPDIR an einen sicheren Ort um, standardmäßig aktiviert |
| Schreiben in PATH-aufgelöste bin/shim-Verzeichnisse (`~/.bun/bin`, `~/.deno/bin`, `$PNPM_HOME`, mise `shims/` und das gesamte `installs/`) | 🔒 Kernel-blockiert (macOS), ⚠️ mise teilweise auf Linux | Verhindert das Trojanisieren einer Binärdatei, die dein nächster *nicht-sandboxed* Befehl über PATH auflöst. Aus demselben Grund sind `~/.cargo/bin` und `~/go/bin` schon immer schreibgeschützt. Bricht `bun install -g`, `deno install`, `pnpm add -g`, `mise install`, `mise upgrade`, `mise use -g` innerhalb von cplt, absichtlich, und ein Repo, das eine nicht installierte Toolchain pinnt, bootstrappt nicht mehr. Projektlokale Installationen sind nicht betroffen. **Linux:** mise's beide laufen über das schreibgeschützte `bwrap`-Overlay; der Rest hält nativ. Siehe [Globale Tool-Installationen](https://github.com/navikt/cplt/blob/main/docs/known-impacts.md#global-tool-installs) |
| Ausführung aus `~/Library/Caches` | 🔒 Standardmäßig Kernel-blockiert | Verhindert Binary-Drop-Staging. Copilot-native Module sind über eine Ausnahme befreit. Gezielte Ausnahmen mit `--allow-cache-exec <SUBDIR>` hinzufügen, z. B. `ms-playwright` |
| Ändern von `.vscode/tasks.json`, `launch.json` | ⚠️ Erlaubt, bekanntes Risiko | IDE-Vertrauensgrenze. Siehe [SECURITY.md](https://github.com/navikt/cplt/blob/main/SECURITY.md) für Gegenmaßnahmen |
| Lesen/Schreiben von `~/.copilot` (Auth, Einstellungen) | ✅ Erlaubt | Enthält `file-map-executable` für `keytar.node`, `pty.node`, `computer.node` |
| Schreiben von `~/.copilot/pkg` (native Module) | 🔒 Kernel-blockiert | Verhindert Persistenz durch Ersetzen nativer Module |
| Umgebungsvariablen | 🔒 Bereinigt + gehärtet | Nur eine sichere Allowlist wird durchgelassen. Lifecycle-Skripte blockiert. `--pass-env VAR` fügt eine wieder hinzu |
| Lesen von `~/.config/gh/hosts.yml` + `config.yml` | ✅ Erlaubt (schreibgeschützt) | Nur diese beiden Dateien. Der Rest von `.config/gh` ist blockiert |
| Lesen von `~/.config/mise` | ✅ Erlaubt (schreibgeschützt) | Tool-Versionen und PATH, keine Secrets |
| Lesen von `~/.gitconfig`, `~/.config/git/config` | ✅ Erlaubt (schreibgeschützt) | Ein Dotfiles-Symlink wird zu seinem Ziel verfolgt, sodass ein gestowtes `~/.gitconfig` funktioniert |
| Lesen von `~/.git-credentials` | 🔒 Kernel-blockiert | `credential.helper = store` hält Klartext-Token hier. Kein `--allow-read` öffnet es wieder, wie `~/.netrc`. **Linux:** eine Gewährung auf einen *Vorfahren* (`$HOME` selbst) legt es weiterhin offen, weil Landlock einen Unterpfad innerhalb eines erlaubten Baums nicht verweigern kann |
| Lesen globaler Git-Hooks (`core.hooksPath`) | ✅ Erlaubt (schreibgeschützt, Schreiben verweigert) | Automatisch erkannt. Muss unter `$HOME` mit Tiefe ≥3 liegen. Schreibvorgänge sind explizit blockiert |
| Commit/Tag-Signierung (`commit.gpgsign`, `tag.gpgsign`) | 🔒 Deaktiviert | Private Schlüssel in `~/.ssh` und `~/.gnupg` sind blockiert, daher wird die Signierung über eine Env-Var-Überschreibung deaktiviert |
| Lesen von `~/Library/Application Support/Microsoft` | ✅ Erlaubt (schreibgeschützt) | Geräte-ID für Telemetrie |
| Zugriff auf macOS Keychain | ⚠️ Erlaubt (Lesen+Schreiben) für Agenten, die dort Auth speichern | Die Gewährung kann nicht auf einen Eintrag beschränkt werden, daher erreicht sie jeden Keychain-Eintrag, den der Agent entsperren kann. Opt-in zu `sandbox.keychain_substitute` (EXPERIMENTELL, standardmäßig aus), um sie bei Läufen wegzulassen, bei denen der Agent ohne sie authentifizieren kann — `CLAUDE_CODE_OAUTH_TOKEN` für Claude Code, eine vorhandene Fallback-Token-Datei für Antigravity. Siehe [SECURITY.md](https://github.com/navikt/cplt/blob/main/SECURITY.md#keychain-access-is-all-or-nothing) |
| Ausgehendes Netzwerk (Port 443) | ✅ Erlaubt | Jeder andere Port ist blockiert. Weitere mit `--allow-port` hinzufügen |
| Localhost ausgehend | 🔒 Kernel-blockiert (macOS), ⚠️ portbasiert auf Linux | Verhindert Zugriff auf lokale Dienste. Eingehend funktioniert weiterhin für den Proxy. **Linux:** Landlock-Regeln sind nur Portnummern und können `localhost:443` nicht von `remote:443` unterscheiden, daher ist ein lokaler Dienst auf einem erlaubten Port erreichbar und es gibt keine localhost-spezifische Verweigerung. `--with-proxy` für SSRF-Schutz verwenden, siehe [Linux-Einschränkungen](https://github.com/navikt/cplt/blob/main/docs/security.md#linux) |
| SSH-Agent (Unix-Socket) | 🔒 Kernel-blockiert (macOS), ⚠️ nur Env auf Linux | Verhindert Signierung von Git-Operationen oder SSH zu Hosts. **Linux:** Unix-Socket-`connect()` wird nicht gegated, daher ist das zurückgehaltene `SSH_AUTH_SOCK` die einzige Barriere und ein Agent, der es selbst setzt, kann die geladenen Schlüssel verwenden. `bwrap` versteckt den Standard-OpenSSH-Socket unter `/tmp`, aber nicht einen gnome-keyring/gcr- oder systemd-Agent unter `$XDG_RUNTIME_DIR`. Siehe [Linux-Einschränkungen](https://github.com/navikt/cplt/blob/main/docs/security.md#linux) |
| Entwickler-Tools (`~/.cargo`, `~/.gradle`, `~/.m2`, `~/.sdkman`, `~/.jenv`, `~/.pyenv`, `~/.konan`, etc.) | ✅ Erlaubt (Lesen+Schreiben für Caches) | Nur Verzeichnisse, die auf der Festplatte existieren. Zur Laufzeit verschärft durch das, was `cplt doctor` erkennt |
| Registry-Anmeldedateien (`~/.m2/settings.xml`, `~/.gradle/gradle.properties`, `~/.cargo/credentials`) | 🔒 Kernel-blockiert auf macOS. Auf Linux bleibt das übergeordnete Tool-Verzeichnis lesbar | Mit `--allow-read` überschreiben. Siehe [Private Registries](https://github.com/navikt/cplt/blob/main/docs/known-impacts.md#private-registries) |
| Lesen von `~/.npmrc` | 🔒 Kernel-blockiert (beide Plattformen) | Mit `--allow-read` überschreiben. Bricht yarn 1, siehe [yarn 1](https://github.com/navikt/cplt/blob/main/docs/known-impacts.md#yarn-1-and-unreadable-home-rc-files) |
| Go-Quellcode (`~/go/src`) | 🔒 Kernel-blockiert | Nur `~/go/bin` und `~/go/pkg` sind lesbar |
| Lesen von `~/.ssh`, `~/.gnupg`, `~/.aws`, `~/.azure` | 🔒 Kernel-blockiert | |
| Lesen von `~/.kube`, `~/.docker`, `~/.nais` | 🔒 Kernel-blockiert | |
| Lesen von `~/.password-store`, `~/.terraform.d` | 🔒 Kernel-blockiert | |
| Lesen von `~/.config/gcloud`, `~/.config/op` | 🔒 Kernel-blockiert | Einzelne Dateien sind mit `--allow-read` überschreibbar. Siehe [Cloud-Anmeldedaten](https://github.com/navikt/cplt/blob/main/docs/known-impacts.md#cloud-credential-directories) |
| Lesen oder Schreiben von `~/.config/cplt`, `~/.nav-pilot` | 🔒 Kernel-blockiert | Tool-Zustand, der entscheidet, was der *nächste* Start tun darf. `~/.config/cplt` ist als ganzer Teilbaum nicht überschreibbar; innerhalb von `~/.nav-pilot` bleibt ein benannter Pfad gewährbar, sodass eine gepinnte agentpakke-Nutzlast gelesen werden kann |
| Lesen von `~/.netrc`, `~/.pypirc`, `~/.vault-token` | 🔒 Kernel-blockiert | Auf beiden Plattformen nicht überschreibbar. Eine davon in `allow.read` zu nennen ist ein Startfehler |
| Lesen von `~/.gem/credentials` | 🔒 Kernel-blockiert | Auf beiden Plattformen nicht überschreibbar. Eine davon in `allow.read` zu nennen ist ein Startfehler |
| Destruktive `gh` CLI-Operationen (merge, delete, release) | 🔒 Kommando-gegated (standardmäßig an) | Opt-out mit `--no-gh-guard`. Siehe [gh guard](https://github.com/navikt/cplt/blob/main/docs/gh-guard.md) |
| `git push` auf den Default-Branch | 🔒 Kommando-gegated (standardmäßig an) | Blockiert Pushes auf `main`/`master`; Feature-Branch-Pushes funktionieren weiterhin. `protect_default_branch_only = false` blockiert jeden Push, `git_guard.mode = "warn"` warnt nur, `--no-git-guard` macht Opt-out |
| Vererbung durch Kindprozesse | ✅ Alle Einschränkungen gelten für Subprozesse | |

Diese Tabelle ist eine Zusammenfassung. Die Sandbox erlaubt außerdem Zugriff auf Systemdateien (SSL-Zertifikate, `/etc/hosts`), temporäre Verzeichnisse (Lesen und Schreiben, kein Exec) und System-Tool-Pfade (`/usr/bin`, `/opt/homebrew`). Führe `cplt --print-profile` für die vollständigen SBPL-Regeln aus.

Für das vollständige Sicherheitsmodell, die Bedrohungsanalyse und die Teststrategie lies [SECURITY.md](https://github.com/navikt/cplt/blob/main/SECURITY.md).

## Wie cplt sich vergleicht

### Codex CLI's Sandbox

| Bereich | cplt | Codex CLI Sandbox |
| --- | --- | --- |
| Kontrolle ausgehender Netzwerkverbindungen | CONNECT-Proxy mit Domain-Allow/Block-Listen | Keine Filterung auf Domain-Ebene |
| Umgebungsbehandlung | Allowlist plus gehärtete Env-Injektion | Einfacheres Pass-Through-Modell |
| Schutz von Secret-Dateien | Deny-Muster wie `.env*`, `.pem`, `.key` innerhalb des Repos | Primär verzeichnisbezogener Zugriff |
| Repo-Richtlinie | [`.cplt.toml`](https://github.com/navikt/cplt/blob/main/docs/configuration.md#per-repo-configuration-cplttoml) mit explizitem Trust/Approval-Flow | Keine Richtliniendatei auf Repo-Ebene |
| Agent-Unterstützung | Copilot, OpenCode, Gemini CLI, Antigravity CLI, Pi, Claude Code, goose, DeepSeek Harness oder Shell | Nur Codex |

cplt ist nicht überall stärker. Codex CLI hat heute Linux-Namespace-Isolation und bietet bereits explizite Sandbox-Modi wie read-only und workspace-write. cplt hat diese Modus-Matrix noch nicht.

### Docker-basierte Sandboxes

| Bereich | cplt | Docker-basierte Sandbox |
| --- | --- | --- |
| Startzeit | Ungefähr sofort für normale CLI-Nutzung | Normalerweise langsamerer Container-Start |
| Netzwerkkontrolle | Ausgehende Filterung pro Anfrage über Proxy | Normalerweise Alles-oder-Nichts-Netzwerkzugriff |
| Dateikontrollen | Regeln pro Pfad und pro Muster | Kontrollen pro Mount |
| Host-Anforderungen | Einzelne Binärdatei | Docker-Daemon erforderlich |
| Eignung für Firmenlaptops | Funktioniert, wo Docker nicht verfügbar oder eingeschränkt ist | Oft durch lokale Richtlinie blockiert |

Docker bietet in manchen Umgebungen weiterhin stärkere Isolation, besonders wenn du ein vollständig getrenntes Dateisystem und Prozess-Namespace willst. cplt tauscht das gegen leichteres Setup und engere Integration mit der Maschine, auf der du bereits entwickelst.

### VS Code Agent-Modus-Berechtigungen

Tools wie der VS Code Agent-Modus verlassen sich hauptsächlich auf UI-Berechtigungen. cplt erzwingt seine Einschränkungen im Kernel, sodass der Agent sich nicht mit einem Prompt oder einer geänderten Anweisung darum herumreden kann. Das ist am wichtigsten für CLI-Agenten und Credential-Exposition:

- cplt funktioniert außerhalb der IDE
- Env-Vars werden gefiltert, bevor der Agent startet
- sensible Dateien können blockiert werden, auch wenn sie innerhalb des Repos liegen
- dieselben Einschränkungen gelten für Kindprozesse

### Claude Code's Sandbox (Anthropic Sandbox Runtime)

[Anthropic Sandbox Runtime](https://github.com/anthropic-experimental/sandbox-runtime) (`srt`) ist die Sandboxing-Schicht, die von Claude Code verwendet wird. Gleicher High-Level-Ansatz wie cplt, macOS Seatbelt plus Kernel-Level-Linux-Enforcement plus ein HTTP-Proxy, andere Implementierung.

| Bereich | cplt | Anthropic srt |
| --- | --- | --- |
| Sprache / Auslieferung | Einzelne Rust-Binärdatei | Node.js + npm-Paket + externe Abhängigkeiten |
| Linux-Backend | Landlock LSM (keine Abhängigkeiten, keine Namespaces) | bubblewrap (Container über User-Namespaces) |
| Umgebungsfilterung | Strikte Allowlist + Suffix-Deny (`_TOKEN`, `_SECRET`) | Erbt vollständige Parent-Env (Secrets gehen durch) |
| Schutz von Credential-Verzeichnissen | 15+ Verzeichnisse standardmäßig verweigert | Benutzer muss manuell konfigurieren |
| DNS-Rebinding-Schutz | ✅ Post-DNS-IP gegen private Bereiche geprüft | ❌ Nicht implementiert |
| Netzwerk-Proxy | HTTP CONNECT + Domain-Allow/Block | HTTP + SOCKS5 + experimentelles TLS MITM |
| SSH-Git | Auf macOS im Kernel blockiert (Agent-Socket verweigert); auf Linux wird nur `SSH_AUTH_SOCK` zurückgehalten | Über SOCKS5 proxied |
| Paketmanager-Skripte | Standardmäßig blockiert (`npm_config_ignore_scripts`) | Nicht blockiert |
| Agent-Unterstützung | Copilot, OpenCode, Gemini, Antigravity, Pi, Claude Code, goose, DSH, Shell | Claude Code |
| Konfiguration | TOML (global + pro Repo) | JSON (nur global) + `--control-fd` Live-Updates |
| Bibliotheks-API | ❌ Nur Binärdatei | ✅ Einbettbare TypeScript-Bibliothek |

cplt ist out of the box sicherer: Env-Filterung, Credential-Schutz, DNS-Rebinding-Prüfungen, Blockierung von Lifecycle-Skripten. srt ist flexibler: SOCKS5, TLS-Inspektion, Callbacks pro Anfrage, Bibliothekseinbettung. Die Wahl des Linux-Backends ist wichtig. bwrap braucht Workarounds auf Ubuntu 24.04+ wegen AppArmor-Userns-Einschränkungen, während Landlock Kernel 5.13 oder neuer erfordert, aber null externe Abhängigkeiten hat.

### GitHub Copilot CLI's eigene Sandbox

Copilot CLI wird seit Juni 2026 mit einer lokalen Sandbox ausgeliefert, im
Standard-Seat enthalten. Sie führt Shell-Befehle über Microsoft MXC mit
eingeschränktem Dateisystem-, Netzwerk- und Systemzugriff aus, auf macOS, Linux und Windows.
`/sandbox enable` schaltet sie ein.

Wenn das für dich ausreicht, nutze es. Es kostet nichts extra und läuft auf Windows,
was cplt nicht tut.

Zwei Dinge tut es nicht.

Die Richtlinie liegt beim Administrator, nicht beim Repository. Unternehmen setzen
Sandbox-Richtlinien über Intune oder ein anderes MDM. Nichts liegt neben dem Code,
sodass eine Regel, die für ein Repository wichtig ist, nicht zu einem Contributor,
zur CI oder zu einem Laptop folgen kann, den das MDM nicht verwaltet. In cplt ist die
Richtlinie `.cplt.toml` im Repository. Reviewer sehen Änderungen daran im Pull
Request, und die Datei kann die eigene Konfiguration eines Entwicklers verschärfen, aber nie
lockern.

Es beschränkt den Prozess, nicht das, was der Prozess mit den Anmeldedaten tut, die er
hält. Die `/sandbox`-Tabs decken das Dateisystem, das Netzwerk und System-
fähigkeiten ab, und innerhalb eines Git-Repositories erhält der Agent standardmäßig Lese- und Schreibzugriff
auf `.git`. Ein sandboxed Agent hat weiterhin dein `gh`-Token und deinen
Push-Zugriff. Einen Branch pushen, einen Pull Request mergen und ein
Repository löschen sind alles wohlgeformte API-Aufrufe von einem autorisierten Client, und eine
Dateisystem- oder Netzwerkregel hat dazu keine Meinung. cplt umhüllt stattdessen `git` und
`gh`. Der Agent committet, brancht und rebased frei. `gh pr merge`,
`gh repo delete` und `gh release create` sind standardmäßig blockiert. Ebenso
`git push` auf `main`/`master`; Feature-Branch-Pushes funktionieren weiterhin, weil
`protect_default_branch_only` an ist. Setze es auf `false`, um jeden Push zu blockieren, oder
`git_guard.mode = "warn"`, um nur zu warnen.

Beides laufen zu lassen ist vernünftig. MXC beschränkt den Prozess. Die Guards entscheiden, was
der Agent mit den Anmeldedaten tun darf, die er hält.

### Ehrliche Lücken

- macOS hat heute die stärkste Durchsetzung auf Dateiebene. Linux-Abdeckung verbessert sich, ist aber nicht identisch.
- cplt bietet noch keine einfachen Richtlinien-Presets für read-only / workspace-write / full-access.
- Wenn du vollständige Container-Isolation willst, versucht cplt nicht, Docker zu ersetzen.

## Installation

### Homebrew (empfohlen)```bash
brew install navikt/tap/cplt

mise```bash

mise use -g 'github:navikt/cplt@'

root@kitploit:~
mise wählt das richtige Release-Asset für deine Plattform und verifiziert dessen Build-Provenienz-Attestierung.

Pinne die Version. Unsere Versionsstrings sind nicht vergleichbares Semver — sie enthalten führende Nullen und zwei Bindestriche — daher kann `mise latest` eine ältere Version als die neueste auflösen ([navikt/copilot#818](https://github.com/navikt/copilot/issues/818)).

### apt (Debian/Ubuntu, empfohlen unter Linux)

[navikt/apt](https://navikt.github.io/apt/) ist ein signiertes Archiv, das über GitHub Pages bereitgestellt wird und cplt und nav-pilot für amd64 und arm64 enthält:```bash
curl -fsSL https://navikt.github.io/apt/keyring/navikt-archive-keyring.gpg \
  | sudo tee /usr/share/keyrings/navikt-archive-keyring.gpg >/dev/null
echo "deb [signed-by=/usr/share/keyrings/navikt-archive-keyring.gpg] https://navikt.github.io/apt stable main" \
  | sudo tee /etc/apt/sources.list.d/navikt.list
sudo apt update && sudo apt install cplt

Es ist ein reines apt-Repository, das unsere Releases spiegelt, kein Distributionspaket mit eigenem Maintainer. Sein Publish-Job läuft stündlich und zieht das neueste .deb aus dem jeweils neuesten Release jedes Tools, sodass ein vor Minuten erstelltes Release bis zu einer Stunde braucht, um auf diesem Weg installierbar zu werden.

Das Paket legt die Binärdatei unter /usr/bin/cplt ab, und Upgrades laufen von da an über sudo apt upgrade. cplt update weigert sich, eine apt-Installation anzufassen, und verweist stattdessen auf sudo apt upgrade: Das Ersetzen der Binärdatei hinter dem Rücken von dpkg würde durch den nächsten apt-Lauf rückgängig gemacht.

Ohne das Archiv ist dasselbe .deb ein Release-Asset:```bash arch=$(dpkg --print-architecture) # amd64 or arm64 gh release download --repo navikt/cplt --pattern "${arch}.deb" sudo apt install ./cplt_"${arch}".deb

root@kitploit:~
### curl | bash

Für Distributionen, die keine Debian-Derivate sind, und für CI:```bash
curl -fsSL https://raw.githubusercontent.com/navikt/cplt/main/install.sh | bash

Optionen:```bash

Install a specific version

curl -fsSL ... | bash -s -- --version 2026.05.05-174753-75bae5b

Install to a custom directory

curl -fsSL ... | bash -s -- --dir ~/.local/bin

Skip Homebrew (force direct download)

curl -fsSL ... | bash -s -- --no-brew

root@kitploit:~
### Von Releases herunterladen

Holen Sie sich den neuesten Build für Ihre Plattform von [GitHub Releases](https://github.com/navikt/cplt/releases/latest):```bash
# macOS, Apple Silicon (M1/M2/M3/M4)
curl -fsSL https://github.com/navikt/cplt/releases/latest/download/cplt-aarch64-apple-darwin.tar.gz | tar xz
sudo mv cplt /usr/local/bin/

# macOS, Intel
curl -fsSL https://github.com/navikt/cplt/releases/latest/download/cplt-x86_64-apple-darwin.tar.gz | tar xz
sudo mv cplt /usr/local/bin/

# Linux, x86_64
curl -fsSL https://github.com/navikt/cplt/releases/latest/download/cplt-x86_64-unknown-linux-gnu.tar.gz | tar xz
sudo mv cplt /usr/local/bin/

# Linux, ARM64
curl -fsSL https://github.com/navikt/cplt/releases/latest/download/cplt-aarch64-unknown-linux-gnu.tar.gz | tar xz
sudo mv cplt /usr/local/bin/

Jede Release-Binärdatei enthält eine Build-Provenienz-Attestierung. Verifiziere sie:```bash gh attestation verify cplt -o navikt

root@kitploit:~
### Aus dem Quellcode erstellen```bash
git clone https://github.com/navikt/cplt.git && cd cplt
cargo build --release
sudo cp target/release/cplt /usr/local/bin/

Oder mit mise:```bash mise run install

root@kitploit:~
`mise run install` und manuelle Builds legen cplt in `/usr/local/bin/cplt` ab. Wenn du zusätzlich den Homebrew-Build unter `/opt/homebrew/bin/cplt` hast, setze `/usr/local/bin` an den Anfang von `PATH`, damit dein Entwicklungs-Build gewinnt:```bash
# Check which cplt is active
which cplt

# If it shows /opt/homebrew/bin/cplt, reorder your PATH:
export PATH="/usr/local/bin:$PATH"

Oder führen Sie einfach /usr/local/bin/cplt explizit aus und umgehen Sie die PATH-Auflösung vollständig.

Windows (WSL2)

cplt hat kein Windows-Sandbox-Backend. Die Durchsetzung erfolgt über Apple Seatbelt unter macOS und Landlock LSM unter Linux, sodass es nichts gibt, was nativ unter Windows ausgeführt werden könnte. Der unterstützte Weg ist WSL2, wo cplt eine gewöhnliche Linux-Installation ist und die Sandbox kernel-erzwungen wird. Jeder Microsoft-Kernel-Zweig baut CONFIG_SECURITY_LANDLOCK=y und listet landlock an erster Stelle in CONFIG_LSM (config-wsl), ausgeliefert seit Kernel 5.15.57.1, und die Standard-Kernel-Befehlszeile von WSL setzt keine lsm=-Überschreibung.

In PowerShell, einmalig:```powershell wsl --install # WSL2 + the default distro (now Ubuntu 26.04 LTS), then reboot wsl --install -d Ubuntu-24.04 # ...or pin an older release wsl --update # keep the Microsoft kernel current, see the ABI note below

root@kitploit:~
Everything unten läuft **innerhalb der Distribution** (`wsl` oder das Ubuntu-Profil im Windows Terminal), nicht in PowerShell:```bash
# 1. Node. Copilot CLI requires Node 22+
#    Ubuntu 26.04 ships 22.x, so apt is enough:
sudo apt update && sudo apt install -y nodejs npm
#    Ubuntu 24.04 ships Node 18, too old. Use nvm, fnm, or NodeSource there instead.

# 2. GitHub CLI, and log in. Ubuntu's universe package works but lags
#    (2.45 on 24.04); add GitHub's apt repo if you want a current gh:
#    https://github.com/cli/cli/blob/trunk/docs/install_linux.md
sudo apt install -y gh
gh auth login

# 3. The agent, installed in the distro, never on the Windows side
npm install -g @github/copilot

# 4. cplt, from the apt archive. The default distro is Ubuntu, so this is
#    the same route as on any other Debian derivative.
curl -fsSL https://navikt.github.io/apt/keyring/navikt-archive-keyring.gpg \
  | sudo tee /usr/share/keyrings/navikt-archive-keyring.gpg >/dev/null
echo "deb [signed-by=/usr/share/keyrings/navikt-archive-keyring.gpg] https://navikt.github.io/apt stable main" \
  | sudo tee /etc/apt/sources.list.d/navikt.list
sudo apt update && sudo apt install cplt

# 5. Check the result
cplt doctor

Copilot CLI nicht auf der Windows-Seite installieren. Bei aktiviertem Interop (dem Standard) wird der Windows-PATH an den der Distribution angehängt, sodass ein Windows-seitiges npm install -g @github/copilot innerhalb der Distribution als /mnt/c/Users/<user>/AppData/Roaming/npm/copilot auftaucht. Das ist eine Windows-Installation, die über Interop erreicht wird. Sie kann nicht in der Linux-Sandbox ausgeführt werden, und der npm-Shim führt ein node aus, das die Distribution nicht haben wird, es sei denn, du hast dort ebenfalls eines installiert. Das Symptom war früher ein unzusammenhängender Laufzeit-Extraktionsfehler. cplt benennt jetzt die Ursache, wenn es einen Agenten unter /mnt/<drive>/ auflöst und unter WSL läuft, und cplt doctor meldet es als fehlgeschlagenen Check statt als bestandenen (#188). WSL wird aus kernel-eigenem Zustand erkannt, entweder /run/WSL oder der Kernelname in /proc/sys/kernel/osrelease und /proc/version, nicht aus WSL_DISTRO_NAME, das unter sudo und in systemd-Units fehlt und das jeder Prozess setzen kann. Auf einer reinen Linux-Maschine wird /mnt/c in Ruhe gelassen. Dort ist es ein gewöhnlicher Einhängepunkt.

Dieser Check hat zwei Grenzen, beide bewusst gewählt. Er schlägt auf dem Standard-Automount-Root an, sodass eine verschobene Installation ([automount] root in /etc/wsl.conf) die Windows-seitige Installation nicht erkennt und du den alten, weniger hilfreichen Fehler mit dem Pfad darin bekommst. Und das Abschalten von Interop verhindert zwar, dass der Windows-PATH durchsickert, hängt aber /mnt/c nicht aus.

Kernel und Landlock-ABI. Aktuelles WSL (2.7.x und später) liefert Linux 6.18, was Landlock-ABI 7 ergibt — alles, was cplt nutzt, außer dem Unix-Socket-connect()-Recht, das ABI 9 (Kernel 7.1) benötigt. Eine Installation, die noch auf der 6.6-Kernel-Linie läuft, bekommt ABI 3: Dateisystemregeln werden durchgesetzt, aber TCP-Port-Regeln (ABI 4), ioctl-Einschränkung (ABI 5) und Signal-/Abstract-Socket-Scoping (ABI 6) sind nicht verfügbar, und die Netzwerkfilterung fällt auf den CONNECT-Proxy zurück. wsl --update bringt dich voran. cplt doctor gibt die Kernelversion und das gefundene ABI aus, was der Check ist, der auf deiner Maschine zählt.

Landlock nicht in .wslconfig deaktivieren. Eine [wsl2] kernelCommandLine mit einer lsm=-Liste, die landlock auslässt, oder ein benutzerdefinierter [wsl2] kernel=, der ohne CONFIG_SECURITY_LANDLOCK gebaut wurde, entfernt die Kernel-Durchsetzung, auf die cplt angewiesen ist, und cplt doctor wird Landlock als nicht verfügbar melden.

Das Projekt im Linux-Dateisystem halten. Arbeite in ~/src/... innerhalb der Distribution statt in /mnt/c/Users/.... Microsofts eigene Empfehlung ist, dass dateisystemübergreifender Zugriff deutlich langsamer ist, und /mnt/c wird ab WSL 2.9.x standardmäßig über 9p bereitgestellt (virtiofs ist Opt-in über [wsl2] virtiofs=true). Wichtiger noch: Wir haben nicht verifiziert, wie Landlock Regeln auf diesem Einhängepunkt durchsetzt. Der Kernel dokumentiert keine Ausnahme für netzwerk- oder FUSE-gestützte Dateisysteme, nur Pipes, Sockets und nsfs, und Landlocks eigene Testsuite übt 9p und FUSE aus, sodass wir erwarten, dass es funktioniert. Niemand hier hat es bestätigt. Behandle ein Projekt unter /mnt/c als ungeprüft statt als unterstützt.

Bubblewrap. Ubuntu 23.10+ blockiert unprivilegierte User-Namespaces über kernel.apparmor_restrict_unprivileged_userns, was bwrap bricht. Dieses Sysctl stammt aus einem Ubuntu-Kernel-Patch, der im Microsoft-Kernel fehlt, sodass die optionale Bubblewrap-Schicht unter Ubuntu-unter-WSL2 voraussichtlich funktioniert. Das ist eine Schlussfolgerung aus dem Kernel-Quellcode, nicht etwas, das wir ausgeführt haben. Falls bwrap dort fehlschlägt, sag es bitte in #189. cplts eigener seccomp-Filter ist ein einfaches PR_SET_SECCOMP-BPF-Programm, das sich auf den Filter stapelt, den WSL in jedem Prozess installiert.

Noch nicht auf einer echten WSL2-Installation verifiziert. Aus dem Quellcode verifiziert: Landlock ist einkompiliert und steht an erster Stelle in CONFIG_LSM im Microsoft-Kernel; die /mnt/<drive>/-Erkennung, die verwendeten WSL-Signale und ihr Fehlertext; dass cplt doctor bei einem solchen Agenten fehlschlägt und Kernel + Landlock-ABI ausgibt; die 5.13+/6.7+-Anforderungen; und dass install.sh das Linux-Release-Binary installiert. Noch von niemandem hier verifiziert: wie sich Landlock auf /mnt/c verhält, ob Bubblewrap unter WSL2 funktioniert, die genauen Paketversionen, die dein Distributions-Release mitbringt, und die obige Sequenz von Anfang bis Ende. Falls du es ausführst, berichte bitte, was tatsächlich passiert ist, in #189.

Shell-Einrichtung (empfohlen)

Standardmäßig bekommst du die Sandbox, indem du cplt eintippst. Damit auch einfaches copilot sandboxed läuft:```bash cplt --shell-install

root@kitploit:~
Das erkennt deine Shell, hängt den Alias an deine rc-Datei an und gibt aus, was es getan hat. Führe es so oft aus, wie du möchtest, es werden keine Duplikate hinzugefügt.

`--agent` legt fest, welcher Befehl den Alias erhält, und jeder Agent, den cplt starten kann, ist verfügbar:```bash
cplt --shell-install --agent opencode   # 'opencode' runs sandboxed
cplt --shell-install --agent claude     # and 'claude', alongside the others

Jede Installation ergänzt deine rc-Datei, anstatt das Vorhandene zu ersetzen, sodass du so viele Agents sandboxen kannst, wie du verwendest. Ohne --agent erhältst du copilot, was das Flag schon immer installiert hat.

ShellGeänderte DateiWas hinzugefügt wird (für --agent opencode)
zsh (macOS-Standard)~/.zshrceval "$(cplt --shell-setup --agent opencode)"
bash~/.bashrceval "$(cplt --shell-setup --agent opencode)"
fish~/.config/fish/conf.d/cplt.fishalias opencode 'cplt --agent opencode'

--agent antigravity installiert Aliase für sowohl antigravity als auch agy, da beide Namen denselben Agent starten.

Starte deine Shell neu oder source die Datei, um sie zu aktivieren.

Es gibt keinen Alias für --agent shell: Es gibt keine shell-Binärdatei zum Überschreiben. Gib cplt --agent shell für eine gesandboxte Shell ein, oder cplt exec -- <command> für einen einzelnen Befehl.

Manuelle Einrichtung (Alternative)

Wenn du --shell-install lieber nicht verwenden möchtest, füge die Zeile selbst hinzu:```bash

zsh / bash

eval "$(cplt --shell-setup --agent opencode)"

fish

alias opencode 'cplt --agent opencode'

root@kitploit:~
Dasselbe Muster, das mise, direnv und starship verwenden.
</details>

**Warum jeder Alias seinen Agenten benennt.** `alias opencode=cplt` würde nicht das tun, wonach es aussieht. Ein einfaches `cplt` wählt seinen Agenten aus `--agent`, dann aus der Konfigurationsdatei und schließlich aus dem, was es in PATH findet – und die PATH-Erkennung bevorzugt `copilot`. Wenn du `opencode` eingibst, würde stattdessen Copilot in einer Sandbox ausgeführt, ohne dass auf dem Bildschirm etwas darauf hinweist. Der Alias übergibt `--agent`, damit der Befehl, den du eingibst, auch der Agent ist, den du bekommst.

**Warum ein Alias statt eines Symlinks?** cplt und Copilot CLI installieren sich in dasselbe Homebrew-bin-Verzeichnis (`/opt/homebrew/bin/`), und dort kann nur eine Datei namens `copilot` liegen, sodass ein Symlink einen Konflikt verursachen würde. Ein Alias umgeht das. Die echte `copilot`-Binärdatei bleibt in PATH, wo cplt sie finden und umschließen kann, und der Alias leitet deinen Befehl um.

> **Hinweis:** cplt weigert sich zu verschachteln. Wenn es erkennt, dass es bereits in einer Sandbox läuft (über die Umgebungsvariable `__CPLT_WRAPPED`), startet es nicht erneut. Schreibgeschützte Unterbefehle wie `--print-profile` und `cplt doctor` funktionieren weiterhin innerhalb einer bestehenden Sandbox.

## Verwendung```
cplt [OPTIONS] [-- <AGENT_ARGS>...]

Alles nach -- geht direkt an den Agentenprozess (copilot, opencode, gemini, antigravity, pi, claude, goose, dsh oder shell).

Policy-Presets

Ein Preset setzt eine Baseline für die fünf Haupt-Sandbox-Toggles mit einem einzigen Flag statt einer Liste von ihnen. Einzelne Flags gewinnen weiterhin gegen das Preset, also tut --preset permissive --no-allow-tmp-exec genau das, was es sagt. Auch als [sandbox] preset = "..." in der Config setzbar.

Vollständige Preset-Matrix und Auflösungsreihenfolge: docs/configuration.md.

Dateizugriff

Das Projektverzeichnis ist der beschreibbare Arbeitsbereich, plus eine schmale Allowlist, die für Auth, Runtime und Tooling benötigt wird (siehe Tabelle oben). Der Kernel blockiert alles andere, SSH-Keys und Cloud-Credentials eingeschlossen.

Umgebungsvariablen

cplt bereinigt standardmäßig die Kindumgebung. Nur sichere Variablen werden durchgelassen, und Cloud-Credentials, Datenbank-URLs und Package-Tokens werden entfernt. Es injiziert außerdem Härtungsvariablen, die npm/yarn/pnpm-Lifecycle-Skripte blockieren (Postinstall-Hooks, der Supply-Chain-Angriffsvektor Nummer eins), Git-Commit- und Tag-Signierung deaktivieren (da ~/.ssh und ~/.gnupg innerhalb der Sandbox unerreichbar sind) und Developer-Tooling-Telemetrie abwählen (DO_NOT_TRACK=1, NEXT_TELEMETRY_DISABLED=1, TURBO_TELEMETRY_DISABLED=1, CHECKPOINT_DISABLE=1 und andere).

Was durchgelassen wird:

Präfix-Allowlist mit Secret-Suffix-Schutz. Eine Variable, die einem erlaubten Präfix wie COPILOT_* oder YARN_* entspricht, wird trotzdem verworfen, wenn sie auf ein secret-tragendes Suffix endet: _TOKEN, _AUTH, _SECRET, _SECRET_KEY, _KEY, _PASSWORD oder _CREDENTIALS. Also wird COPILOT_DEBUG durchgelassen und COPILOT_API_KEY nicht.

Immer blockiert: AWS_*, AZURE_*, NPM_TOKEN, DATABASE_URL, VAULT_TOKEN, SSH_AUTH_SOCK, Docker-Variablen, CI-Tokens und alles, was nicht in der Allowlist steht.

FlagWas es tut
--pass-env <VAR>Eine Umgebungsvariable an den Agenten durchreichen. Wiederholbar
--inherit-env⚠️ Gefährlich. Die vollständige Elternumgebung erben. Entfernt nur , , , . Nur zum Debuggen

Sandbox-Toggles

Unterstützte Runtimes

cplt entdeckt installierte Tools automatisch und schreibt passende Sandbox-Regeln. Im Allgemeinen erhalten nur Verzeichnisse, die auf der Festplatte existieren, Regeln, sodass es keine Phantom-Pfade gibt. Unter macOS werden beschreibbare App-Verzeichnisse bei Entdeckung einbezogen, auch wenn sie noch nicht existieren, sodass sie bei der ersten Verwendung erstellt werden können. Linux kann einen Schreibzugriff auf einen nicht existierenden Pfad nicht erlauben, also muss die Erstellung dort außerhalb der Sandbox erfolgen.

Führe cplt doctor aus, um zu sehen, ob cplt hier für deinen Agenten funktionieren wird, und cplt doctor --verbose für alles, was es auf deinem Rechner entdeckt hat.

Debugging

Session-Flags

Diese werden in die eigenen Session-Flags des Agenten übersetzt, sodass du kein ---Trennzeichen benötigst.

--continue und --resume werden auch für OpenCode, Antigravity und Claude Code gemappt:

¹ Weder OpenCode noch Antigravity hat einen interaktiven Session-Picker, also bedeutet ein bloßes --resume „letzte Sitzung fortsetzen". Claude Code hat einen, also wird es direkt übernommen.

--remote und --name sind nur für Copilot. Pi und Shell-Modus erhalten überhaupt keine Übersetzung, also werden alle vier Flags für sie verworfen. Auto-Resume ist ein separater Mechanismus: Wenn du cplt ohne Pass-Through-Args und ohne Session-Flags aufrufst, hängt es --resume für dich an, und das gilt nur für Copilot.

Kombiniere sie mit Sandbox-Flags und ---Pass-Through-Args:```bash cplt --resume=my-task # resume by name cplt --remote --name my-task -- -p "fix tests" # remote + named + prompt

root@kitploit:~
### Agents

Wähle einen mit `--agent <name>` aus oder mache ihn mit `cplt config set sandbox.agent <name>` zum Standard. Copilot, OpenCode und Antigravity werden automatisch aus `PATH` in dieser Reihenfolge erkannt, wenn du keinen benennst.

| Agent | `--agent`-Wert | Automatisch erkannt | Auth |
| --- | --- | --- | --- |
| GitHub Copilot CLI | `copilot` | ja, Priorität 1 | GitHub-Token, aus dem Keychain oder `gh` |
| [OpenCode](https://opencode.ai/) | `opencode` | ja, Priorität 2 | Copilot-Abonnement via `/connect` oder `--pass-env ANTHROPIC_API_KEY` |
| [Antigravity CLI](https://github.com/google-antigravity/antigravity-cli) | `antigravity`, Aliase `agy` und `agi` | ja, Priorität 3 | Google OAuth im Browser |
| [Pi](https://github.com/earendil-works/pi) | `pi` | nein | `--pass-env ANTHROPIC_API_KEY` und Verwandte |
| [Claude Code](https://docs.anthropic.com/en/docs/claude-code) | `claude`, Aliase `cc` und `claude-code` | nein | Abonnement-OAuth in `~/.claude` oder dem Keychain, `CLAUDE_CODE_OAUTH_TOKEN` (entfernt die Keychain-Berechtigung) oder `--pass-env ANTHROPIC_API_KEY` |
| [DeepSeek Harness](https://github.com/deepseek-ai/deepseek-harness) | `dsh`, Aliase `deepseek` und `deepseek-harness` | nein | `--pass-env DEEPSEEK_API_KEY` oder `$DSH_HOME/.env` (`~/.dsh/.env`) |
| Deine Shell | `shell` | nein | keine |

- **Pi, Claude Code, goose und DeepSeek Harness werden nie automatisch erkannt.** `pi` und `dsh` sind generische Binärnamen, die mit etwas anderem auf deinem Rechner kollidieren könnten, und Claude Code muss bewusst ausgewählt werden.
- **API-Schlüssel von Drittanbietern sind Opt-in.** `ANTHROPIC_API_KEY`, `OPENAI_API_KEY`, `GEMINI_API_KEY`, `OPENROUTER_API_KEY`, `ANTHROPIC_AUTH_TOKEN`, `CLAUDE_CODE_OAUTH_TOKEN` und die Bedrock/Vertex-Routing-Variablen (`CLAUDE_CODE_USE_BEDROCK`, `AWS_BEARER_TOKEN_BEDROCK`, `CLAUDE_CODE_USE_VERTEX`, `ANTHROPIC_VERTEX_PROJECT_ID`, `GOOGLE_CLOUD_PROJECT`) werden nie durchgereicht, es sei denn, du benennst sie mit `--pass-env`.
- **Abonnement-Auth benötigt keine Umgebungsvariable.** Der `/connect`-Device-Flow von OpenCode speichert sein Token in `~/.local/share/opencode/auth.json`, und das OAuth-Token von Claude Code liegt in `~/.claude` (`.credentials.json` unter Linux) oder im macOS-Keychain. Beide sind innerhalb der Sandbox erreichbar, sodass cplt bei keinem von beiden wegen eines fehlenden API-Schlüssels nervt.
- **OAuth-Browser-Flows benötigen `--allow-browser`**, wenn eine Anmeldeaufforderung erscheint. Das betrifft Antigravity; jeder andere Agent hier verwendet einen Device-Flow, der einen Code und eine URL ausgibt und keinen Browser benötigt. Das Flag erlaubt dem Agenten, jede Anwendung außerhalb der Sandbox zu starten, und kann nicht auf URLs eingeschränkt werden, also aktiviere es für die Anmeldung und deaktiviere es danach wieder — siehe die [Flag-Tabelle](#sandbox-toggles) und [docs/security.md](https://github.com/navikt/cplt/blob/main/docs/security.md#--allow-browser-is-a-sandbox-escape-and-cannot-be-scoped).
- **Claude Code Auto-Update ist deaktiviert** mit `DISABLE_AUTOUPDATER=1`. Claude Code hat kein `--no-auto-update`-Flag, Selbstaktualisierung innerhalb der Sandbox ist ein Persistenzvektor, und sie würde ohnehin an schreibgeschützten Installationspfaden scheitern.
- **`CLAUDE_CONFIG_DIR` wird berücksichtigt.** Wenn es gesetzt ist, gewährt cplt dieses Verzeichnis anstelle von `~/.claude` und reicht die Variable durch, sodass ein verschobenes Konfigurationsstammverzeichnis weiterhin funktioniert.
- OpenCode ist [ein offiziell unterstützter Copilot-Client](https://github.blog/changelog/2026-01-16-github-copilot-now-supports-opencode/), sodass dein bestehendes Copilot-Abonnement mit `/connect` innerhalb von OpenCode funktioniert.

Konfigurationsverzeichnisse pro Agent, Keychain-Nutzung, Exec-Berechtigungen und Env-Isolation findest du in [SECURITY.md](https://github.com/navikt/cplt/blob/main/SECURITY.md#supported-agents).

### goose-Unterstützung

cplt kann [goose](https://github.com/aaif-goose/goose) sandboxen, den Open-Source-KI-Agenten (Binärdatei `goose`). Verifiziert gegen goose 1.48.0.```bash
# Run goose (must be explicit — not auto-detected)
cplt --agent goose

# goose is provider-agnostic — pass your provider's API key
cplt --agent goose --pass-env ANTHROPIC_API_KEY
cplt --agent goose --pass-env OPENAI_API_KEY

# Skip the keyring entirely: keep the key in the environment
GOOSE_DISABLE_KEYRING=1 cplt --agent goose --pass-env OPENAI_API_KEY --pass-env GOOSE_DISABLE_KEYRING

# Set goose as your default agent
cplt config set sandbox.agent goose

Sicherheitshinweise für goose:

  • Nicht automatisch erkannt: explizit auswählen mit --agent goose oder sandbox.agent = "goose" in der Konfiguration setzen
  • Provider-agnostisch: goose leitet den Modellverkehr an einen vom Benutzer konfigurierten Provider weiter (Anthropic, OpenAI, Google, Databricks, OpenRouter, …). Gängige Provider-Schlüssel (ANTHROPIC_API_KEY, OPENAI_API_KEY, AZURE_OPENAI_API_KEY, GOOGLE_API_KEY, DATABRICKS_HOST/DATABRICKS_TOKEN, GROQ_API_KEY, OPENROUTER_API_KEY, XAI_API_KEY, AWS_BEARER_TOKEN_BEDROCK) werden als Auth-Hinweise erkannt und müssen über --pass-env übergeben werden. goose liest , nicht . Jeder Provider außerhalb dieser Teilmenge funktioniert trotzdem: Benennen Sie seine Variable mit

DeepSeek Harness-Unterstützung

cplt kann DeepSeek Harness (Binary dsh) sandboxen, das plugin-orientierte Agent-Harness von DeepSeek. Upstream liefert es als Developer Preview aus, und seine eigene SAFETY.md besagt, dass man sich nicht auf seine Kontrollen als einzige Grenze verlassen sollte — genau der Fall, für den cplt existiert.```bash

Run DSH (must be explicit — not auto-detected)

cplt --agent dsh

Pass the API key, or keep it in $DSH_HOME/.env

cplt --agent dsh --pass-env DEEPSEEK_API_KEY

Set DSH as your default agent

cplt config set sandbox.agent dsh

root@kitploit:~
**Sicherheitshinweise für DSH:**
- **Nicht automatisch erkannt**: Wähle es mit `--agent dsh` (Aliase `deepseek`, `deepseek-harness`) aus oder setze `sandbox.agent = "dsh"`. `dsh` ist ein kurzer, generischer Befehlsname, der auf deinem System zu etwas anderem gehören könnte
- **Schalte DSHs eigene Sandbox innerhalb von cplt aus**: DSH verpackt jeden Shell- und Datei-Tool-Aufruf in seine eigene Prozess-Sandbox — Seatbelt unter macOS, bwrap oder Landlock unter Linux. Keine davon lässt sich in cplt verschachteln. macOS unterstützt keine verschachtelten `sandbox-exec`-Aufrufe (dieselbe Einschränkung, die cplt dazu bringt, Gradles innere Sandbox zu deaktivieren, siehe [Limitations](#limitations)), und bwrap baut seinen Namespace mit `unshare` auf, was cplts seccomp-Filter verweigert. cplt ist in jedem Fall die durchsetzende Grenze, also wähle für sandboxed Sessions das von DSH mitgelieferte Berechtigungs-Preset `danger-full-access`. Lass den inneren Runner aktiviert und Tool-Aufrufe schlagen mit einem Sandbox-Runner-Fehler statt einem Task-Fehler fehl
- **Ein Home-Root, und cplt folgt der Überschreibung**: DSH speichert Sessions, Einstellungen, Cache und Profile unter `$DSH_HOME` (standardmäßig `~/.dsh`). `DSH_HOME` steht auf der Env-Allowlist, sodass das Kind denselben Root auflöst, den cplt gewährt. Ein Wert, der auf ein System-Root oder dein Home-Verzeichnis zeigt, wird vor dem Start abgelehnt — dasselbe Veto, das `CLAUDE_CONFIG_DIR` durchläuft
- **Host-Persistenz-Guard**: `$DSH_HOME/cordis.patch.yml`, das Home-Level-Overlay, das der Loader beim Boot liest, ist schreibgeschützt. `$DSH_HOME/profiles/` bleibt beschreibbar, weil DSH bei jedem Boot den Include-Root von `cordis.yml` jedes Profils neu schreibt, sodass ein profilweises `cordis.patch.yml` und installierte Plugins ein dokumentiertes Residuum sind — nimm Profil- und `dsh plugin`-Änderungen außerhalb von cplt vor und starte `dsh` immer über cplt, damit alles Eingeschleuste trotzdem sandboxed läuft
- **Standard-Domains**: nur `deepseek.com`. Der mitgelieferte `dsh-llm-deepseek`-Adapter verwendet standardmäßig `https://api.deepseek.com`. Richte `DEEPSEEK_BASE_URL` auf ein Gateway und du musst die Domain dieses Gateways über `allowed_domains` hinzufügen
- **Auth**: Übergib den Key mit `--pass-env DEEPSEEK_API_KEY` oder bewahre ihn in `$DSH_HOME/.env` auf. Ein Key, der über DSHs eigene Models-UI gespeichert wird, landet in `$DSH_HOME/.credentials.yaml`, innerhalb desselben beschreibbaren Roots. Der macOS Keychain ist gesperrt, also benötigt `git push` über HTTPS das Token von `gh` in `hosts.yml` oder `--pass-env GH_TOKEN`

### Shell-Modus

Führe eine einfache sandboxed Shell ohne KI-Agent und mit denselben Einschränkungen aus. Praktisch zum Testen von Build-Tools, zum Debuggen von Sandbox-Problemen oder einfach zum sorgfältigen manuellen Arbeiten.```bash
# Interactive sandboxed shell (uses $SHELL: fish, zsh, bash)
cplt --agent shell

# Inspect what's allowed without entering the shell
cplt --agent shell --print-profile

Die gleichen Deny-by-default-Regeln gelten: Dateisystem-Isolierung, Netzwerkbeschränkungen, Env-Bereinigung. Shell-Konfigurationsverzeichnisse (fish-Variablen und -History, zsh-History) bleiben beschreibbar.

Für einen einzelnen Befehl ist cplt exec sauberer als cplt --agent shell -- -c 'cmd'.

Exec-Modus

Führe einen beliebigen Befehl innerhalb der Sandbox aus, ohne einen Agenten zu starten. Kein Startbanner, keine Bestätigungsaufforderung, daher eignet es sich für Skripte, Pipes und Shell-Aliase.```bash

Sandbox a single command

cplt exec -- npm install cplt exec -- make build cplt exec -- go test ./...

Compound commands via $SHELL -c

cplt exec -c "npm install && npm test"

Pass sandbox flags as usual

cplt exec --allow-lifecycle-scripts -- npm install cplt exec --project-dir /path/to/repo -- make build cplt exec --with-proxy -- curl https://example.com

Shell aliases for sandboxed tools

alias npm="cplt exec -- npm" alias node="cplt exec -- node" alias python="cplt exec -- python"

root@kitploit:~
Jedes Top-Level-`cplt`-Flag gilt: `--project-dir`, `--allow-read`, `--deny-path`, `--with-proxy`, `--pass-env` und der Rest. Füge `--no-quiet` hinzu, um die vollständige Zusammenfassung der Sandbox-Konfiguration zu sehen, bevor der Befehl ausgeführt wird.

### Beispiele```bash
# The common case: Copilot in the sandbox
cplt -- -p "fix the tests"

# Sessions
cplt --resume                                   # pick one interactively
cplt --resume=my-refactor                       # by name
cplt --continue                                 # most recent in this directory
cplt --remote --name my-task -- -p "fix tests"  # named remote session

# Check the environment before the first run
cplt doctor

# Let Copilot read a shared library directory
cplt --allow-read ~/shared-libs -- -p "use shared-libs"

# Block a path you don't want Copilot to see
cplt --deny-path ~/.config/gh -- -p "refactor auth"

# Extra outbound port, e.g. an external API
cplt --allow-port 8443 -- -p "test the API"

# Localhost for MCP servers or dev servers
cplt --allow-localhost 3000 --allow-localhost 8080 -- -p "use the MCP server"

# All of localhost, needed by Next.js/Turbopack and Vite builds
cplt --allow-localhost-any -- -p "fix the build"

# Pass specific env vars through
cplt --pass-env MY_CUSTOM_VAR --pass-env ANOTHER_VAR -- -p "run with custom config"

# Inherit the full environment (dangerous, debugging only)
cplt --inherit-env -- -p "debug the build"

# Network
cplt --no-proxy -- -p "fix the tests"                    # proxy is on by default
cplt --blocked-domains ./blocked-domains.txt -- -p "refactor"
cplt --allow-private-domain intern.nav.no -- -p "use mcp-onboarding"

# Non-interactive / CI (skip the confirmation prompt)
cplt --yes -- -p "fix the tests"

# Inspect and debug the sandbox itself
cplt --print-profile
cplt --show-denials -- -p "fix the tests"

Konfiguration

Die Konfiguration erfolgt auf zwei Ebenen: global, für Entwicklerpräferenzen, und pro Repository, für Teamrichtlinien.```bash

Browse and change settings interactively

cplt settings

Set global preferences

cplt config set sandbox.quiet true cplt config set proxy.blocked_domains "~/.config/cplt/blocked-domains.txt" cplt config set git_guard.mode warn # observe pushes instead of blocking them cplt config set gh_guard.enabled false # opt out of the gh guard entirely

Set per-repo policy (committed to .cplt.toml)

cplt config set --repo sandbox.allow_jvm_attach true cplt config set --repo deny.paths "~/secrets"

Inspect

cplt config show # effective config (file + defaults) cplt config explain # every key with its description

root@kitploit:~
`cplt settings` ist der interaktive Editor mit den Ansichten Effective, Global und Repository, Suche, gestaffelten Änderungen und einer expliziten Bestätigung, bevor sicherheitsrelevante Einstellungen gespeichert werden. `cplt config` bleibt die stabile nicht-interaktive Schnittstelle für Skripte und CI. Repository-Vorschläge werden weiterhin separat mit `cplt trust` committet und genehmigt. Der Editor committet oder genehmigt sie niemals automatisch.

Die Rangfolge verläuft über CLI-Flags, dann die globale Konfigurationsdatei unter `~/.config/cplt/config.toml`, dann integrierte Standardwerte. Die Konfiguration pro Repository in `.cplt.toml` ist eine separate Ebene und keine Sprosse auf dieser Leiter: `[deny]` verschärft bedingungslos, und genehmigte Berechtigungen sind ausschließlich additiv, sodass ein Repository eine Funktion aktivieren, aber niemals etwas deaktivieren kann, das durch ein CLI-Flag oder die globale Konfiguration festgelegt wurde.

Eine `.cplt.toml` im Repository-Stammverzeichnis enthält die Team-Richtlinie:```toml
[deny]                    # Applied automatically, no opt-in needed
paths = ["~/secrets", "~/.vault-token"]
env = ["VAULT_TOKEN", "DATABASE_URL"]

[propose]                 # Requires developer approval (cplt trust accept)
gh_guard = true
git_push_prevention = true
allow_jvm_attach = true
allow_docker = true

[propose.allow]
ports = [5432]
localhost = [3000]
socket = ["/var/run/docker.sock"]

cplt liest sie aus git HEAD, sodass der Agent seine eigene Richtlinie nicht mitten in der Sitzung manipulieren kann und Trust-Genehmigungen an den Inhalt der Datei gebunden sind. Eine nicht committete .cplt.toml gewährt nichts, bis sie committet wird, obwohl ihre [deny]-Schlüssel weiterhin gelten. In CI und Skripten, wo niemand eine Eingabeaufforderung beantworten kann, genehmigt --accept-repo-config die Vorschläge der committeten Datei für diesen einen Lauf, ohne einen Trust zu persistieren. cplt init schreibt eine für dich, indem es die Tooling-Landschaft des Projekts erkennt:```bash cplt init # preview detected permissions cplt init --write # write .cplt.toml to disk cplt init --quiet # output only TOML (pipe-friendly) cplt init --global # generate a personal ~/.config/cplt/config.toml

root@kitploit:~
Es kennt JVM (Gradle/Maven), Node.js, Docker, Python, Rust, Go, Playwright, Spring Boot, Ktor, TestContainers, Next.js, Vite, Flyway, Cypress und Umgebungsgeheimnisse aus `.env.example`. Gefährliche Berechtigungen kommen mit einer Risikowarnung versehen aus dem Generator heraus. `--global` betrachtet stattdessen Dinge auf Maschinenebene: Playwright-Browser, GPG-Signierung, Registry-Anmeldedaten, alternative Agenten.

Einige Schlüssel sind nur global gültig und werden aus `.cplt.toml` abgelehnt, weil sie maschinenspezifisch oder eine lokale Präferenz sind: `sandbox.agent`, `sandbox.quiet`, `sandbox.yes`, `sandbox.validate`, `sandbox.scratch_dir`, `sandbox.pass_env`, `sandbox.inherit_env`, `sandbox.allow_cache_exec`, `sandbox.allow_cache_exec_any`, `proxy.enabled`, `proxy.port`, `proxy.log_file`, `proxy.log_level`, `proxy.blocked_domains`, `proxy.allowed_domains` und jeder `[gh_guard]`- und `[git_guard]`-Schlüssel.

Vollständige Details, einschließlich des Vertrauensmodells, der Pfaderweiterungsregeln und der vollständigen Konfigurationsdateireferenz: [docs/configuration.md](https://github.com/navikt/cplt/blob/main/docs/configuration.md).

## Architektur```
┌──────────────────────────────────┐
│  cplt (Rust binary)              │
│  ┌───────────┐  ┌─────────────┐  │
│  │ Policy    │  │ CONNECT     │  │
│  │ Generator │  │ Proxy       │  │
│  └─────┬─────┘  │ (optional)  │  │
│        │        └─────────────┘  │
│        ▼                         │
│  ┌─────────────┬────────────┐    │
│  │   macOS     │   Linux    │    │
│  │  Seatbelt   │  Landlock  │    │
│  │  sandbox-   │  + seccomp │    │
│  │  exec       │  pre_exec  │    │
│  └─────────────┴────────────┘    │
│        │                         │
│        ▼                         │
│  copilot (sandboxed)             │
│  ├── All child processes         │
│  ├── Cannot read ~/.ssh          │
│  ├── Network port-restricted     │
│  ├── SSH agent blocked           │
│  └── Filesystem = primary ctrl   │
└──────────────────────────────────┘

Das Sicherheitsmodell ist ein Dateisystem mit Deny-by-Default und Kernel-Durchsetzung. Unter macOS und unter Linux mit Kernel 6.7+ (Landlock ABI v4) ist das Netzwerk standardmäßig auf Port 443 beschränkt, mit --allow-port für zusätzliche Ports. Auf älteren Linux-Kernels übernimmt der CONNECT-Proxy diese Beschränkung, weshalb er standardmäßig aktiviert ist. SSH-Agent-Zugriff und ausgehende Verbindungen zu localhost werden unter macOS im Kernel blockiert. Unter Linux ist weder das eine noch das andere der Fall: Port-basierte Landlock-Regeln können localhost nicht von einem entfernten Host unterscheiden, und unix socket connect() wird von Landlock unterhalb von Kernel 7.1 nicht abgefangen, sodass – abgesehen von den Sockets, die bubblewrap maskiert – der zurückgehaltene SSH_AUTH_SOCK das Einzige ist, was zwischen dem Agenten und deinen geladenen Schlüsseln steht. Der Profilgenerator erkennt deine Umgebung (cplt doctor --verbose zeigt dieselben Probe-Ergebnisse) und erzeugt Regeln nur für Tool-Verzeichnisse, die tatsächlich auf der Festplatte existieren. Weniger Regeln, engere Sandbox.

  • macOS: Ein Seatbelt/SBPL-Profil wird generiert und an sandbox-exec übergeben
  • Linux: Landlock-LSM-Regeln plus ein seccomp-BPF-Filter, angewendet über pre_exec (Kernel 5.13+, TCP-Port-Filterung ab 6.7+)

Interna und Modulaufbau: docs/architecture.md. Bedrohungsmodell, Verteidigungsschichten und ehrliche Lücken: SECURITY.md.

Sicherheit

Ein Binary, minimale Abhängigkeiten, keine Laufzeitdienste, keine Telemetrie. Drei Verteidigungsschichten mit klaren Grenzen dazwischen:

Wogegen cplt schützt:

  • Exfiltration von Geheimnissen (SSH-Schlüssel, Cloud-Anmeldedaten, .env-Dateien): kernel-blockiert
  • Unautorisierte Codeausführung aus Temp-Verzeichnissen: kernel-blockiert
  • Persistenz über Binaries in Cache-Verzeichnissen: kernel-blockiert, da für diese Verzeichnisse exec verweigert wird
  • Persistenz über Git-Hooks im Projekt: .git/hooks ist unter macOS im Kernel schreibgeschützt. Unter Linux bleibt es mit Landlock und ohne Bubblewrap beschreibbar, und cplts eigenes parent-seitiges git läuft dann mit core.hooksPath=/dev/null, sodass es niemals einen platzierten Hook ausführt – ein git, das du selbst ausführst, jedoch schon
  • Persistenz über Package-Manager-Tool-Verzeichnisse, die sowohl beschreibbar als auch ausführbar sind (mise-Shims, PNPM_HOME, ~/.deno/bin, ~/.bun/bin): Schreibzugriff wird dort gewährt, damit pnpm add -g und Verwandte in der Sandbox funktionieren, sodass ein Agent ein Binary hinterlassen kann, das eine spätere Shell aus deinem PATH aufgreift
  • Ein platziertes Binary, das den Agenten kapert, den cplt startet: Beim Start und Audit löst cplt die Helfer, die es selbst ausführt (, , , und das , aus dem es ein Token liest), aus festen Systemverzeichnissen statt aus auf, aber das Agent-Binary selbst läuft von dort, wo es entdeckt wurde, was bei einer npm-global-Installation üblicherweise unter einem beschreibbaren mise- oder node-Baum liegt. cplt kann es nicht aus einem festen Verzeichnis auflösen – es lebt legitimerweise dort, wo dein Versionsmanager es abgelegt hat –, also prüft es den aufgelösten Pfad gegen die Schreibregeln, die die Sandbox gleich anwenden wird, und , wobei es das Binary und den beschreibbaren Baum benennt, und fährt dann fort

Wogegen cplt nicht schützt:

  • Bösartigen Code, der sich bereits im Projektverzeichnis befindet. Der Agent hat dort vollständigen Lese-/Schreibzugriff
  • Logikfehler, die der Agent einführt. Du reviewst den Code weiterhin
  • Einen raffinierten Angreifer, der den Command-Guard umgeht. Verwende serverseitigen Branch-Schutz
  • Netzwerkangriffe auf erlaubte Domains. Wenn github.com erlaubt ist, kann der Agent dort lesen und schreiben
  • macOS-Keychain-Zugriff für Agenten, die dort Auth speichern. Die Inhalte sind passwortgeschützt, und sandbox.keychain_substitute kann die Gewährung aufgeben, wo ein Agent eine andere Anmeldedatenquelle hat

Unsere Prioritäten, in dieser Reihenfolge: korrekt (jede Behauptung ist getestet, jeder Edge Case hat eine CVE- oder Forschungsreferenz), transparent (SECURITY.md verbirgt nichts), einfach (ein Binary, keine Konfiguration erforderlich, vernünftige Standardwerte) und nützlich (aus dem Weg gehen und den Agenten sicher arbeiten lassen).

Mehr: docs/security.md · SECURITY.md

Netzwerk und Proxy

Der Proxy ist standardmäßig aktiviert. Der gesamte ausgehende Datenverkehr von Copilot CLI, gh und curl läuft über einen localhost-CONNECT-Proxy via HTTP_PROXY/HTTPS_PROXY und NODE_USE_ENV_PROXY=1. Er lauscht auf einem vom Betriebssystem zugewiesenen ephemeren Port, sodass nichts kollidiert. Du erhältst Verbindungsprotokollierung in Echtzeit, Domain-Blockierung, Domain-Allowlisting, ein persistentes Audit-Log und dieselbe Port-Richtlinie, die die Sandbox durchsetzt (443 plus alles in allow.ports).```bash cplt --proxy-forced -- -p "fix tests" # force all egress through the proxy cplt --no-proxy -- -p "fix tests" # disable for one run cplt --blocked-domains blocked-domains.txt -- -p "x" # block known-bad domains cplt --allowed-domains allowed-domains.txt -- -p "x" # allowlist mode cplt --default-allowlist -- -p "x" # fail-closed: only the agent's own domains cplt --observe-domains -- -p "x" # record what the agent contacts, block nothing cplt --proxy-upstream http://proxy.corp:8080 -- -p "x" # chain through a corporate proxy

root@kitploit:~
`--observe-domains-out <FILE>` schreibt die beobachtete Menge, eine Domain pro Zeile, und
`--proxy-upstream-no-proxy <HOST>` listet Hosts auf, die direkt statt über
das Upstream erreicht werden sollen.```bash
cplt config set proxy.enabled false
cplt config set proxy.blocked_domains "~/.config/cplt/blocked-domains.txt"
cplt config set proxy.allowed_domains "~/.config/cplt/allowed-domains.txt"
cplt config set proxy.log_file "~/.config/cplt/proxy.log"

Der Proxy-erzwungene Modus ist Opt-in. Er beschränkt den Kernel-Egress auf den Proxy-Port, sodass ein direkt geöffneter Socket oder ein env -u HTTPS_PROXY nicht vorbeischlüpfen kann. Die Durchsetzung ist auf macOS vollständig, wo auf localhost:<proxy_port> festgelegt wird. Unter Linux blockiert er direktes TCP :443, und eine seccomp-Regel erlaubt nur SOCK_STREAM mit Protokoll 0 oder IPPROTO_TCP für AF_INET/AF_INET6, sodass auch UDP, Raw, SCTP und DCCP geschlossen sind — auf Kosten von allem, was einen solchen Socket öffnet, nicht nur von Code, der UDP sendet. Was bleibt, ist ein portbasierter Rest, evil.com:<proxy_port>, bis #114.

Außerhalb des Proxy-erzwungenen Modus schränkt Linux UDP nicht ein. Landlocks Netzwerkrechte sind bis ABI v10 nur TCP, cplt behandelt AccessNet::ConnectTcp allein, und die obige seccomp-Regel wird bewusst nicht angewendet — SOCK_DGRAM dort zu verweigern würde getaddrinfo(3) und damit alles DNS für jedes nicht über den Proxy laufende Tool brechen. Ausgehendes UDP zu jedem Host, eingehender UDP-Bind, DNS-Tunneling und QUIC/HTTP-3 sind daher im Standardmodus unvermittelt, und der CONNECT-Proxy überträgt nur TCP, sodass nichts davon im Proxy-Log erscheint. macOS schränkt UDP im Standardmodus ein, leitet es aber auch nicht weiter: remote ip "*:443" deckt UDP ab, sodass QUIC/HTTP-3 auf 443 auch dort den Proxy nicht berührt. Unter proxy.forced ist das Proxy-Log auf macOS eine vollständige Aufzeichnung des Egress. Unter Linux ist es vollständig, außer für den obigen Rest evil.com:<proxy_port>, der den Proxy nicht durchläuft und daher nicht in seinem Log erscheint.

Beide Listen stimmen auf dieselbe Weise überein: example.com deckt die exakte Domain und jede Subdomain ab, der Abgleich ist case-insensitive, und abschließende Punkte werden entfernt. Blocklist- und Allowlist-Dateien werden alle fünf Sekunden neu eingelesen, sodass du sie live bearbeiten kannst. Localhost-Verkehr umgeht den Proxy über NO_PROXY und erscheint nie im Audit-Log. --proxy-timeout <SECONDS> begrenzt Anfrage- und Header-Lesevorgänge (Standard 60) und baut keine etablierten CONNECT-Tunnel ab, die bis zu einer Stunde im Leerlauf bleiben können.

Jedes Proxy-Flag, jedes Detail zur Domain-Filterung, Upstream-Corporate-Proxy-Verkettung und das Format des Verbindungslogs: docs/proxy.md.

Command guards

Aktiviere sie, und cplt fängt gh und git über Wrapper-Skripte in $PATH ab:

Dies ist Layer 3, eine weiche Barriere. Sie hält einen regelkonformen Agenten davon ab, versehentlich etwas Destruktives zu tun. Für eine harte Grenze stütze dich auf die Kernel-Sandbox und den serverseitigen Branch-Schutz.

Mit aktiviertem gh-Guard cached cplt außerdem das GitHub-Token beim Start und liefert es einmal über den gh auth token-Callback aus, dann löscht es den Cache. Das reduziert versehentliches und umgebungsbedingtes Leaken. Es ist keine Grenze gegen einen feindseligen Agenten, denn der Cache liegt im eigenen TMPDIR des Agenten, und ein Agent, der ihn vor dem legitimen Konsumenten liest, bekommt das Token trotzdem. SECURITY.md enthält die vollständige Erklärung zu block_auth_token.

Vollständiges Verhalten: docs/gh-guard.md · docs/git-guard.md

Known impacts

Die Sandbox blockiert einige Workflows absichtlich. Die häufigen und ihre Fixes:

Playwright Chromium benötigt cplt config set sandbox.allow_cache_exec ms-playwright, und Chromium muss ohne seine eigene verschachtelte Sandbox laufen. Auf macOS können seine Helper keine zweite Seatbelt-Sandbox innerhalb von cplt initialisieren (forbidden-sandbox-reinit); unter Linux blockiert cplts seccomp-Filter die Namespace-Syscalls, die diese Sandbox benötigt. Playwright als Bibliothek startet bereits mit --no-sandbox, und dasselbe Opt-in setzt PLAYWRIGHT_MCP_SANDBOX=false für Playwright MCP, das es sonst wieder einschalten würde. Jeder andere Chromium-Launcher benötigt selbst --no-sandbox. cplt bleibt die durchsetzende Kernel-Grenze, aber ein kompromittierter Renderer erhält dann das vollständige cplt-Playwright-Profil statt Chromiums engerem Child-Profil. Siehe Cache exec und SECURITY.md.

Git commit funktioniert für jeden Agenten; ob git push über HTTPS funktioniert, hängt vom Agenten ab. Drei Voraussetzungen: HTTPS-Remotes statt SSH verwenden (git remote set-url origin https://github.com/org/repo.git, oder global umschreiben mit git config --global url."https://github.com/".insteadOf "[email protected]:"), einmal gh auth login außerhalb der Sandbox ausführen und gh auth setup-git ausführen, falls der Credential-Helper noch nicht konfiguriert ist. Push führt dann gh auth git-credential aus, was ein Token benötigt, das gh von innerhalb der Sandbox erreichen kann — das unterscheidet sich je nach Agent, siehe Git workflow. Pushes auf den Default-Branch und alle Force-Pushes werden standardmäßig vom git-Guard verweigert; pushe einen Feature-Branch. Der SSH-Agent-Socket ist blockiert, weil er jeden geladenen Key entsperrt und sich bei jedem Host authentifizieren kann, während der gh-Credential-Helper auf GitHub beschränkt ist.

Die JVM ist proxy-aware, daher muss ein internes Maven-Repository auf einer privaten IP jetzt erlaubt werden. cplt injiziert http(s).proxyHost/proxyPort in JAVA_TOOL_OPTIONS, sodass die Gradle- und Maven-Abhängigkeitsauflösung über den CONNECT-Proxy läuft und im Proxy-Log erscheint, statt ihn zu umgehen. Der SSRF-Guard des Proxys verweigert dann ein internes Nexus oder Artifactory, das in den privaten Adressraum auflöst, genau wie er es bereits für curl, npm und pip tut. Füge seinen DNS-Namen zu proxy.allow_private_domains hinzu. Eine Repository-URL, die als bloßes IP-Literal geschrieben ist (https://10.20.30.40/repository/maven-public/), kann durch keinen Key erlaubt werden — diese Prüfung läuft, bevor die Allow-List konsultiert wird —, daher benötigt ein solches Repository einen DNS-Namen. WorkerExecutor-Plugin-Forks und ein Gradle-Daemon, der außerhalb von cplt gestartet und innerhalb wiederverwendet wird, laufen nicht über den Proxy. Siehe Internal Maven/Gradle repositories on private IPs.

Gradle 9+ führt seine eigene verschachtelte Sandbox aus, und cplt schaltet sie ab. Seit Gradle 8.8 hüllt sich der Daemon in sandbox-exec (gesteuert durch GRADLE_MACOS_SANDBOX, früher die Property org.gradle.daemon.sandbox). macOS unterstützt keine verschachtelten sandbox-exec-Aufrufe, daher schlägt die innere Sandbox bei Socket-Operationen mit "Operation not permitted" fehl. cplt injiziert GRADLE_MACOS_SANDBOX=off, da es bereits Sandboxing auf Kernel-Ebene bereitstellt. Dies ist ein bekanntes Upstream-Problem, das jedes Tool trifft, das Gradle in eine äußere Sandbox einhüllt. Überschreibe mit --pass-env GRADLE_MACOS_SANDBOX, wenn du wirklich Gradles eigene Sandbox willst.

Copilot CLI 1.0.83 führt seine eigene verschachtelte Sandbox aus, und cplt schaltet sie ab. Unter Linux baut diese Sandbox einen Netzwerk-Namespace auf — slirp4netns, iptables, /dev/net/tun — und cplts seccomp-Filter verweigert das dafür benötigte unshare. cplt setzt außerdem HTTP_PROXY/HTTPS_PROXY, was in 1.0.83 eine Linux-Sandbox auf den Proxy-Egress-Pfad bringt, ob du es wolltest oder nicht, sodass die beiden bei jedem Start kollidieren. Symptom: [cplt] Starting Copilot in sandbox... und dann nichts. cplt injiziert Copilots eigenes Opt-out, COPILOT_CLI_SANDBOX_SUPPORT_OVERRIDE=unsupported; Copilot tritt für die Sitzung zurück, sagt es, und lässt dein gespeichertes sandbox.enabled unangetastet. cplt ist die Grenze, wie bei Gradle und Chromium. Überschreibe mit --pass-env COPILOT_CLI_SANDBOX_SUPPORT_OVERRIDE. Eine unternehmensverwaltete Richtlinie, die die Sandbox erfordert, überschreibt all dies — siehe Copilot CLI's own command sandbox.

Jede Auswirkung, mit den Pro-Tool-Tabellen, JVM- und Kotlin-Daemon-Hinweisen, GPG-Fehlerbehebung und den Plattformunterschieden bei privaten Registries: docs/known-impacts.md.

Limitations

macOS

  • sandbox-exec ist veraltet. Apple hat es nicht entfernt, könnte es aber in einer zukünftigen macOS-Version tun.
  • SBPL hat keine domainbasierte Filterung. Der optionale CONNECT-Proxy bietet stattdessen Domain-Blocking.
  • SBPLs lsopen hat ebenfalls keinen Filter, daher ist --allow-browser alles von Launch Services oder nichts davon. Mit aktiviertem Flag kann der Agent jede Anwendung außerhalb der Sandbox starten, und kein Wrapper kann das einschränken — siehe docs/security.md.

Linux

  • Kernel 5.13+ erforderlich, mit aktiviertem Landlock LSM.
  • TCP-Port-Filterung benötigt Kernel 6.7+. Ältere Kernel erhalten nur Dateisystem-Durchsetzung.
  • Landlock kann keine Unterpfade innerhalb erlaubter Pfade verweigern, daher wird .env-Lesen/Schreiben/Löschen innerhalb des Projektverzeichnisses nicht vom Kernel durchgesetzt. .git/hooks-Schreibvorgänge werden blockiert, wenn Bubblewrap aktiv ist.
  • --deny-path erfordert Bubblewrap. Es wird über Mount-Masken durchgesetzt, wenn bwrap aktiv ist. Ohne es ist Landlock nur eine Allowlist und cplt warnt über das Deny, statt es anzuwenden.

Mehr: docs/security.md

Contributing

Beiträge sind willkommen.```bash git clone https://github.com/navikt/cplt.git && cd cplt git config core.hooksPath hack # enables pre-commit fmt + clippy checks mise run check # runs fmt, clippy, and tests

root@kitploit:~
Öffne ein Issue, bevor du eine große Änderung beginnst. Jeder PR muss CI bestehen (fmt, clippy, Tests).

## Referenzen

- [SECURITY.md](https://github.com/navikt/cplt/blob/main/SECURITY.md), das vollständige Sicherheitsmodell, die Bedrohungsanalyse, die Teststrategie und frühere Arbeiten
- [Apple sandbox-exec(1)](https://keith.github.io/xcode-man-pages/sandbox-exec.1.html)
- [Chromium Seatbelt V2 Design](https://chromium.googlesource.com/chromium/src/sandbox/+show/refs/heads/main/mac/seatbelt_sandbox_design.md)
- [Landlock LSM documentation](https://docs.kernel.org/userspace-api/landlock.html)
- [seccomp-BPF documentation](https://www.kernel.org/doc/html/latest/userspace-api/seccomp_filter.html)
- [OWASP SSRF Prevention Cheat Sheet](https://cheatsheetseries.owasp.org/cheatsheets/Server_Side_Request_Forgery_Prevention_Cheat_Sheet.html)
- [michaelneale/agent-seatbelt-sandbox](https://github.com/michaelneale/agent-seatbelt-sandbox)

## Lizenz

[MIT](https://github.com/navikt/cplt/blob/main/LICENSE)
Tool herunterladen
FlagWas es tut
--preset strictVollständiger Netzwerk-Lockdown. Alle fünf Toggles aus, plus gh_guard, git_guard, proxy.forced (erzwungener Proxy-Egress) und proxy.default_allowlist (fail-closed Domain-Allowlist) an. Notausgang: --allow-all-domains deaktiviert nur die Allowlist
--preset standardDie aktuellen Defaults. Alle fünf aus, Scratch-Verzeichnis bleibt an. Gleichbedeutend mit keinem Preset
--preset permissiveAktiviert allow_localhost_any, allow_tmp_exec und allow_lifecycle_scripts
--preset full-trust⚠️ Gefährlich. Aktiviert alle fünf, zusätzlich allow_env_files und allow_docker
FlagWas es tut
-d, --project-dir <DIR>In welchem Verzeichnis Copilot arbeiten darf. Standardmäßig das Root des aktuellen Git-Repos
--allow-read <PATH>Copilot erlauben, Dateien außerhalb des Projekts zu lesen, nur lesend. Wiederholbar
--allow-write <PATH>Copilot erlauben, außerhalb des Projekts zu lesen und zu schreiben. Mit Vorsicht verwenden. Wiederholbar. Der Baum ist beschreibbar, aber nicht ausführbar — ein Baum, der beides ist, ist ein Binary-Drop-Pfad, also stoppt ein allow.write über ~/.cargo auch die Ausführung von ~/.cargo/bin. Verwende --allow-exec auf einem separaten, nicht überlappenden Baum, wenn du beides brauchst
--allow-exec <PATH>⚠️ Gefährlich. Dem Agenten erlauben, Binaries aus einem Baum außerhalb der Standard-Tool-Verzeichnisse auszuführen — etwa ein verschobenes Homebrew- oder Toolchain-Prefix. Gewährt Lesen und Ausführen, niemals Schreiben. Wiederholbar. Wird für ein unsicheres Root (/, /tmp, $HOME und dessen Elternverzeichnisse, die Systemverzeichnisse der Plattform) und für jeden Baum abgelehnt, der einen beschreibbaren überlappt — das Projektverzeichnis, eine --allow-write-Gewährung, ein beschreibbares Tool-Verzeichnis wie ~/.cache, ein beschreibbares Agent-Datenverzeichnis (~/.claude, ~/.local/share/opencode, ~/.pi/agent und ähnliche), das echte .git eines Worktrees oder Bare-Repos, oder einen Baum, den die Backends ohne jegliche Gewährung beschreibbar machen (/tmp und /dev/shm unter Linux; /private/tmp und /private/var/folders unter macOS): beschreibbar plus ausführbar ist ein Binary-Drop-Pfad, und kein Backend kann die Schreibgewährung von der Exec-Gewährung abziehen
--allow-socket <PATH>⚠️ Gefährlich. Einen Unix-Domain-Socket-Pfad erlauben, zum Beispiel einen benutzerdefinierten LSP-Daemon oder einen Datenbank-Socket. Wiederholbar. Was auch immer am anderen Ende sitzt, läuft außerhalb der Sandbox, also ist das Zeigen auf docker.sock oder einen Agent-Socket gleichbedeutend mit --allow-docker, und der einzige Schutz ist, dass --deny-path-Überlappungen abgelehnt werden. Unter Linux tut es nichts unter Kernel 7.1, da Unix-Socket-Verbindungen vor ABI v9 nicht von Landlock gegated werden (siehe Linux-Einschränkungen)
--deny-path <PATH>Einen Pfad blockieren, der sonst erlaubt wäre. Deny gewinnt immer. Wiederholbar
--allow-port <PORT>Ausgehenden Verkehr auf einem zusätzlichen Port erlauben. Standardmäßig nur 443. Wiederholbar. Unter macOS lautet die Regel (remote ip "*:PORT"), was familienagnostisch ist und daher UDP ebenso wie TCP umfasst; Landlock gated nur TCP-Connect. Unter proxy.forced öffnet der Port überhaupt keinen direkten Socket — er ist durch den Proxy erreichbar, sodass proxy-bewusste Tools weiter funktionieren
--allow-localhost <PORT>Ausgehend zu localhost auf einem Port erlauben. Localhost ist standardmäßig blockiert. Für MCP-Server oder Dev-Server verwenden. Wiederholbar
--allow-localhost-anyAusgehend zu localhost auf allen Ports erlauben. Wird von Build-Tools wie Turbopack (Next.js) und Vite benötigt, die zufällige ephemere Ports für IPC verwenden
KategorieBeispieleWie
KernsystemHOME, USER, PATH, SHELL, TMPDIR, LANGExplizite Allowlist
TerminalTERM, COLORTERM, TERM_PROGRAMExplizite Allowlist
EditorEDITOR, VISUAL, PAGERExplizite Allowlist
Auth-TokensGH_TOKEN, GITHUB_TOKEN, COPILOT_GITHUB_TOKENNur durchgelassen, wenn du sie bereits gesetzt hast. Der gh-Guard verwendet stattdessen eine Einmaldatei
Copilot-ConfigCOPILOT_DEBUG, COPILOT_*Präfix-Allowlist
Sprach-RuntimesNODE_*, GOPATH, CARGO_HOME, JAVA_HOME, VIRTUAL_ENV, PYTHONPATHExplizite Allowlist
Tool-ManagerNVM_*, FNM_*, PYENV_*, MISE_*, SDKMAN_*, COREPACK_*, YARN_*Präfix-Allowlist
OpenTelemetryOTEL_EXPORTER_OTLP_ENDPOINT, OTEL_SERVICE_NAME, OTEL_RESOURCE_ATTRIBUTES, OTEL_*Präfix-Allowlist (OTEL_EXPORTER_OTLP_HEADERS kann Opt-in-Auth tragen)
XDG-VerzeichnisseXDG_CONFIG_HOME, XDG_DATA_HOME, XDG_STATE_HOME, XDG_CACHE_HOMEExplizite Allowlist
NO_COLOR
FORCE_COLOR
SSH_AUTH_SOCK
SSH_AGENT_PID
FlagWas es tut
--allow-lifecycle-scriptsnpm/yarn/pnpm-Lifecycle-Skripte (Postinstall-Hooks) ausführen lassen. Standardmäßig blockiert. Verwenden, wenn npm install sie benötigt
--allow-gpg-signingGPG-Commit- und Tag-Signierung innerhalb der Sandbox erlauben. Gewährt Lesezugriff auf den öffentlichen Schlüsselbund und den GPG-Agent-Socket. Private Schlüssel bleiben verweigert. Siehe GPG-Signierung
--allow-jvm-attachJVM-Attach-API-Unix-Sockets in /tmp erlauben. Benötigt für MockK-Inline-Mocking, Mockito-Inline-Agents, ByteBuddy. Siehe JVM Attach API
--allow-msbuildMSBuild-Worker-Node-Unix-Sockets in /tmp erlauben. Benötigt für dotnet build. Aktiviert nicht den persistenten MSBuild-Server. Siehe MSBuild-Worker-Node-IPC
--no-scratch-dirDas sitzungsbezogene Scratch-Verzeichnis deaktivieren, das standardmäßig an ist. TMPDIR wird nicht umgeleitet
--scratch-dirDas sitzungsbezogene Scratch-Verzeichnis explizit aktivieren. Ist bereits der Standard, also dient dies zum Überschreiben von scratch_dir = false in der Config
--brief🧪 Experimentell. Das agentengerichtete Sandbox-Brief in das Scratch-Verzeichnis schreiben (CPLT_BRIEF.md). Standardmäßig aus. Auch sandbox.brief = true in der Config. Instabil, kann sich also in einer zukünftigen Version ändern oder entfernt werden
--no-briefDas Sandbox-Brief für diesen Lauf ausschalten, überschreibt sandbox.brief = true in der Config. Unterdrückt außerdem den AGENTS.md-Block, der an das Brief gekoppelt ist
--agents-md🧪 Experimentell. Mit --brief zusätzlich den verwalteten cplt-Block in die AGENTS.md des Projekts schreiben. Standardmäßig aus. Auch sandbox.agents_md = true in der Config. Ohne --brief wirkungslos. Instabil, kann sich also in einer zukünftigen Version ändern oder entfernt werden
--no-agents-mdDen AGENTS.md-Block für diesen Lauf ausschalten, überschreibt sandbox.agents_md = true in der Config. Lässt das Scratch-Dir-Brief unberührt
--allow-tmp-exec⚠️ Gefährlich. Exec aus System-Temp-Verzeichnissen erlauben (/private/tmp, /private/var/folders). Bevorzuge das Scratch-Verzeichnis
--allow-cache-exec <SUBDIR>Exec aus einem ~/Library/Caches/<SUBDIR> erlauben. Wiederholbar. Für Tools, die dort kompilierte Binaries cachen, wie Playwright und pnpm dlx
--allow-cache-exec-any⚠️ Gefährlich. Exec aus dem gesamten ~/Library/Caches erlauben. Bevorzuge --allow-cache-exec <SUBDIR>
--allow-browser⚠️ Gefährlich. Mit diesem Flag kann der Agent jede Anwendung auf deinem Rechner außerhalb der Sandbox starten. Die Gewährung ist Launch Services, kein Browser: launchd startet das Ziel außerhalb des Seatbelt-Profils, also läuft open -a Terminal /tmp/x.sh unsandboxed. Dies kann nicht auf URLs beschränkt werden — SBPLs lsopen nimmt keinen Filter, und die Gewährung ist über LSOpenCFURLRef() auch ohne das open-Binary erreichbar, sodass kein Wrapper sie einschränken kann (#251, und docs/security.md). Schalte es nur ein, während tatsächlich ein Anmelde-Prompt auf dem Bildschirm ist (MCP-Server-OAuth, Re-Auth), und schalte es dann wieder aus. Standardmäßig aus
--deny-clipboardDen Agenten daran hindern, die macOS-Zwischenablage zu lesen oder zu schreiben (pbpaste/pbcopy), indem der Mach-Service com.apple.pasteboard verweigert wird. Jeder andere Mach-Service (Keychain, DNS, Security-Framework) ist unberührt. Standardmäßig an — dieses Flag wiederholt den Standard
--allow-clipboardDem Agenten die macOS-Zwischenablage zurückgeben, die cplt standardmäßig verweigert. Entspricht sandbox.deny_clipboard = false
--use-bubblewrapNur Linux. Die bubblewrap-Namespace-Schicht (PID-, Mount-, IPC-, UTS-, cgroup-, User-Namespaces plus ein privates /tmp) zusätzlich zu Landlock und seccomp erfordern. Bricht mit Fehler ab, wenn bwrap fehlt. Wird automatisch erkannt, wenn keines der beiden Flags angegeben ist
--no-bubblewrapNur Linux. Niemals bubblewrap verwenden, auch wenn installiert. Fällt auf Landlock und seccomp zurück. Verwende es, wenn bwrap ein bestimmtes Tool bricht
RuntimeHome-VerzeichnisseEnv-Variablen / PräfixeEntdeckung
Node.js.nvm, .local/share/fnm, .local/binNODE_*, NPM_*, NVM_*, FNM_*node
Rust.cargo, .rustupCARGO_HOME, RUSTUP_HOMEcargo
Gogo/bin, go/pkgGOPATH, GOROOT, GOCACHE, etc.go
Java/Kotlin (JVM).sdkman, .jenv, .gradle, .m2JAVA_HOME, JAVA_TOOL_OPTIONS, GRADLE_*, MAVEN_*, SDKMAN_*, JENV_*java, gradle
Kotlin Native.konankeinekeine
Python.pyenvVIRTUAL_ENV, PYTHONPATH, PYENV_ROOT, PYENV_*python3
Yarn Berry.yarnYARN_* (Härtung überschreibt YARN_ENABLE_SCRIPTS)yarn
pnpmLibrary/pnpm, .local/share/pnpmPNPM_HOMEpnpm
CorepackkeineCOREPACK_*keine
mise.local/share/mise, .miseMISE_*mise
FlagWas es tut
--doctorVeraltet. Verwende stattdessen das Subkommando cplt doctor
--print-profileDas generierte Sandbox-Profil (SBPL) ausgeben und beenden
--show-denialsmacOS-Sandbox-Denial-Logs in Echtzeit streamen
--no-validateDie Startprüfung überspringen, die verifiziert, dass die Sandbox-Beschränkungen aktiv sind
-y, --yesDen interaktiven Bestätigungs-Prompt überspringen. Die Konfigurationszusammenfassung wird weiterhin ausgegeben, zur Auditierbarkeit. Erforderlich, wenn stdin kein TTY ist, also benötigen CI und Skripte es
-q, --quietDas Startbanner und nicht wesentliche Nachrichten unterdrücken. Fehler und Warnungen werden weiterhin ausgegeben. Auch sandbox.quiet = true in der Config
--no-quietsandbox.quiet = true überschreiben und die Startzusammenfassung trotzdem anzeigen
--no-auditDen Post-Session-Änderungsbericht überspringen. cplt vergleicht normalerweise den Arbeitsbaum mit einem Baseline-Commit, der vor dem Lauf festgelegt wurde, und listet auf, was die Sitzung berührt hat, wobei sensible Pfade markiert werden. -q unterdrückt ihn ebenfalls
--init-configEine Starter-Config-Datei unter ~/.config/cplt/config.toml erstellen und beenden
FlagWas es tut
--resume[=SESSION]Eine vorherige Sitzung fortsetzen. Bloßes --resume wählt interaktiv, --resume=NAME wählt nach Name oder ID
--continueDie jüngste Sitzung im aktuellen Verzeichnis fortsetzen
--remoteFernsteuerung aktivieren, sodass du die Sitzung von GitHub.com oder mobil überwachen und steuern kannst
--name SESSIONDie Sitzung benennen, damit --resume=NAME sie später finden kann
cplt-FlagCopilotOpenCodeAntigravity (agy)Claude Code
--continue--continue--continue--continue--continue
--resume--resume--continue¹--continue¹--resume
--resume=ID--resume=ID--session ID--conversation ID--resume ID
--remote--remoteignoriertignoriertignoriert
--name NAME--name NAMEignoriertignoriertignoriert
GOOGLE_API_KEY
GEMINI_API_KEY
--pass-env
  • Keine Standard-Domains: goose kontaktierte in einer --observe-domains-Aufzeichnung keinen eigenen Host, daher ist seine integrierte Allowlist nur die gemeinsame Paket-Registry-Basis. Fügen Sie die Domain Ihres Providers über allowed_domains hinzu, bevor Sie --default-allowlist aktivieren
  • Keychain wird gewährt, und Sie können sie vermeiden: goose speichert Provider-Geheimnisse standardmäßig im macOS-Login-Keychain, daher gewährt cplt es — aber diese Gewährung ist breiter als goose's eigener Eintrag (#242). GOOSE_DISABLE_KEYRING=1 lässt goose stattdessen eine secrets.yaml in seinem Konfigurationsverzeichnis verwenden, und die Übergabe des Schlüssels mit --pass-env vermeidet gespeicherte Geheimnisse vollständig. Unter Linux verwendet goose den D-Bus Secret Service, den die Keychain-Gewährung nicht betrifft
  • Konfigurationsverzeichnis ist schreibgeschützt: ~/.config/goose/config.yaml deklariert extensions:-Einträge, deren cmd goose bei jedem Sitzungsstart startet, sodass ein beschreibbares Konfigurationsverzeichnis ein Host-Persistenz-Vektor ist. Normale Sitzungen schreiben es nicht; /mode-Änderungen und persistierte Tool-Berechtigungen überleben einen sandboxten Lauf nicht. Neukonfiguration mit goose configure außerhalb von cplt
  • goose's Daten- (~/.local/share/goose/) und State-Verzeichnisse (~/.local/state/goose/) sind beschreibbar, mit verweigerter Ausführung. goose verwendet diese XDG-Pfade auch unter macOS und respektiert dort die XDG_*-Überschreibungen
  • --continue und bloßes --resume werden auf goose session --resume abgebildet; --resume=ID auf goose session --resume --session-id ID; --name X auf goose session --name X. Dies sind Subcommand-Flags, daher injiziert cplt das session-Subcommand mit ihnen. --remote wird ignoriert (kein goose-Äquivalent)
  • SchichtDurchsetzungUmgehbar?Was sie schützt
    1. Kernel-SandboxmacOS Seatbelt / Linux Landlock+seccomp❌ NeinDateizugriff, exec, Netzwerkports
    2. Netzwerk-ProxyCONNECT-Proxy, Domain-Filterung❌ Nein (innerhalb der Sandbox)Ausgehende Verbindungen, Exfiltration
    3. Command-GuardPATH-basierte Wrapper-Skripte⚠️ Weiche BarrierePushes, Merges, Releases, API-Schreibzugriffe
    git
    bwrap
    sandbox-exec
    mise
    gh
    PATH
    warnt beim Start
  • cplt doctor: Seine --version-Probes führen jedes Agent-Binary aus, das es auf deinem PATH findet, im Parent, sodass ein platziertes dort ausgeführt wird – dieselbe Exposition durch entdeckte Pfade wie beim Start oben, weshalb doctor ein Bericht und keine Grenze ist. Seine gh-Prüfung wird aus den vertrauenswürdigen Verzeichnissen aufgelöst, und sein Auslesen der Kernel-Version startet überhaupt nichts
  • Datenexfiltration an unautorisierte Domains: proxy-blockiert
  • Versehentliche Pushes auf main und PR-Merges ohne Review: guard-blockiert
  • CommandAction
    gh pr merge, gh repo delete, gh release create🔒 Blocked
    git push origin main, git push --force🔒 Blocked
    gh api (write to other repos)🔒 Scope-checked
    gh pr list, gh issue list, git commit✅ Allowed
    git push origin feature-branch✅ Allowed with protect_default_branch_only
    ImpactFix
    .env files blockedcplt config set sandbox.allow_env_files true
    npm postinstall hooks blockedcplt config set sandbox.allow_lifecycle_scripts true
    go test / mise run blocked (temp exec)The scratch dir is on by default. If you still need it, cplt config set sandbox.allow_tmp_exec true
    Localhost connections blockedcplt config set allow.localhost 3000, or cplt config set sandbox.allow_localhost_any true
    Docker blockedcplt config set sandbox.allow_docker true ⚠️
    SSH blockedUse HTTPS remotes instead
    GPG signing disabledcplt config set sandbox.allow_gpg_signing true
    JVM MockK/Mockito failscplt config set sandbox.allow_jvm_attach true
    dotnet build MSBuild worker nodes blockedcplt config set sandbox.allow_msbuild true
    Private registry creds blockedcplt config set allow.read "~/.m2/settings.xml"
    Internal Maven/Nexus repo unreachable (Gradle/Maven)cplt config set proxy.allow_private_domains "intern.example.com". An IP-literal repository URL cannot be allowed — give the host a DNS name; see below
    Playwright Chromium won't launchAllow cache exec, then disable Chromium's nested sandbox; see below