Skip to content

docs(rfc): RFC-CLIENT-0002 — least-privilege install (accepted)#369

Open
LukasWodka wants to merge 4 commits into
developfrom
rfc/least-privilege-install
Open

docs(rfc): RFC-CLIENT-0002 — least-privilege install (accepted)#369
LukasWodka wants to merge 4 commits into
developfrom
rfc/least-privilege-install

Conversation

@LukasWodka

@LukasWodka LukasWodka commented Jul 22, 2026

Copy link
Copy Markdown
Contributor

RFC-CLIENT-0002 — Status: Accepted (2026-07-25). Renders at docs/rfcs/0002-least-privilege-install.md.

We require blanket root/sudo today, which blocks non-admin data scientists/researchers (hospitals, universities, HPC) — our ICP. Audit of every sudo call site shows the entire privileged surface is the container runtime + 2 kernel modules; the CLI tools and the k3d/k3s cluster are already user-space. So the requirement isn't "admin" — it's "a usable container runtime."

Proposes a tiered install (Tier 0 zero-root when a runtime exists → Tier 1 rootless → Tier 2 one scoped privileged step, ideally an admin's one-time prepare-host), plus how this reframes B2 (post-install PATH is a consequence of the no-sudo choice).


Why this is now ready to merge

This PR sat as a "do not merge" draft since 2026-07-22 while the design it describes was accepted in practice and largely built. The tracking epic tracebloc/backend#1168 is 6 of 9 children merged (67%) — the foundation and host probe (#1171), tier routing (#1172), sudo/root handling (#1173), CLI PATH (#1174), Tier 0 (#1175) and the rootless spike (#1176) are all on develop. @saadqbal's review has been adopted in the document (rootless Docker is the primary target, not a fallback).

Leaving it open indefinitely left the repo with no record of a decision the team had already acted on, and parked a card in In progress that no longer described any work. So: merge it as the accepted design-of-record. The three unbuilt children (#1177 Tier 1, #1178 prepare-host, #1179 Windows/WSL2) are tracked on the epic — implementation status belongs there, not in this document's header.

Changes in the latest commit

  1. Renumbered 00010002. This was a real within-repo collision: client already has docs/rfcs/0001-rootless-spike.md on develop, so two different documents in the same directory both claimed 0001. 0002 is the next free number in this repo. The rootless spike's back-link is repointed to 0002 in docs(rfc): qualified identifier for the rootless spike + fix the LPI back-link #403.
  2. Qualified identifier RFC-CLIENT-0002 in the header. RFC numbers are per-repo, so a bare "RFC 0001" names four different documents across the org. Org-wide index: docs/rfcs/README.md in tracebloc/backend (private) — see tracebloc/backend#1259.
  3. Status set to Accepted (2026-07-25), noting that implementation is tracked in tracebloc/backend#1168.
  4. Dropped the "do not merge" framing from the title and this body.

The document body is otherwise unchanged — only the header block and the filename moved.

The general rule this adopts

An RFC's status (Draft / Accepted / Superseded / Rejected) lives in the document header, never as a board column: the board tracks implementation, the document tracks the decision, and they move at different speeds. A discussion PR either merges (accepted) or closes (rejected) — it does not linger. Written up in the index added by tracebloc/backend#1259.

Companion PRs

Repo PR Contents
backend tracebloc/backend#1259 the qualified-ID scheme + the org-wide index
cli tracebloc/cli#412 qualified IDs in the three cli RFC headers
client #403 RFC-CLIENT-0001 header + the back-link repoint to 0002

In-flight: tracebloc/backend#1146 adds backend/docs/rfcs/0002-platform-cost-autoscale-architecture.md. It will need the same header treatment (RFC-BACKEND-0002) when it merges — it is already listed in the index.

Test plan

Docs-only; no installer script, chart or workflow touched. Verified the rename is recorded as a rename (not delete+add), the document renders, and no customer names or internal hostnames appear in this public repo.

🤖 Generated with Claude Code


Note

Low Risk
Documentation-only; no installer, CLI, or runtime behavior changes in this PR.

Overview
Adds docs/rfcs/0002-least-privilege-install.md as the accepted design-of-record for RFC-CLIENT-0002 (least-privilege install), resolving the in-repo RFC number collision with 0001-rootless-spike.md.

The document records the tiered install direction (Tier 0 usable runtime with no root → Tier 1 user-scoped rootless Docker → Tier 2 one scoped admin/prepare-host step), rootless Docker as primary, side-effect-free host audit / tier detection (docker info, cgroup v2 + userns, sudo messaging), and how B2 (post-install PATH) follows from installing the CLI without sudo. Header marks status Accepted (2026-07-25) and points implementation at tracebloc/backend#1168; rollout and remaining spike/Tier 1/prepare-host/WSL work stay tracked on that epic, not as open RFC design.

Reviewed by Cursor Bugbot for commit f303d54. Bugbot is set up for automated code reviews on this repo. Configure here.

Draft RFC: the installer assumes blanket root/sudo, which excludes non-admin
users (hospital/university/HPC researchers). Audit shows the ONLY privileged
surface is the container runtime + two kernel modules; tools + the cluster are
already user-space. Proposes a tiered model (zero-root when a runtime exists →
rootless → one scoped privileged step) and ties in A2 (sudo/root) + B2 (PATH).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@saadqbal

Copy link
Copy Markdown
Contributor

Nice framing on this, Lukas — the "we don't need admin, we need a container runtime" reframe is exactly right. My takes on the open questions:

1 + 2 are really one decision. Committing to rootless as Tier 1 is what makes the kernel-module question disappear, so I'd merge them. Go rootless Docker as the primary target — it keeps our whole k3d code path intact (just a different socket) and it's a genuine security selling point to hospital/uni IT. Podman-as-k3d-backend is still too flaky to be primary (best-effort only); k3s-rootless is the cleaner long-term end state but a bigger rewrite — park it as a future spike, not a competing option now.

On the modules: rootless sidesteps both. overlay → fuse-overlayfs (userspace, what rootless uses anyway); br_netfilter → not needed once networking goes through slirp4netns. So "can't modprobe" should mean fall to rootless, not fail. The real prereq to probe instead is cgroup v2 + unprivileged userns, which is on by default on anything modern (Ubuntu 22.04+, RHEL 9+).

3 — prepare-host: yes, build it, but thin. IT wants one reviewable script they approve once, then researchers self-serve at Tier 0. Ship it as both a readable snippet and a tracebloc prepare-host subcommand that just runs that same audited snippet. Fine that it's last in the rollout.

4 — WSL2: once you're inside the distro you're on Linux, so the same tiering applies there. Enabling WSL2 is the Windows-side "Tier 2" (one-time admin). One thing to call out: prefer rootless Docker inside WSL over Docker Desktop — it dodges Docker Desktop's commercial licensing, which is a real blocker for large hospital systems. Use Docker Desktop's WSL integration only if it's already there.

5 — detection: probe behaviorally, side-effect-free. docker info exit 0 is the one test that proves binary + daemon + user-in-group all at once — that's your Tier 0 check. Skip hello-world by default (it pulls an image); gate it behind --verify. For the A2 messaging, the trio id -u / command -v sudo / sudo -n true cleanly separates already root vs sudo missing vs sudo needs a password — that kills the current misleading abort.

Net: I'd rewrite the open questions as one real question — "which rootless runtime, and validate cgroup v2/userns across our target hosts" — because that's the only part that needs a hands-on spike.

LukasWodka and others added 2 commits July 22, 2026 16:37
…-host + host audit, WSL2=Linux, detection yes)

Resolves the five open questions from the first draft per Lukas 2026-07-22:
Docker as the single runtime (rootless Docker at Tier 1); kernel modules a hard
Tier-2 requirement with no userspace fallback; build a standalone prepare-host
step plus a short host-audit report shared with doctor; WSL2 treated as Linux and
native Windows preferring rootless Docker; and yes to side-effect-free detection.
Rollout re-sequenced so detection + audit land first (also closing A2/B2).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Folds in Asad review of #369. Key flip: rootless Docker is the primary path,
not a fallback, which dissolves the kernel-module question (fuse-overlayfs +
slirp4netns remove overlay/br_netfilter from the privileged surface). Cant-modprobe
now falls to rootless rather than failing; we probe cgroup v2 + unprivileged userns
instead. prepare-host shipped as snippet + subcommand; WSL2 prefers rootless over
Docker Desktop (licensing); detection uses docker-info + the id/sudo/sudo-n trio.
Five open questions collapse to one hands-on spike: validate rootless Docker as the
k3d backend across target hosts. Rollout re-sequenced so that spike leads the core
build.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@LukasWodka

Copy link
Copy Markdown
Contributor Author

Agreed on all of it — folded the whole review into the RFC (just pushed).

The big one: rootless Docker is now the primary target, not a fallback. You're right that 1 + 2 are really one decision — committing to rootless is what makes the module question disappear. So the RFC now says "can't modprobe → fall to rootless, not fail," and probes cgroup v2 + unprivileged userns instead. Podman → best-effort, k3s-rootless → parked as a future spike.

Also folded in:

  • prepare-host as both a reviewable snippet and a tracebloc prepare-host subcommand running that same audited snippet.
  • WSL2: same tiering inside the distro; enabling WSL2 = the one-time Windows admin step; and prefer rootless Docker over Docker Desktop — the licensing point is a great catch, that's a real blocker for the big hospital systems.
  • Detection: docker info exit 0 as the single Tier-0 test, hello-world behind --verify, and the id -u / command -v sudo / sudo -n true trio for the A2 messaging.

So the five open questions collapse to the one you named — validate rootless Docker as the k3d backend across our target hosts (cgroup v2 + userns coverage on the hospital/HPC images we've actually seen, plus fuse-overlayfs dataset-copy perf and the security posture we endorse). I've made that the gating spike in the rollout; everything else is build work.

That's the only thing left open — happy to scope it as a spike ticket, or if you'd rather own the validation yourself, even better. Thanks for the sharp review.

Two fixes to get this RFC out of limbo.

**Renumber 0001 -> 0002.** `client` already has a `0001-rootless-spike.md` on
develop, so this file collided with it inside its own repo. 0002 is the next
free number in this repo. The header now carries the qualified ID
`RFC-CLIENT-0002` — RFC numbers are per-repo, so a bare "RFC 0001" names four
different documents across the org.

**Status: Accepted (2026-07-25).** The design has plainly been accepted in
practice: the tracking epic tracebloc/backend#1168 is 6-of-9 children merged,
including the foundation, tier routing, sudo handling, Tier 0 and the rootless
spike. Leaving the document as a permanent "do not merge" draft left the repo
with no record of a decision the team had already acted on. Implementation
status stays where it belongs — on the epic, not in this header.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@LukasWodka LukasWodka changed the title RFC 0001: least-privilege install (for discussion — do not merge) docs(rfc): RFC-CLIENT-0002 — least-privilege install (accepted) Jul 25, 2026
@LukasWodka
LukasWodka marked this pull request as ready for review July 25, 2026 10:30
@LukasWodka

Copy link
Copy Markdown
Contributor Author

bugbot run

@LukasWodka

Copy link
Copy Markdown
Contributor Author

👋 Heads-up — Code review queue is at 39 / 30

Above the WIP limit. The team convention is to review existing PRs before opening new work.

Open PRs currently in Code review (oldest first):

Pull from review before opening new work. (This is a nudge from the kanban WIP check, not a block.)

@cursor cursor Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

✅ Bugbot reviewed your changes and found no new issues!

Comment @cursor review or bugbot run to trigger another review on this PR

Reviewed by Cursor Bugbot for commit f303d54. Configure here.

@LukasWodka LukasWodka self-assigned this Jul 26, 2026
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