Reframe the queued uid-split decision into a broader hardening analysis. Audit found the same-uid attack surface (DB readable from srcds, ptrace allowed, RCON stored plaintext) is closable by either uid split or systemd directive composition; the three specs ground that choice in a threat model, survey the defenses, and lay out a self-contained test plan to run on left4.me next. uid-split spec deferred pending results. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
114 lines
5.6 KiB
Markdown
114 lines
5.6 KiB
Markdown
# Session handoff — next: execute hardening test plan
|
|
|
|
Short handoff. Three new hardening specs landed today; the next session
|
|
takes the test plan to `left4.me` and runs it. Decision on
|
|
`2026-05-15-user-uid-split-design.md` is **deferred** until the test
|
|
plan reports back.
|
|
|
|
## What just landed
|
|
|
|
Three coordinated specs at `docs/superpowers/specs/`:
|
|
|
|
- `2026-05-15-hardening-threat-model.md` — assets, attackers (A1-A6),
|
|
trust boundaries (TB1-TB8), attack scenarios (S1-S6), what we
|
|
defend (D1-D7), what we accept losing.
|
|
- `2026-05-15-hardening-defenses-survey.md` — full Linux + systemd
|
|
defense menu, per-defense primitive mapping, candidate composition
|
|
for `left4me-server@.service` + `left4me-web.service`.
|
|
- `2026-05-15-hardening-test-plan.md` — 11 tests runnable cold on
|
|
`left4.me`; drop-in style so they never modify persistent units.
|
|
|
|
## Why the shape changed (from uid-split → hardening)
|
|
|
|
The prior handoff pointed this session at the 1/2/3-user decision in
|
|
`2026-05-15-user-uid-split-design.md`. Audit during this session
|
|
established that the same-uid attack surface (DB readable from srcds,
|
|
ptrace of gunicorn allowed, RCON passwords stored plaintext in DB,
|
|
no `/proc` isolation) is closable by *either* a uid split *or*
|
|
systemd directive composition (`TemporaryFileSystem=` +
|
|
`SystemCallFilter=~@debug` + `PrivateUsers=true` + `ProcSubset=pid`
|
|
+ empty `CapabilityBoundingSet=`). Operator chose to step back: do
|
|
threat-model + research + test before committing to either approach.
|
|
The three new specs are the output of that step-back.
|
|
|
|
## What's next: run the test plan
|
|
|
|
The test plan is **self-contained** — drop a fresh Claude session on
|
|
`left4.me` (141.95.32.8) with the spec in hand and it can execute end
|
|
to end. System units only; no user units, no lingering.
|
|
|
|
Per the test plan's structure:
|
|
1. Capture baseline (`systemd-analyze security`, current unit state,
|
|
sysctl).
|
|
2. Tests 1-6 isolate individual directives against srcds on
|
|
`left4me-server@1` (canary; server@2 stays baseline as a fallback).
|
|
3. Test 7 composes everything that passed.
|
|
4. Test 8 verifies the threat-model defenses (D1-D5) actually work.
|
|
5. Test 9 applies `kernel.yama.ptrace_scope=2` system-wide.
|
|
6. Test 10 applies the sudo-compatible subset to `left4me-web.service`.
|
|
7. Test 11 is a 24-48h soak.
|
|
|
|
Results template at the bottom of the test plan; fill in as you go.
|
|
|
|
After execution: write the implementation plan at
|
|
`docs/superpowers/plans/2026-MM-DD-hardening-refactor.md` against the
|
|
proven composition. The plan touches `~/Projekte/ckn-bw/bundles/left4me/metadata.py`
|
|
(live source for unit emission per `items.py:2-5`) and the reference
|
|
copies in `deploy/files/usr/local/lib/systemd/system/`.
|
|
|
|
## Decision-relevant context
|
|
|
|
- **Source of truth for unit files is ckn-bw**, not left4me's
|
|
`deploy/files/`. The `deploy/files/usr/local/lib/systemd/system/*.service`
|
|
copies are reference-only post-deploy-dir-rethink; the
|
|
`systemd/units` reactor in `~/Projekte/ckn-bw/bundles/left4me/metadata.py:150+`
|
|
is the live emission. Audit confirmed (commit `5284e28` + `items.py:2-5`
|
|
comment).
|
|
- **Sandbox is already strong.** `l4d2-sandbox` unit is not in scope
|
|
for this refactor — its hardening profile was verified during 2026-05-15
|
|
build-time-idmap work. Document as load-bearing; do not weaken.
|
|
- **Sudo on the web app blocks deep hardening there.** `NoNewPrivileges=true`
|
|
and `PrivateUsers=true` are incompatible with the helper-invocation
|
|
pattern. Sudo-compatible subset only on web. Full hardening blocked
|
|
on a future "replace sudo with systemctl-managed unit triggering"
|
|
refactor (build-overlay-unit spec is a step in that direction).
|
|
- **uid-split spec is deferred, not closed.** After Phase A test
|
|
results come back, decide: residual risk small enough → close
|
|
`2026-05-15-user-uid-split-design.md` as superseded. Residual risk
|
|
significant → write the split as a follow-up.
|
|
|
|
## Open questions to clarify with operator before/during execution
|
|
|
|
(Captured in the threat model's "Open questions" section.)
|
|
|
|
1. Is gunicorn directly internet-reachable, or only via nginx?
|
|
2. Admin-auth strength on the web app (defines S2 realism).
|
|
3. Workshop content curation policy (defines A3 realism).
|
|
4. Is `ckn@10.0.4.128` usable as a test bench, or is `left4.me` the
|
|
only deployment target? (Test plan currently assumes `left4.me`.)
|
|
5. Current `kernel.yama.ptrace_scope` setting on the host.
|
|
6. AppArmor enabled on host? (Default Debian: not enabled.)
|
|
|
|
## What's NOT next
|
|
|
|
- **build-overlay-unit refactor**
|
|
(`docs/superpowers/specs/2026-05-15-build-overlay-unit-design.md`).
|
|
Still queued; sequenced behind this. The hardening profile from
|
|
this work becomes the template for the build-overlay unit.
|
|
- **Pushing the ckn-bw `91b7265` commit.** Still unpushed; still safe.
|
|
Mentioned in the previous handoff; not a blocker.
|
|
- **uid-split implementation.** Deferred pending test results.
|
|
- **AppArmor profiles.** Listed in the defenses survey; deferred.
|
|
Revisit after Phase A if directive-only hardening leaves gaps.
|
|
|
|
## Pointers
|
|
|
|
- Test plan (the thing to execute): `docs/superpowers/specs/2026-05-15-hardening-test-plan.md`
|
|
- Threat model: `docs/superpowers/specs/2026-05-15-hardening-threat-model.md`
|
|
- Defenses survey: `docs/superpowers/specs/2026-05-15-hardening-defenses-survey.md`
|
|
- Original uid-split spec (deferred): `docs/superpowers/specs/2026-05-15-user-uid-split-design.md`
|
|
- Live unit emission: `~/Projekte/ckn-bw/bundles/left4me/metadata.py:150+`
|
|
- Reference units: `deploy/files/usr/local/lib/systemd/system/`
|
|
- Scratch plan from earlier this session
|
|
(`~/.claude/plans/docs-superpowers-specs-2026-05-15-sessio-cosmic-codd.md`)
|
|
is superseded by the three specs; safe to discard.
|