Skipbox
PagesVM isolation

Security

VM isolation

How Skipbox keeps jobs apart: one new VM per job, deleted with its disk, a runner for one job, no inbound connections, and private repositories only.

View as Markdown

One new VM per job

Every job gets a new VM, made for it. The VM runs that one job and is never given another, then it's deleted with its disk. A VM still there 6 hours after it started is deleted too.

Nothing a job leaves on disk, in Docker or in memory reaches a later job.

Where the VMs run

In Helsinki, on dedicated servers Fluxenic rents from Hetzner and on Hetzner Cloud servers made for one job each. A Hetzner Cloud server's vCPU are shared with other Hetzner customers; no other job shares that server, its network or its disk.

A runner for one job

Skipbox registers each runner just in time, for a single job, with the job's own labels. On an organization it's in the organization's default runner group; on a personal account it's on the job's repository, so it can only run that repository's jobs. A runner left registered after the job is removed.

No inbound connections

Nothing on the internet can connect to a job's VM. See Network and egress.

Private repositories only

On a public repository, anyone who opens a pull request can run code on a self-hosted runner. Skipbox refuses jobs from public repositories and emails the owner. A repository made public later has its waiting jobs refused.

What a job can read

A job's VM holds your workflow's secrets and GitHub's token for that job, as on any runner, and code the job runs can read them. Treat a Skipbox runner as you treat a GitHub-hosted one: give a job only the secrets it needs.

Updated November 9, 2026