Runner has no isolation, so a build runs as the runner's user #144

closed cmc opened this on 2026-09-04 16:49 UTC · security · milestone v1.14.0

Discussion

cmc 2026-09-04 16:49 UTC

Split from #115, whose remedy was "-jobs N in the runner; an image: per job once isolation exists". The concurrency half is done; this is the isolation half, which the wording already treats as gated on something that does not exist yet.

A build runs whatever a repository's .gitbay/ci.yml says, with sh -c, as the runner process's own user (cmd/gitbay-runner/main.go). deploy/gitbay-runner.override.conf constrains the service — NoNewPrivileges, ProtectSystem=full, RestrictSUIDSGID, CPU and IO weight — and the key is scoped runner, so a build cannot administer the instance or write outside its workspace through systemd's protections. What it can still do is read anything that user can read, reach the network, and see the other concurrent builds' workspaces under the shared -workdir.

That is acceptable while every repository on the instance is the operator's. It stops being acceptable the moment a fork's CI runs, which registration = "open" makes reachable.

Remedy needs a decision before code: which isolation mechanism. Options are a container runtime (Docker or podman, a new external dependency on the runner host and a deployment change for bay1), bwrap (lighter, Linux-only, already common on CI hosts), or a per-build unprivileged user plus a private mount namespace. image: per job in ci.yml only means something once one is chosen.

Until then: do not enable CI for repositories you do not trust, and note that -jobs N puts N untrusted builds side by side under one workdir.

referenced in commit 3b4f05eb52 by cmc: runner: -jobs N runs that many builds at once

2026-09-04 17:13 UTC

referenced in commit 3f7409ca2e by cmc: runner, wiki: construct the step environment instead of inheriting it

2026-09-06 20:03 UTC

referenced in commit f32cde0608 by cmc: deploy, wiki: prepare a runner host for rootless podman

2026-09-06 20:03 UTC

referenced in commit 3d2795d9c2 by cmc: runner, wiki: give builds a home that outlives the build

2026-09-06 22:25 UTC

closed by commit 76668f2f38 by cmc: runner, ci, store, wiki: run build steps in a rootless podman container

2026-09-06 22:25 UTC

referenced in commit 382be3c705 by cmc: ci: image: per job, validated as a reference not a command line

2026-09-06 22:25 UTC

referenced in commit 29051440c6 by cmc: ci, deploy, wiki: an image gitbay's own jobs can build in

2026-09-06 23:07 UTC

referenced in commit d6632e706a by cmc: deploy, wiki: NoNewPrivileges=no so rootless podman can start

2026-09-06 23:34 UTC

referenced in commit 74b01ee3dc by cmc: runner: podman with the cgroupfs manager, not systemd

2026-09-07 01:23 UTC

referenced in commit 44c2c11f58 by cmc: runner, deploy, wiki: images are provisioned, never pulled by a build

2026-09-07 01:23 UTC

referenced in commit 7d675c19a7 by cmc: deploy, wiki: ProtectKernelTunables=no so a container can mount proc

2026-09-07 01:52 UTC

referenced in commit 42d56acf6e by cmc: deploy: no default sysctls in build containers

2026-09-07 01:52 UTC

referenced in commit 41f52e0d70 by cmc: wiki: validate podman mode on a scratch repository first

2026-09-07 01:52 UTC

referenced in commit 94bf85e690 by cmc: deploy: pin podman's run root under the runner's home; end the pause process with the service

2026-09-07 01:52 UTC

referenced in commit 6bea6f3df8 by cmc: runner: mount the build home into the container

2026-09-07 02:00 UTC

referenced in commit c8bc377b47 by cmc: deploy: install the image prune timer with the runner

2026-09-07 02:32 UTC

referenced in commit 89eba6adea by cmc: runner, deploy, wiki: -cpus and -memory cap a build's container

2026-09-07 02:32 UTC

referenced in commit 5bd5b27bc1 by cmc: deploy, wiki: the runner claims the isolation canary too

2026-09-07 03:48 UTC

referenced in commit 38bdad0c9f by cmc: Design: runner isolation with rootless podman

2026-09-07 04:02 UTC