Keep a copied template on GitHub hosted runners until you have reviewed it fully. A self hosted runner is your own machine inside your own network, and a workflow that runs there can reach whatever that machine can reach. If you must use one, isolate it, keep it short lived, and restrict who can send jobs to it.
What changes with your own runner
GitHub's own template examples run on a hosted runner label such as ubuntu-latest. Changing that label to a self hosted one is a one line edit, and it changes the blast radius.
GitHub's page on compromised runners lists what an attacker can do once they run commands on a runner: read secrets that the job references, steal the job token, send data out over the network, change repository contents if token permissions allow, and so on. The same page notes that GitHub hosted runners do not scan for malicious code downloaded during a job. On your own runner, the same actions happen with your network around them.
Questions to ask first
- What can this machine reach? Internal services, cloud metadata, other build output?
- Is it shared across repositories? A runner used by many repositories lets one job leave things behind for another.
- Is it fresh for each job? A runner that persists between jobs can carry files, caches and processes from an earlier run.
- Who can trigger jobs on it? Pull requests from forks and outside contributors are a particular concern.
- What credentials live on it? Cloud credentials sitting on disk are available to every job.
A comparison
| Property | GitHub hosted | Self hosted, default setup |
|---|---|---|
| Network position | Outside your network | Inside your network |
| Lifetime | Fresh for each job | Often long lived |
| Who maintains the image | GitHub | You |
| Reach of a hijacked step | Job token and referenced secrets | Those plus whatever the host can reach |
If you still need one
- Separate runner groups for sensitive repositories, so a low risk repository cannot send jobs to a high risk runner.
- Short lived runners that start clean for each job and are destroyed after.
- No standing credentials on the machine. Prefer short lived federated credentials, which GitHub describes through OpenID Connect.
- Network limits so the runner reaches only what builds need.
- No untrusted pull requests on those runners.
- Patching the host and runner software on a fixed schedule.
Our post on ephemeral versus persistent CI runners goes deeper on the lifetime choice.
Review the template again
When a template uses a custom label, read the whole file with that in mind. Steps that were harmless on a disposable hosted machine, such as installing tools globally or writing to the home directory, behave differently on a machine that lives on.
Quick check
Do self hosted runners make builds safer?
Not by themselves. They give you control and network access, and with that comes responsibility for isolation and patching.
Can I use a hosted runner to test a template first?
Yes, and it is a good habit. Trial on a hosted runner in a throwaway repository, then decide whether the job needs your own hardware.
Sources
- Compromised runners, GitHub Docs
- Secure use reference, GitHub Docs
- OpenID Connect in GitHub Actions, GitHub Docs
Last reviewed: 19 October 2026.