registry: run the documentation worker's renders in bubblewrap (step 1 of #233) #497
Loading…
Reference in a new issue
No description provided.
Delete branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Step 1 of the epic #233 (isolating the documentation worker's runs). Related: #17, #234, #236.
Goal. Every
torbrun of the documentation worker (sandboxedintools/registry/src/documentation.trb, the single place that starts one, including the--versionprobe ofDocumentationWorker.started) runs inside bubblewrap, so a render cannot see or touch the service.Design (decided by the loop, see #233).
sandboxedputsbwrapbetweenprlimitandenv -i(the limits stay):--unshare-all(user, pid, ipc, uts, net, cgroup),--die-with-parent,--new-session,--uid 65534 --gid 65534,--ro-bindof/usr,/bin,/lib*(symlinks recreated) and of the toolchain directory (the directory ofdocumentationToolchain),--proc /proc,--dev /dev,--tmpfs /tmp,--bind <work> <work>(the only writable path, the scratch the service hands over and reads the site back from),--chdir <work>,--clearenv. No/srv/torbpath is mounted and nothing else of the service's file system.REGISTRY_DOC_ISOLATION:bwrap(default) ornone. The worker refuses to start (the existing "started" error path, so the operator sees it) whenbwrapis selected and the--versionprobe fails inside it;noneis for the stand-in toolchain of the tests and for development, and the README says it must not be used in production.REGISTRY_DOC_SCRATCH) that lies inside the storage or database path.tools/deploy/Dockerfile.registryinstallsbubblewrapin the runtime stage. Whether the container may create user namespaces (Docker's default seccomp profile forbids it) is step 2, the deployment (composesecurity_opt/ profile, or a separate renderer container if the probe cannot pass); this step keepsREGISTRY_DOC_TORBempty in the image.feat(registry): run the documentation worker's renders in bubblewrap; a seconddocs(registry): ...only if the README/RELEASE.md text should be its own commit.Acceptance criteria.
sandboxedwith isolationbwrapstarts the program underbwrapwith exactly the arguments above (unit test on the built argument list, runs everywhere).sandboxedshows, on a host wherebwrapworks: it cannot read/proc/<parent pid>/environ, cannot see or write a file placed beside the scratch directory (a stand-in for/srv/torb/...), has no network (a connect to loopback fails), runs as uid 65534, and can write inside the work directory. The test probesbwrapfirst and reports that it was skipped where user namespaces are not available.startedfails with a clear message when isolation isbwrapand the probe fails;nonekeeps today's behaviour. The existing documentation tests pass withnone.tools/registry/README.md(settings table, the "limited, not isolated" sentence), the comment ofdocumentation.trbandDockerfile.registry/compose.example.ymlcomments say what is isolated and what step 2 still owes; RELEASE.md section 7.7 gets the same in one paragraph. Docs change regeneratesskills/only if a skill template is touched (not expected).Out of scope. Compose/seccomp changes and the production switch-on (step 2), escaping of raw HTML (#234), fault classification (#236).
[loop:torbscript] claim implement by session:loop-torbscript-20261026-1044 until 2026-10-26T16:05:05Z
[loop:torbscript] implement: checkpoint (context budget), branch
loop/497-registry-bubblewrappushed (one WIP commit, to be squashed into the final Conventional Commit). Done:Config.documentationIsolation(REGISTRY_DOC_ISOLATION, defaultbwrap),sandboxCommand/bubblewrapArguments/systemLinks/toolchainDirectory/scratchProblemintools/registry/src/documentation.trb,startedvalidates isolation, refuses a scratch inside storage/database, probe error names bubblewrap; existing test config usesnone. Not compiled or run yet (no torb in the worker env). Open: tests (argument-list unit test, bwrap-probing sandbox test with skip, scratch-inside-storage refusal, probe-failure message), README settings table + "limited, not isolated" sentence, comments inDockerfile.registry(installbubblewrap, keepREGISTRY_DOC_TORBempty) andcompose.example.yml, RELEASE.md 7.7 paragraph, reword commit tofeat(registry): run the documentation worker's renders in bubblewrap,Part of #233/Closes #497PR, ci-wait. Note: toolchain dir bound is the parent ofbin(torb findsstd/besidebin). Roughly 100k tokens used. next: implement (continue)[loop:torbscript] claim implement (continuation 1) by session:loop-torbscript-20261026-1044 until 2026-10-26T16:15:10Z
[loop:torbscript] implement: checkpoint (context budget), PR #500 open (
Part of #233,Closes #497), branchloop/497-registry-bubblewrapsquashed to one Conventional Commit. Done: code fixed to compile (torb checkclean),documentation-isolation.test.trb(8 tests pass locally with the nightly toolchain; bwrap is absent on this host so the isolation run itself is exercised only in CI, it prints a skip note where bwrap does not work), README table + sentence, Dockerfile.registry (bubblewrap), compose comments, RELEASE.md 7.7. Open: forge CI result forcd352aa8(ci-wait in flight), fix findings on the same branch, then commentnext: review (Argus). Roughly 160k tokens used by this continuation.[loop:torbscript] claim implement (continuation 2) by session:loop-torbscript-20261026-1044 until 2026-10-26T16:35:04Z
[loop:torbscript] implement: forge CI green on PR head
584a9d3c(#500). The only failure atcd352aa8was pdisc (stale body hash oftools/registry/README.md); fixed by restamping.pdisc-sidecar.yaml, amended into the single Conventional Commit and force-with-lease pushed. gates, bootstrap, tier A/B and the tools/registry job (which runs the new bwrap test) all pass. About 60k tokens this continuation, most of it waiting on a long CI queue. next: review (Argus)