runner: a key scope that reaches the runner protocol and nothing else !188

merged merged by cmc on 2026-09-03 15:59 UTC · krz/gitbay:runner-scope into main

Discussion

cmc

Runner commands required an instance admin, so the key a CI host holds was an admin key: a build step could read it and run admin commands. On gitbay.org the runner polls as the admin account with no repository scope while registration is open.

  • keys add --scope runner confines a key to runner next/log/done and read-only git; Dispatch refuses every other command for that scope, whoami included.
  • requireRunner accepts a runner-scoped key or, still, an admin, so the deployed runner keeps working until its key is swapped.
  • deploy/gitbay-runner.override.conf adds NoNewPrivileges, ProtectSystem=full, ProtectKernelTunables, ProtectControlGroups, RestrictSUIDSGID.
  • TestRunnerScopedKey: claim works, every other command is exit 4, the account's full key is refused as a runner, clone works, push is refused.

Not in this MR: env scrubbing in the runner (a step runs as the same uid and can read the same files, so the scope is what limits the blast radius), a per-repository CI opt-in, and the Threat-Model wiki page. Left as Ref #92; the operational follow-up on bay1 is to create a non-admin ci account, add its key with --scope runner, and restart the runner with -repos krz/gitbay.

Ref #92