docs(releasing): why the release job stays on a hosted runner
- self-hosted works technically: outbound HTTPS only, no inbound ports, honours HTTPS_PROXY/NO_PROXY — a box behind a proxy is fine - but it defeats the pinned-runner decision: the build host sets the glibc floor, so a workstation runner (2.39 here) puts it back to 2.38+ and drops Ubuntu 22.04 / Debian 12 / RHEL 9 - and a workstation-built release is unattested - records what self-hosting accepts: jobs run as the starting user, with that user's ~/.ssh, credentials and network reach — including hosts named in ~/.ssh/config; worst on public repos, where a stranger's PR runs code on the runner - if unavoidable: dedicated VM, unprivileged user, --ephemeral, segmented network, treat .credentials as a secret Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
a705622f4a
commit
3dcadefbfd
1 changed files with 51 additions and 0 deletions
|
|
@ -98,6 +98,57 @@ Known first-run risks, in the order they are likely to bite:
|
||||||
runners, absent in slim containers); and a 403 on publish, which is
|
runners, absent in slim containers); and a 403 on publish, which is
|
||||||
step 4.
|
step 4.
|
||||||
|
|
||||||
|
## Why the release job is NOT on a self-hosted runner
|
||||||
|
|
||||||
|
A self-hosted runner would work — it needs no inbound ports, polls
|
||||||
|
GitHub over outbound HTTPS, and honours `HTTPS_PROXY`/`NO_PROXY`, so a
|
||||||
|
box behind a proxy is fine. Two reasons not to use one for THIS job:
|
||||||
|
|
||||||
|
**It defeats the point of pinning the runner.** The release binaries
|
||||||
|
link glibc dynamically, so the build host sets the floor every user
|
||||||
|
must clear. `ubuntu-22.04` was chosen to keep that floor near 2.35. A
|
||||||
|
runner on a developer machine (glibc 2.39 here) puts it back at 2.38+
|
||||||
|
and silently drops Ubuntu 22.04, Debian 12 and RHEL 9 — the exact
|
||||||
|
regression the pinned image prevents. If a self-hosted runner is
|
||||||
|
unavoidable, build inside a container pinned to the oldest glibc you
|
||||||
|
intend to support, not on the host.
|
||||||
|
|
||||||
|
**A release built on a workstation is unattested.** "It built on my
|
||||||
|
machine" is what a pipeline exists to stop being true.
|
||||||
|
|
||||||
|
### If you do self-host, what you are accepting
|
||||||
|
|
||||||
|
A runner executes workflow code **as the user that started it**, with
|
||||||
|
that user's filesystem and network reach. On a personal workstation
|
||||||
|
that means `~/.ssh`, `~/.config/gh`, cloud and cluster credentials,
|
||||||
|
browser profiles, and every host reachable from it — including LAN
|
||||||
|
services and anything named in `~/.ssh/config`, which on a work laptop
|
||||||
|
is usually production. A job does not need to be malicious to leak;
|
||||||
|
it needs to be careless once.
|
||||||
|
|
||||||
|
The risk is highest on a **public** repository, where a pull request
|
||||||
|
from a stranger can run arbitrary code on the runner. GitHub's own
|
||||||
|
guidance is not to use self-hosted runners with public repositories.
|
||||||
|
On a private repository the blast radius is smaller but not zero:
|
||||||
|
anyone with write access, or one compromised token, reaches the same
|
||||||
|
shell.
|
||||||
|
|
||||||
|
If it is still the right call, make it boring:
|
||||||
|
|
||||||
|
- a dedicated VM or container, never a workstation, on a network
|
||||||
|
segment that cannot reach production;
|
||||||
|
- a separate unprivileged user with no SSH keys, no cloud config, and
|
||||||
|
no credentials of its own;
|
||||||
|
- `--ephemeral` registration so each job gets a clean runner and a
|
||||||
|
poisoned toolchain cannot outlive one build;
|
||||||
|
- `.credentials` under the runner's home is a long-lived credential to
|
||||||
|
act as that runner — treat the box as holding a secret;
|
||||||
|
- restrict egress if the workload allows; the same outbound HTTPS the
|
||||||
|
runner needs is what exfiltration would use.
|
||||||
|
|
||||||
|
A reasonable split: self-hosted for tests that need private-network
|
||||||
|
access or unusual hardware, GitHub-hosted for the release artifact.
|
||||||
|
|
||||||
## Releasing from the pipeline
|
## Releasing from the pipeline
|
||||||
|
|
||||||
```
|
```
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue