Hook Sandbox: Landlock, Network Namespace, Deny-List seccomp
nestr advanced 6 min read
Status: designed, not shipped to customers. The sandbox is on engine main and runs in the CLI, which has no install path yet (nestr.tools, read 2026-10-25). The seccomp filter is a deny-list under a signed I-2 exception until M13.1 or 2027-01-31.
ELI5
Installing never runs package code. If a package has a hook you choose to run, it runs in a box: it can only touch its own folder, gets its own private network, and a filter blocks a list of dangerous system calls. That list is a blocklist for now, not an allowlist, and nestr says so publicly.
Technical Deep Dive
Source: nestr-tools/engine internal/pellets/sandbox/landlock_linux.go:1-40, fsview_linux.go:5-32, netns_linux.go, egress/egress.go:27, seccomp_linux.go:35-36,43,74-77,104,162,173,286-306, main.go:36-47 @e9180e4; nestr-tools docs/decisions/2026-10-20-i2-seccomp-deny-list-until-m13.md (signed flight@arno.host 2026-10-20), docs/decisions/2026-10-12-i2-hook-sandbox-network-seccomp-gaps.md @b8f0585; read 2026-10-25.
flowchart LR HOOK["consented hook"] --> TR["nestr re-execs itself as a trampoline"] TR --> NS["new namespaces incl CLONE_NEWNET"] NS --> LL["Landlock: paths limited to the pellet dir"] NS --> FV["fsview: minimal filesystem view, no proc, dev or tmp"] LL --> SC["seccomp-bpf: arch check, then deny-list"] SC --> EX["exec the hook, empty capability set"]| Layer | What it does | Spec |
|---|---|---|
| Network namespace | every hook gets its own netns whether or not network is granted; egress is controlled per hook | PEL-SBX-012 (fixed 2026-10-12) |
| Landlock (kernel 5.13+) | irrevocable path allowlist: nothing outside the pellet directory; unavailable Landlock is reported, not ignored | PEL-SBX-001 |
| fsview | a constructed filesystem view, because Landlock does not cover pathname sockets | PEL-SBX-001 (sockets, fixed) |
| seccomp-bpf | kills any non-x86_64 arch, then blocks a list of syscalls: clone without CLONE_NEW* flags, clone3, the new mount API, io_uring_setup and others; final instruction is default-allow | PEL-SBX-002 (not met) |
The deny-list exception
timeline title PEL-SBX-002 default-deny seccomp 2026-10-12 : First I-2 record accepts the gap until Phase 12 close 2026-10-20 : New I-2 ADR signed, deny-list continues M13.1 or 2027-01-31 : Exception lapses, default-deny with per-hook seccomp_allow requiredThe 2026-10-20 ADR binds conditions for the whole period: no surface may describe the hook filter as default-deny or allowlist-based; support runbook 07 and the public Security page must say it is a deny-list; any bypass found is added within the same phase and logged; the empty capability set and the namespace filter stay. The landing roadmap lists “Default-deny syscall filter” under Now.
Still open per the founder journal: PEL-SBX-001 (identity), meaning hooks do not yet run as a separate unprivileged user; the roadmap lists “Hook identity” under Now.
Key Terms
- trampoline →
nestrre-executing itself withsandbox.TrampolineArgto apply limits, Landlock and seccomp before exec (main.go:36-47). - deny-list → seccomp filter that blocks named syscalls and allows the rest; PEL-SBX-002 requires the opposite.
- seccomp_allow → the planned per-hook manifest field for a default-deny filter.
Q&A
Q: Which three kernel mechanisms contain a hook, and what does each restrict? A: A network namespace (the hook’s own network stack, egress controlled), Landlock (filesystem access limited to the pellet directory) and seccomp-bpf (an architecture check plus a syscall deny-list), with a constructed filesystem view covering what Landlock misses.
Q: Is the seccomp filter default-deny, and what decision governs the answer? A: No. Its final instruction is default-allow. The signed I-2 ADR of 2026-10-20 accepts that until M13.1 or 2027-01-31, on condition that nothing calls it default-deny and the Security page discloses it.
Q: Which CPU architecture does the sandbox support?
A: x86_64 only: the filter kills any process whose syscall arch is not AUDIT_ARCH_X86_64 (seccomp_linux.go:43,77). The landing says “Linux (x86-64)”.
Examples
A reviewer drafts “hooks run under a strict syscall allowlist” for the Security page. That sentence breaks condition 2(a) of the signed exception. The compliant wording: hooks run in their own namespaces with a Landlock path allowlist and a seccomp deny-list, and the default-deny filter PEL-SBX-002 requires is not shipped yet.
neighbors on the map
- Engine Metrics Catalogue: Request, Pellet and Supply-Chain Series writing a Grafana panel against engine series