Skip to content

Reconcile the threat model and security docs with the real boundary - #271

Merged
seanwevans merged 1 commit into
mainfrom
claude/threat-model-reconciliation
Jul 20, 2026
Merged

seanwevans merged 1 commit into
mainfrom
claude/threat-model-reconciliation

Conversation

@seanwevans

Copy link
Copy Markdown
Owner

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:

  1. docs/threat-model.md (the normative doc) said "Hostile Python code: DEFENDED" with no qualification. That was false for the default backend="subinterpreter", where a object.__subclasses__() walk reaches the real os/open.
  2. SECURITY.md claimed 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/pickle removed) presented as shipped fact.

What

  • 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. The boundary summary is rewritten around the two backends; assumptions now lead with "untrusted code runs under backend="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

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
@seanwevans
seanwevans merged commit 77d54a1 into main Jul 20, 2026
18 of 19 checks passed
@seanwevans
seanwevans deleted the claude/threat-model-reconciliation branch July 21, 2026 18:09
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants