← ScopeShelf

Terminal, iTerm und die gesandboxte Shell

Hilfe · Stand 12. September 2026 · Read in English

Terminal-Apps sind der eine Fall, in dem ScopeShelf nicht die App sandboxt, sondern die Shell darin. Diese Seite erklärt, warum das so ist, geht jede Einstellung durch und listet die Fehlermeldungen auf, die dir begegnen können, samt Abhilfe.

Auf dieser Seite
  1. Warum ein Terminal nicht in der Sandbox laufen kann
  2. Was ScopeShelf stattdessen macht
  3. Terminal-Launcher in der App anlegen
  4. Der Abschnitt „Shell“, Einstellung für Einstellung
  5. Die gesandboxte Shell starten
  6. Was drinnen geht und was nicht
  7. Dasselbe auf der Kommandozeile
  8. Was die Sandbox durchsetzt und was nicht
  9. Fehlermeldungen und was zu tun ist

1. Warum ein Terminal nicht in der Sandbox laufen kann

Terminal.app, iTerm2, Alacritty, kitty und Co. starten deine Shell nicht direkt. Sie gehen über /usr/bin/login, ein kleines Programm mit gesetztem setuid-Bit. macOS weigert sich, setuid-Programme in einer Seatbelt-Sandbox zu starten, egal was im Profil steht. Das kannst du selbst nachprüfen:

$ sandbox-exec -p '(version 1)(allow default)' /usr/bin/login -fpl $USER /bin/echo hi
sandbox-exec: execvp() of '/usr/bin/login' failed: Operation not permitted

Ein Terminal, das in der Sandbox startet, öffnet also sein Fenster, versucht eine Session aufzumachen und scheitert. Es sieht aus, als wäre die App kaputt. Daran lässt sich in ScopeShelf nichts einstellen; es ist eine Regel des Betriebssystems.

ScopeShelf erkennt solche Apps beim Auswählen. Auf der Karte steht Terminal — die Sandbox gilt für die Shell, die du hier startest, der Start-Button heißt Shell starten, und es gibt für sie weder „Beenden“ noch „Geschützt neu starten“: das würde dein Terminal mit allen offenen Shells schließen, für einen Start, der nicht funktionieren kann.

2. Was ScopeShelf stattdessen macht

Dein Terminal läuft ganz normal, ohne Sandbox. Darin startet ScopeShelf eine gesandboxte Shell: eine zsh (oder welche Shell du benutzt), eingepackt in das Seatbelt-Profil des Launchers. Alles, was du aus dieser Shell startest, erbt die Sandbox: Claude Code, Codex, npm, Build-Skripte, git. Die Shell sieht deinen Projektordner und die freigegebenen Ordner, und sonst nichts aus deinem Benutzerordner.

Es gelten dieselben drei Zonen wie bei jedem Launcher:

Alles außerhalb deines Benutzerordners (/usr, /opt/homebrew, /Applications, /tmp) bleibt erreichbar, wie bei jedem ScopeShelf-Launcher.

3. Terminal-Launcher in der App anlegen

  1. Neuer Launcher. Unter Schritt 1 klickst du in der Zeile Oder eine installierte App direkt auf Terminal oder iTerm. Den Datei-Dialog brauchst du nicht. Wenn du ihn trotzdem nimmst: Terminal.app liegt unter /System/Applications/Utilities/; der Dialog zeigt versteckte Ordner, du kannst also dorthin navigieren oder Cmd+Shift+G drücken und den Pfad einfügen.
  2. Name. Der daraus abgeleitete Kurzname ist das, was du später auf der Kommandozeile tippst (scopeshelf shell mein-name).
  3. Freigaben. Die Vorlagen für Terminal und iTerm geben von sich aus nichts frei. Nach dem Projektordner fragt ScopeShelf beim ersten „Shell starten“ (siehe unten), den musst du hier also nicht eintragen. Trag hier ein, was die Tools drinnen über das Projekt hinaus brauchen. Typisch für Claude Code mit dem nativen Installer:
    # Schreibbar
    ~/.claude                     # Einstellungen, Sitzungen
    ~/.local/share/claude         # die Programmdateien
    # Dateien (als einzelne Dateien freigegeben)
    ~/.claude.json
    ~/.gitconfig
    Referenzmaterial, das die KI nur lesen soll, kommt als nur lesbar dazu.
  4. Abschnitt „Shell“ (Schritt 4). Hier wird die Shell selbst eingestellt. Alle Listen sind auf deinem Mac gemessen, nicht geraten. Die Einzelheiten stehen im nächsten Abschnitt.
  5. Sichern.

4. Der Abschnitt „Shell“, Einstellung für Einstellung

Du findest ihn unter Launcher bearbeiten → Schritt 4, Shell. Dieselben Einstellungen gibt es noch einmal unter Einstellungen → Shell als Vorgabe für alle Launcher; ein Launcher überschreibt nur, was du in ihm setzt.

