Repository navigation
Reconcile the threat model and security docs with the real boundary - #271
Merged
Merged
Conversation
The threat model claimed 'hostile Python: DEFENDED' without qualification, and SECURITY.md claimed guarantees the code did not provide (e.g. 'guest cannot execute syscalls outside the eBPF allow-list', a CPython-hardening build that is not shipped). Now that a real backend='process' boundary exists (separate process + seccomp + Landlock + coarse eBPF deny-mask), make the docs match reality. - docs/threat-model.md: the hostile-Python answer is now backend-conditional -- NOT DEFENDED for subinterpreter, DEFENDED IN DEPTH (conditional on kernel features) for process. Replaces the 'single-process system' framing with a backend-aware boundary summary; updates assumptions and adds a change-control history entry. - SECURITY.md: rewrites the authoritative boundary statement and layered defenses around the process backend's actual stack; corrects the false eBPF 'allow-list' claim (it is a coarse deny-mask); moves the no-GIL build, allocator arenas, CPython CFI/canary flags, path-aware eBPF matching, and reproducible-build/signing claims to an explicit roadmap section; softens supported-platforms and disclosure to what is true. - README.md: the security-model section leads with 'the boundary is the backend' and lists the process backend's real confinement stack. - supervisor.py: module docstring no longer says isolation 'is not implemented here'; points at the backend distinction. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01DDSofWX5HwawsrwbN2nSXR
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Why
This is the capstone of the boundary series (#267–#270). Those PRs built a real
backend="process"boundary; this one makes the security docs tell the truth about it — and stop claiming things the code never did.The audit that started this work found two documentation problems:
docs/threat-model.md(the normative doc) said "Hostile Python code: DEFENDED" with no qualification. That was false for the defaultbackend="subinterpreter", where aobject.__subclasses__()walk reaches the realos/open.SECURITY.mdclaimed guarantees the code didn't provide: "guest cannot execute syscalls outside the eBPF allow-list" (it's a coarse deny-mask), and a whole CPython-hardening section (no-GIL build, per-interpreter allocator arenas,-fstack-protector-strong/-fsanitize=cfi,ctypes/cffi/pickleremoved) presented as shipped fact.What
docs/threat-model.md— the hostile-Python answer is now backend-conditional: NOT DEFENDED forsubinterpreter, DEFENDED IN DEPTH (conditional on kernel features) forprocess. The boundary summary is rewritten around the two backends; assumptions now lead with "untrusted code runs underbackend="process""; a change-control history entry records the shift.SECURITY.md— the authoritative boundary statement and layered-defense sections are rewritten around the process backend's actual stack (process isolation → seccomp deny-list → Landlock → coarse eBPF deny-mask → rlimit/cgroup). The false eBPF "allow-list" claim is corrected. The no-GIL build, allocator arenas, CPython CFI/canary flags, path-aware eBPF matching, and reproducible-build/signing claims are moved to an explicit roadmap section. Supported-platforms and disclosure are softened to what's true.README.md— the security-model section now leads with "the boundary is the backend" and lists the process backend's real confinement layers.supervisor.py— the module docstring no longer says isolation "is not implemented here"; it points at the backend distinction.Deliberately honest, not aspirational
Every kernel layer is described as best-effort, degrades where unavailable, fails closed in hardened mode — because that's how the code behaves. The eBPF layer is called out as coarse (whole-class denial), with per-path FS delegated to Landlock and per-destination network to the broker. Nothing here claims a hardware-VM boundary.
Testing
Docs plus a one-line docstring. Full suite: 448 passed, 4 environment-gated skips; pre-commit hooks pass on the changed source file. No test asserts on the doc text that changed.
🤖 Generated with Claude Code
https://claude.ai/code/session_01DDSofWX5HwawsrwbN2nSXR
Generated by Claude Code