Abgespalten von #30, das die macOS-Hälfte trägt und mit #79 geschlossen wurde. Die Linux-Hälfte war dort nie belegt: Es stand keine Linux-Maschine zur Verfügung, auf der bubblewrap zu prüfen gewesen wäre, und ein Feature auf Verdacht zu bauen war ausdrücklich nicht der Zuschnitt.
Was schon da ist
Die Naht ist gelegt und die schwierigen Entscheidungen sind auf macOS getroffen und gemessen. Eine Linux-Strategie ist eine Klasse, kein Umbau:
Sandbox::Strategy (src/smith/sandbox.cr:117) — name, active?, wrap(command) : {String, Array(String)}, sandboxed?, describe. MacOS und Off implementieren sie; Sandbox.build wählt aus.
Policy trägt bereits alles, was eine zweite Umsetzung braucht: write, write_defaults, deny_read, network (allow/deny/ports), unsandboxed, auto_approve, required.
Sandbox.absolute löst ~ und Symlinks auf — beides sind stille Fehlerquellen und auf Linux nicht anders.
BashJobs#start ist der einzige Ort, an dem ein Shell-Prozess entsteht; das Wrapping sitzt dort und deckt Hintergrund-Jobs mit ab.
SandboxApprover, smith sandbox, die Warnung beim Start und required = true sind plattformunabhängig und funktionieren, sobald active? true liefert.
Zu schreiben ist also im Kern: Sandbox::Linux < Strategy plus ein Zweig in Sandbox.build.
Zu klären, bevor Code entsteht — am besten als Spike wie #65
- bubblewrap oder Landlock?
bwrap ist ein Prozess-Wrapper und passt exakt auf wrap, braucht aber unprivilegierte User-Namespaces, die manche Distributionen abschalten (und Debian/Ubuntu über AppArmor-Profile einschränken). Landlock ist im Kernel (ab 5.13, mehrere ABI-Versionen mit unterschiedlichem Funktionsumfang), braucht keine Namespaces — aber Syscalls statt eines Binaries, also Bindings. Die Antwort entscheidet, ob das ein Wrapper oder eine Bibliotheksanbindung wird.
- Wie wird auf „nicht verfügbar" erkannt? Auf macOS reicht
File.exists?. Auf Linux ist bwrap vorhanden und kann trotzdem scheitern, wenn Namespaces gesperrt sind. Der Test muss also ein echter Probelauf sein, wie es die Specs für die Schachtelung schon tun (SANDBOX_EXEC_USABLE, spec/smith/sandbox_spec.cr:29) — sonst meldet smith Schutz, den es nicht hat.
- Die Schreib-Allowlist ist eine andere. Die macOS-Voreinstellungen (
~/Library/Caches, $TMPDIR als /var/folders/…) sind dort sinnlos; Linux braucht $XDG_CACHE_HOME, ~/.cache, /tmp, ~/.local/{share,state}, ~/.npm, ~/.cargo. Der Lackmustest ist derselbe: make test innerhalb der Sandbox. Auf macOS hat genau das zwei Verzeichnisse aufgedeckt, ohne die die Toolchain obskur scheitert.
- Netzwerk.
bwrap --unshare-net ist ein ganzes Netz-Namespace, also alles oder nichts — die Portebene, die SBPL kann, gibt es dort nicht. Entweder network = "ports:…" ist auf Linux nicht unterstützt und sagt das, oder es braucht mehr Maschinerie (eigenes Namespace plus Filter). Ersteres wäre konsistent damit, wie die Hostnamen-Grenze auf macOS behandelt wird.
- Lesen. macOS erlaubt Lesen pauschal und nimmt
deny_read gezielt heraus. Mit bwrap ist es umgekehrt: Was nicht gebindet ist, ist nicht da. Ein --ro-bind / / mit gezielten --tmpfs-Überdeckungen für deny_read kommt der macOS-Semantik am nächsten — zu prüfen, ob das trägt.
- Was passiert mit
/proc, /dev und dem TTY? bwrap braucht --dev, --proc und meist --die-with-parent; ohne das Letzte überlebt ein Hintergrund-Job seinen Aufrufer. smith bringt Jobs beim Sessionende selbst um (BashJobs#shutdown_all), aber die Interaktion gehört geprüft.
Akzeptanzkriterien
Nicht-Ziele
Abgespalten von #30, das die macOS-Hälfte trägt und mit #79 geschlossen wurde. Die Linux-Hälfte war dort nie belegt: Es stand keine Linux-Maschine zur Verfügung, auf der
bubblewrapzu prüfen gewesen wäre, und ein Feature auf Verdacht zu bauen war ausdrücklich nicht der Zuschnitt.Was schon da ist
Die Naht ist gelegt und die schwierigen Entscheidungen sind auf macOS getroffen und gemessen. Eine Linux-Strategie ist eine Klasse, kein Umbau:
Sandbox::Strategy(src/smith/sandbox.cr:117) —name,active?,wrap(command) : {String, Array(String)},sandboxed?,describe.MacOSundOffimplementieren sie;Sandbox.buildwählt aus.Policyträgt bereits alles, was eine zweite Umsetzung braucht:write,write_defaults,deny_read,network(allow/deny/ports),unsandboxed,auto_approve,required.Sandbox.absolutelöst~und Symlinks auf — beides sind stille Fehlerquellen und auf Linux nicht anders.BashJobs#startist der einzige Ort, an dem ein Shell-Prozess entsteht; das Wrapping sitzt dort und deckt Hintergrund-Jobs mit ab.SandboxApprover,smith sandbox, die Warnung beim Start undrequired = truesind plattformunabhängig und funktionieren, sobaldactive?true liefert.Zu schreiben ist also im Kern:
Sandbox::Linux < Strategyplus ein Zweig inSandbox.build.Zu klären, bevor Code entsteht — am besten als Spike wie #65
bwrapist ein Prozess-Wrapper und passt exakt aufwrap, braucht aber unprivilegierte User-Namespaces, die manche Distributionen abschalten (und Debian/Ubuntu über AppArmor-Profile einschränken). Landlock ist im Kernel (ab 5.13, mehrere ABI-Versionen mit unterschiedlichem Funktionsumfang), braucht keine Namespaces — aber Syscalls statt eines Binaries, also Bindings. Die Antwort entscheidet, ob das ein Wrapper oder eine Bibliotheksanbindung wird.File.exists?. Auf Linux istbwrapvorhanden und kann trotzdem scheitern, wenn Namespaces gesperrt sind. Der Test muss also ein echter Probelauf sein, wie es die Specs für die Schachtelung schon tun (SANDBOX_EXEC_USABLE,spec/smith/sandbox_spec.cr:29) — sonst meldet smith Schutz, den es nicht hat.~/Library/Caches,$TMPDIRals/var/folders/…) sind dort sinnlos; Linux braucht$XDG_CACHE_HOME,~/.cache,/tmp,~/.local/{share,state},~/.npm,~/.cargo. Der Lackmustest ist derselbe:make testinnerhalb der Sandbox. Auf macOS hat genau das zwei Verzeichnisse aufgedeckt, ohne die die Toolchain obskur scheitert.bwrap --unshare-netist ein ganzes Netz-Namespace, also alles oder nichts — die Portebene, die SBPL kann, gibt es dort nicht. Entwedernetwork = "ports:…"ist auf Linux nicht unterstützt und sagt das, oder es braucht mehr Maschinerie (eigenes Namespace plus Filter). Ersteres wäre konsistent damit, wie die Hostnamen-Grenze auf macOS behandelt wird.deny_readgezielt heraus. Mitbwrapist es umgekehrt: Was nicht gebindet ist, ist nicht da. Ein--ro-bind / /mit gezielten--tmpfs-Überdeckungen fürdeny_readkommt der macOS-Semantik am nächsten — zu prüfen, ob das trägt./proc,/devund dem TTY?bwrapbraucht--dev,--procund meist--die-with-parent; ohne das Letzte überlebt ein Hintergrund-Job seinen Aufrufer. smith bringt Jobs beim Sessionende selbst um (BashJobs#shutdown_all), aber die Interaktion gehört geprüft.Akzeptanzkriterien
Sandbox::LinuximplementiertStrategy;Sandbox.buildwählt sie auf Linuxmake testinnerhalb der Sandbox belegtsmith sandboxzeigt die Linux-Strategie so an, dass erkennbar ist, was tatsächlich greiftNicht-Ziele
container, Docker, Lima) als Ausführungsmodell