Skip to content
MNPPI on GitHub

Self-hosted runner security

Status
Pilot
Reviewed
July 24, 2026
Cadence
Review each quarter

The runner host is a trust boundary. A workflow can read or change anything its job environment can reach.

If a PR runs lint and tests on your hardware, treat that job as untrusted code. Keep the host small. Create one isolated environment per job. The environment registers for one job and disappears when the job ends.

Use a just-in-time GitHub runner inside a rootless container. Just-in-time means GitHub registers the runner for one job only.

The environment should have:

  • No host filesystem mounts
  • No container engine socket
  • No privileged mode
  • No added Linux capabilities
  • no-new-privileges
  • CPU, memory, process, and disk limits
  • An isolated working directory
  • A short registration lifetime
  • Automatic cleanup after success, failure, or timeout

The host keeps only the scheduler and container runtime. It must not keep project source or job credentials after cleanup.

Default for normal repository checks. Fast and practical for a small organization. Shares the host kernel, so it is not a full hostile-code boundary.

Run untrusted fork code without secrets. Do not use privileged workflow events to execute untrusted pull request code.

Limit GitHub token permissions per job. Keep package and cloud credentials out of validation jobs unless the check needs them.

A job is complete only when:

  • GitHub removes the one-job registration
  • The isolated environment stops
  • The work directory is gone
  • Temporary credentials expire or are removed
  • No project process remains on the host