Not persisting environment between jobs in self-hosted runners

In https://docs.github.com/en/actions/hosting-your-own-runners/about-self-hosted-runners#self-hosted-runner-security-with-public-repositories

GitHub advises against using GitHub Runner for public repos and adds:

Untrusted workflows running on your self-hosted runner poses significant security risks for your machine and network environment, especially if your machine persists its environment between jobs.

To mitigate the risk, how do you destroy the environment in the self-hosted runner between jobs?

In principle: The same way hosted runners do, run the Runner service in a VM, and after each job destroy it and restart from a known clean image.

There are a bunch of issues to consider, though:

  • I’m not sure if the Github infrastructure supports assigning only one job to a self-hosted runner, at least until it is replaced. You definitely cannot rely on the runner itself for that, because an attacker running code inside the VM might mess with it.
  • An attacker running code in the VM has full network access to anything the VM can reach. That can be mitigated with a strict firewall.
  • Consider the risk that there might be exploitable bugs in whatever VM implementation you use, and possible mitigations. Decide if you’re willing to accept the risk that remains after mitigations.

Thank you for your reply. The simplest way to run the code in a VM is to run it inside a docker image. Unfortunately if you do that then you cannot run the jobs themselves inside a docker image, as that’s not supported by GitHub. So you would need a more heavyweight solution like automatically triggering the boot of a Virtualbox VM or something similar.

However in that case, I am not sure how that would work because the receiving runner would have to start the vm itself. Doesn’t seem like something that can be done transparently on the host.