Skip to content
MNPPI on GitHub

Self-hosted runner security

Status
Pilot
Reviewed
July 23, 2026
Cadence
Review each quarter

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

The preferred model keeps the host small and creates one isolated environment for each job. The environment registers for one job and disappears after 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.
  • A no-new-privileges control.
  • CPU, memory, process, and disk limits.
  • An isolated working directory.
  • A short registration lifetime.
  • Automatic cleanup after success, failure, or timeout.

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

This is the default for normal repository checks. It is fast, repeatable, and practical for a small organization. It shares the host kernel, so it is not a complete 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 for each job. Keep package and cloud credentials out of validation jobs unless the check requires them.

A job is complete only when:

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