runner: images are provisioned, never pulled by a build !307

merged merged by cmc on 2026-09-07 01:23 UTC · krz/gitbay:runner-provisioned-images into main

Discussion

cmc

The two loose ends from deploying isolation, which turn out to be one decision.

RestrictSUIDSGID=yes blocks image unpacking. A pull inside the service dies on open /usr/bin/chage: operation not permitted — chage is setgid, and so is something in nearly every distribution image. The choice was to drop a third hardening flag or to stop pulling at build time.

Stopping is the better half, and not only for the flag. On an instance where anyone can push a ci.yml, image: would otherwise mean "fetch and run arbitrary code from a registry nobody vetted". With --pull=never an operator pulls or builds what is allowed and a build chooses among those. That is a security property worth having, arrived at from a constraint.

No built-in default image. docker.io/library/debian:stable-slim was a poor default before and an actively broken one now: with --pull=never, a default the host does not have fails every job that names none. -image is required under -isolation podman, checked before the podman probe so the message does not depend on the machine. bay1's drop-in passes localhost/gitbay-ci:1.

A job naming an image the host lacks fails with the reason and what to do, rather than podman's raw "no such image".

The drop-in now carries ExecStart too, so the flags and the sandboxing that has to match them live in one file — -isolation podman needs NoNewPrivileges=no, -image needs a provisioned image.

TestRunnerRefusesPodmanWithoutAnImage covers the new refusal; TestPodmanMissingImageFailsTheBuild (podman-gated) covers the build-time message.

Stacked on !305.

Ref #144

retargeted from runner-cgroupfs to main: !305 merged

2026-09-07 01:23 UTC