29 lines
1.8 KiB
Markdown
29 lines
1.8 KiB
Markdown
# Lightweight shared Gitea runner
|
|
|
|
The existing global registration and `deploy` label are retained. The runner is
|
|
not privileged, has no Docker socket, drops all capabilities, and now runs as
|
|
UID 10001 with a read-only root filesystem and read-only registration mount.
|
|
Job workspaces live in bounded tmpfs and do not persist across container restarts.
|
|
Job capacity is one; timeout is 60 minutes. The deployment SSH credential remains
|
|
repository-scoped and its CORP forced command accepts only the current master SHA.
|
|
|
|
The derived `0.2.13-hardened` image adds a real `runner` passwd/group entry for
|
|
UID/GID 10001. Setting a numeric Compose user without this entry breaks OpenSSH
|
|
with `No user exists for uid 10001`. The installer builds from the already installed
|
|
base image without network access, then verifies UID resolution and `ssh -G`
|
|
in a read-only, network-disabled container before replacing the running service.
|
|
|
|
Install this directory's files on the Gitea server and run
|
|
`sudo python3 /path/to/install-runner-hardening.py` only after pausing assignment
|
|
of new jobs in Gitea and waiting for the current job to finish. Resume assignment
|
|
after the installer confirms the runner is healthy. An idle `ps` snapshot alone
|
|
is insufficient: the runner could receive a new job before container replacement.
|
|
The installer does not pause scheduling automatically or verify that pause. The
|
|
installer backs up configuration and restores it if the runner cannot rejoin.
|
|
|
|
**Trust boundary:** `deploy:host` executes all jobs as the same container user.
|
|
It is not a security boundary between repository authors. Keep workflow-writing
|
|
permissions restricted to trusted developers. Strict isolation requires separate
|
|
ephemeral job environments; the shared host runner must not run untrusted forks.
|
|
Container restrictions do not make it safe for mutually untrusted tenants.
|