EinstellungWas sie bewirkt
ProgrammWelche Shell läuft. Vorgabe ist deine Login-Shell ($SHELL). Die Liste kommt aus /etc/shells. ScopeShelf kennt zsh, bash, fish, nushell, ksh, sh, tcsh, elvish, xonsh und PowerShell (pwsh). Andere Shells starten auch, aber ScopeShelf kennt ihre Startdateien nicht.
Login-ShellStartet die Shell mit -l, sodass sie ihre Profil-Dateien liest (.zprofile), wie ein frisches Terminalfenster. Standardmäßig an.
ArbeitsordnerDer Arbeitsbereich der Shell: hier startet sie und hier darf sie schreiben, auch wenn der Ordner nicht in den Freigaben oben steht. Lässt du ihn leer, fragt die App beim ersten „Shell starten“ nach einem Ordner und merkt ihn sich. Auf der Kommandozeile heißt ein leerer Arbeitsordner „starte dort, wo ich den Befehl aufgerufen habe“ (siehe Abschnitt 7). Der Benutzerordner selbst wird als Arbeitsordner abgelehnt, weil eine Sandbox, die deinen ganzen Benutzerordner beschreiben darf, nichts schützt.
StartdateienDie Startdateien der gewählten Shell, die es auf deinem Mac wirklich gibt (~/.zshenv, ~/.zprofile, ~/.zshrc bei zsh). Hak an, welche die Shell lesen darf. Ohne sie bekommst du eine nackte Shell: kein Prompt-Thema, keine Aliase, keine PATH-Ergänzungen.
Dateien, die deine Startdateien nachladenScopeShelf liest die angehakten Startdateien und listet auf, was sie selbst per source laden, zum Beispiel ~/.cargo/env oder ~/.nvm/nvm.sh. Hak die auch an, sonst meldet die Shell bei jedem Start operation not permitted für diese Zeile.
Programm-OrdnerOrdner aus deinem $PATH, die im Benutzerordner liegen: ~/.local/bin, ~/.bun/bin, ~/.cargo/bin, die node-Ordner von nvm und so weiter. Alles im Benutzerordner ist in der Sandbox unsichtbar, solange es nicht freigegeben ist; ein dort installiertes Tool verschwindet also ohne Häkchen. Ein bin-Ordner bringt seine Nachbarn lib, libexec und share mit, sonst findet npm zwar node, aber nicht seine Module.
Eigene Konfiguration und History im SandkastenDie Shell bekommt ein eigenes Konfigurationsverzeichnis (ZDOTDIR bei zsh, XDG_CONFIG_HOME bei fish und nushell) unter ~/Library/Application Support/ScopeShelf/shells/<kurzname>. ScopeShelf legt dort kleine Brückendateien ab, die deine echten Startdateien laden, und die History der Shell landet ebenfalls dort. Deine eigene ~/.zsh_history fasst eine gesandboxte Sitzung nie an. Shells ohne verschiebbares Konfigurationsverzeichnis (bash, sh) laufen ohne eigene History.

5. Die gesandboxte Shell starten

Aus der App

Klick auf Shell starten, auf der Launcher-Karte, in der Detailansicht oder im Menü der Menüleiste. Dann passiert zweierlei:

  1. Dialog „Arbeitsordner“ (nur beim ersten Mal, wenn kein Arbeitsordner eingestellt ist): wähl den Projektordner, in dem die Shell arbeiten soll. ScopeShelf speichert ihn im Launcher. Den Benutzerordner und gesperrte Ordner wie ~/.ssh lehnt der Dialog ab.
  2. Dein Terminal kommt nach vorn, mit einem neuen Fenster. ScopeShelf tippt den Shell-Befehl hinein. iTerm und Terminal.app werden direkt gesteuert; jedes andere Terminal bekommt ein Fenster in Terminal.app.

Beim ersten Mal fragt macOS, ob ScopeShelf dein Terminal steuern darf (Systemeinstellungen → Datenschutz & Sicherheit → Automation). Erlaub es, sonst geht nichts auf.

Ein Dock-Starter (in der Detailansicht anzulegen) macht dasselbe, inklusive Ordner-Dialog.

Was der Banner dir sagt

Gesandboxte Shell (tttt, zsh) — beenden mit `exit`, Details mit `scopeshelf scope`.
Schreibbar: ~/repos/mein-projekt  ~/.claude  ~/.local/share/claude
Nur lesbar: ~/.zshenv  ~/.zshrc  ~/.local/bin
Arbeitsordner ~/repos/mein-projekt ist fuer diese Shell schreibbar freigegeben (zusaetzlich zum Profil).

Nach dem Banner bist du in deinem normalen Prompt, im Arbeitsordner. Starte Claude Code, Codex oder was du willst. exit beendet die gesandboxte Shell und bringt dich zurück in die ungeschützte Shell dieses Fensters.

6. Was drinnen geht und was nicht

7. Dasselbe auf der Kommandozeile

Installier den Befehl einmal unter Einstellungen → Kommandozeilen-Werkzeug. Das legt einen Link auf das scopeshelf-Programm aus der App in ~/.local/bin (oder /usr/local/bin, falls dir der Ordner gehört). Danach in jedem Terminalfenster:

scopeshelf shell mein-name                      # Shell im Profil des Launchers, in diesem Fenster
scopeshelf shell mein-name --cd ~/repos/anderes # anderes Projekt, nur für diesen Start
scopeshelf shell mein-name --shell /bin/bash    # andere Shell, nur für diesen Start
scopeshelf shell mein-name --no-network         # ausgehendes Netz für diesen Start sperren
scopeshelf shell mein-name -e FOO=bar           # Umgebungsvariable setzen
scopeshelf shell --app /Applications/iTerm.app ~/repos/x ~/docs:ro
                                                # ad hoc, ohne gespeicherten Launcher: x schreibbar, docs nur lesbar
scopeshelf dry mein-name                        # Profil anzeigen, ohne etwas zu starten
scopeshelf scope                                # in einer gesandboxten Shell: was gilt hier?

Regeln für den Startordner auf der Kommandozeile:

Für ein Projekt im Team legst du eine Datei .scopeshelf ins Repository und rufst in dem Ordner einfach scopeshelf shell auf:

{
  "launcher": "mein-name",
  "shell": { "workingDirectory": "." }
}

Die Projekt-Einstellungen aus der Datei liegen über denen des Launchers; ein relativer Arbeitsordner wird gegen das Projekt aufgelöst.

8. Was die Sandbox durchsetzt und was nicht

Jede Aussage unten prüft ein Skript im Repository (Scripts/check-sandbox-escapes.sh), das jeden Ausbruchsweg aus einer gesandboxten Shell heraus wirklich versucht, mit Stand 1.1.2 sind es 21 Versuche; die vollständige Tabelle, was wo durchgesetzt wird, steht in docs/sandbox-enforcement-map.md. Regeln mit dem Vermerk Profil stecken in jeder ScopeShelf-Sandbox und lassen sich von innen nicht abschalten.

Durchgesetzt vom Profil oder vom Kernel

Durchgesetzt von macOS, nicht vom Profil

Gar nicht geschützt

9. Fehlermeldungen und was zu tun ist

Du siehstBedeutung und Abhilfe
/Users/du/.zshenv:.:1: operation not permitted: /Users/du/.cargo/envEine Startdatei lädt eine weitere Datei, die nicht freigegeben ist. Launcher bearbeiten → Schritt 4, Shell → unter Dateien, die deine Startdateien nachladen anhaken. Der Banner nennt die Datei, bevor die Shell sich beschwert.
… kann kein Arbeitsordner sein: eine Freigabe auf den Benutzerordner (oder darueber) wuerde nichts mehr sperrenDu hast ~ oder einen Ordner darüber gewählt. Wähl einen Projektordner.
… liegt im gesperrten Pfad …Der Arbeitsordner liegt unter ~/.ssh, ~/.aws oder einem anderen gesperrten Ordner. Sperren gewinnen immer gegen Freigaben.
… ist im Profil nicht sichtbar, und es ist kein Arbeitsordner eingestelltDu hast scopeshelf shell in einem Ordner außerhalb der Freigaben aufgerufen. Entweder per cd in einen freigegebenen Ordner wechseln, oder --cd <ordner> mitgeben, dann wird dieser Ordner der Arbeitsbereich.
Arbeitsordner … ist im Profil nur lesbarDer Ordner steht in den Nur-lesen-Freigaben, die Shell kann dort also nicht schreiben. Ändere die Freigabe im Launcher, wenn sie es soll.
zsh: command not found: scopeshelfDas Kommandozeilen-Werkzeug ist nicht installiert oder sein Ordner steht nicht in deinem PATH. Einstellungen → Kommandozeilen-Werkzeug zeigt die genaue Zeile zum Ergänzen. In einer gesandboxten Shell ist der Befehl immer da; das betrifft nur deine normale Shell.
command not found: node (oder claude, bun, cargo …) in der ShellDas Tool liegt in einem Ordner in deinem Benutzerordner, der nicht freigegeben ist. Launcher bearbeiten → Schritt 4, Shell → unter Programm-Ordner anhaken.
Nackter Prompt, keine Aliase, kein ThemaDie Startdateien sind nicht angehakt, oder Login-Shell ist aus. ~/.zshrc und Co. anhaken.
„Shell starten“ tut nichts, oder Not authorized to send Apple eventsScopeShelf darf dein Terminal noch nicht steuern. Systemeinstellungen → Datenschutz & Sicherheit → Automation → ScopeShelf → iTerm / Terminal erlauben.
Shell ist setuid und kann in der Sandbox nicht startenDas gewählte Shell-Programm ist selbst setuid. Wähl unter „Programm“ ein anderes.

Fehlt etwas auf dieser Seite? Sag es uns, dann ergänzen wir es.