Which GitHub Actions Runners Fit Security-Sensitive Repositories?
Run each job on a VM that is destroyed after the build. WarpBuild managed and BYOC runners compared with GitHub-hosted and self-hosted runners for sensitive code.
Last verified:
For a security-sensitive repository, run each job on a virtual machine that is destroyed after the build. Use WarpBuild managed runners if a VM run by a vendor is acceptable. They come in sizes up to 32 vCPU on Linux and Windows (cloud runners docs). Use BYOC (bring your own cloud) if the runner must sit in your own cloud account but you want WarpBuild to operate it. GitHub-hosted runners other than single-CPU runners also meet this bar at standard sizes. Self-host only if you can make your own runners equally short-lived.
Which runner option should a security-sensitive repository use?
Pick an option where one job gets one fresh virtual machine and nothing is reused. That property removes the main risk on a shared runner, where one job reads or changes what an earlier job left behind. GitHub's own security guidance says self-hosted runners "can be persistently compromised by untrusted code in a workflow", while GitHub-hosted runners run code in "ephemeral and clean isolated virtual machines".
WarpBuild managed runners, BYOC runners and GitHub-hosted runners other than single-CPU runners all meet that bar. A self-hosted runner meets it only when you build it that way. So the choice between the first three comes down to where the machine must live and what size it must be, not to isolation.
WarpBuild provides GitHub Actions runners. Your workflows, secrets and permissions stay in GitHub, and moving a job is a change to its runs-on label.
How managed, BYOC, GitHub-hosted and self-hosted runners compare
Three of the four options give each job its own VM and destroy it after the job. They differ in who runs the machine and where it lives.
| Property | WarpBuild managed runner | WarpBuild BYOC runner | GitHub-hosted runner | Self-hosted runner you operate |
|---|---|---|---|---|
| Where the machine runs | WarpBuild infrastructure | Your AWS, GCP or Azure account | GitHub infrastructure | Wherever you run it |
| Machine per job | A VM created on demand for that job | A VM created in your account for that job | A new VM, except single-CPU runners, which run in a container on a shared VM | Whatever you configure. Persistent hosts and container pods are common |
| Reuse between jobs | None by default. The VM is destroyed after the build. Opt-in snapshot runners on Ubuntu boot later jobs from a disk you choose to save | None. The VM is terminated when the job ends | None for VM-based runners | Possible whenever the host outlives the job |
| Disk | Its own encrypted volume, created on demand and destroyed after the build | Its own encrypted volume, destroyed with the instance | Not documented by GitHub | Your storage under your retention rules |
| Cache | Encrypted and stored where only your runner can reach it | In the object storage bucket of your stack, kept until your lifecycle policy expires it | Stored per repository. A run can restore caches from its own branch or the default branch. A pull request can also restore caches from its base branch, including for forks. Entries not used for 7 days are removed | Yours to encrypt and scope |
| Build secrets | Not accessed or stored | Not accessed or stored | Encrypted with Libsodium sealed boxes before they reach GitHub, then decrypted by GitHub to inject into the job | Held by GitHub, then exposed to whatever persists on the host |
Sources: the WarpBuild columns come from the runner security documentation and the BYOC runner lifecycle. The GitHub-hosted column comes from GitHub's GitHub-hosted runners documentation, the dependency caching reference, the secrets documentation and the security guidance. The self-hosted column also comes from GitHub's security guidance.
Which option fits which situation
Choose by where the runner is allowed to live and what the build needs. Isolation is the same for WarpBuild managed runners, BYOC runners and GitHub-hosted runners, except GitHub's single-CPU runners, which run in a container on a shared VM.
| Your situation | Option that fits |
|---|---|
| A VM run by WarpBuild is acceptable, and you want larger or faster machines | WarpBuild managed runners |
| Policy says build machines, disks and caches must stay in your own cloud account or VPC | WarpBuild BYOC on AWS, GCP or Azure |
| Standard machine sizes are enough and builds do not need your private network | Standard GitHub-hosted runners or WarpBuild managed runners. On Linux x64 and ARM64 from 2 to 32 vCPU and on Windows x64 from 4 to 32 vCPU, managed runners bill less per minute than the GitHub runner of the same size and architecture (pricing, GitHub rates) |
| You must operate the hardware yourself, for example with Actions Runner Controller (ARC) | Self-hosted runners, set up as one-job runners |
GitHub-hosted runners also come in larger sizes and with Azure private networking. These are billed at their own rates and need their own setup.
If policy only requires the runner to sit in your own cloud, BYOC does that without a fleet to operate. Self-hosting fits when you must run the hardware yourself and can keep runners as short-lived as a hosted VM. GitHub's security guidance says just-in-time runners "perform at most one job before being automatically removed". It also warns that reusing hardware to host them can expose information from the environment, and that self-hosted runners "should almost never be used for public repositories". ARC runs runners as pods that contain the runner containers in your Kubernetes cluster. Pods on the same nodes share that hardware, so check how your cluster isolates jobs before it runs untrusted code.
What a security reviewer can record about WarpBuild runners
On default runners, each job runs in its own VM that is created on demand, destroyed after the build and never reused. Its encrypted storage volume is destroyed with it, and WarpBuild does not access or store build secrets, per the runner security documentation. The source checkout lives on that volume, as the source code answer explains. Snapshot runners are opt-in. Before you save a snapshot, run the cleanup step to remove credentials, because GitHub may give a snapshot runner to other jobs in your organization. See the Security section of Snapshot Runners. For the full set of reviewer questions and evidence, use the security review checklist.
Can public repositories and fork pull requests run safely?
Yes, on a runner that gives each job a fresh VM. WarpBuild runners are managed for you, but they connect through GitHub's self-hosted runner interface, in the Default runner group of your GitHub organization. By default, GitHub lets only private repositories use a runner group, per its runner group documentation. So enable it once: open the Default runner group settings for your organization and check Allow public repositories.
The caution behind GitHub's default is real for long-lived runners. A pull request from a fork can carry code that runs on the machine, and on a host that outlives the job, that code can leave something behind for the next job. A per-job VM that is destroyed after the build removes that path. This is why the public repositories documentation states that WarpBuild runners provide the same safety as GitHub-hosted runners.
Two GitHub settings still matter on a public repository. With the exception of GITHUB_TOKEN, GitHub does not pass secrets to the runner when a workflow is triggered from a forked repository, per the GitHub secrets documentation. A narrow permissions block limits what that GITHUB_TOKEN can do.
name: pr-checks
on:
pull_request:
permissions:
contents: read
jobs:
test:
runs-on: warp-ubuntu-latest-x64-4x
steps:
- name: Check out the code
uses: actions/checkout@v7
with:
persist-credentials: false
- name: Install dependencies
run: npm ci
- name: Test
run: npm testpersist-credentials: false tells the checkout action not to configure the token with the local git config, so later steps cannot reuse it for git commands. Since version 6, the action stores that token in a file under $RUNNER_TEMP when the input is left at its default of true, per the actions/checkout README. On a machine that is destroyed after the build, the exposure lasts one job, and this setting closes it inside that job too.
Fork pull requests that really need a credential belong in a separate workflow on a separate trigger. Gate it behind an environment with required reviewers, so a person approves the job before it runs.
How runners reach private services
Jobs that need a private database or an internal API reach it through the WarpBuild Networking addon, not through an inbound opening in your network. You create a network addon configuration and add network.name=<config-name> to the runs-on label. When the job starts, the runner joins your Tailscale tailnet using Tailscale OIDC and an ephemeral node key. When the job finishes, the ephemeral node is removed from the tailnet automatically, so its access ends with the machine.
jobs:
integration:
runs-on: warp-ubuntu-latest-x64-8x;network.name=production-tailnet
steps:
- uses: actions/checkout@v7
- name: Run integration tests against the private API
run: ./scripts/integration.shThe networking documentation covers the Tailscale trust credential and tag scoping. The tags a runner advertises must be a subset of the tags you configure, so your tailnet policy limits what a compromised job can reach.
The WarpBuild control plane calls GitHub from three static egress IP addresses. If your organization uses a GitHub IP allow list or restricts inbound traffic to a GitHub Enterprise Server instance, add those addresses to the allow list. They are published in the GitHub Enterprise documentation.
If policy requires the runner instance itself to sit inside your own network, use BYOC. The instance, its network and the storage bucket are then resources in your cloud account. The AWS BYOC page covers that setup and its hardening steps.
Where the compliance evidence is
WarpBuild is SOC 2 Type 2 certified (Security, Availability, Confidentiality). See the trust center.
For BYOC, much of the evidence a reviewer wants comes from your own cloud console and audit trail, because the instances, disks and bucket are in your account. The security review checklist explains which evidence applies to each deployment.
FAQ
Are WarpBuild runners safe to use on public repositories?
Yes. Each WarpBuild job runs in its own virtual machine that is created on demand and destroyed after the build, so a pull request from a fork gets a clean machine that no other job reuses. GitHub also does not pass repository secrets, except GITHUB_TOKEN, to a workflow triggered from a forked repository. Public repositories need one setting first: check Allow public repositories on the Default runner group in your GitHub organization settings.
Does WarpBuild access or store our build secrets?
No. WarpBuild does not access or store any build secrets. Secrets are stored in GitHub as repository or organization secrets (https://docs.github.com/en/actions/concepts/security/secrets) and are only accessible to your runner environment. That environment lives for the length of the build and is then destroyed with its encrypted storage volume, per https://www.warpbuild.com/docs/ci/security.
Is a BYOC runner reused for a second job?
No. A WarpBuild BYOC runner is one VM created in your cloud account for one job and terminated when the job ends. Standby disks change only how the VM boots. A pooled VM is pre-initialized and shut down, then powered on for one job and terminated at the end of it.
Can a WarpBuild runner reach services on our private network?
Yes, through the WarpBuild Networking addon. You add network.name=<config-name> to the runs-on label, and the runner joins your Tailscale tailnet with an ephemeral node key when the job starts. The node is removed from the tailnet when the job finishes. Teams that want the runner inside their own network can also use BYOC.
What does a security review need from a runner vendor?
Documented answers on how jobs are isolated, how long build storage lives, whether the vendor can read secrets, what compliance attestation exists, and where runner traffic goes. The security review checklist at https://www.warpbuild.com/enterprise/ci-security-review lists them in the order reviewers ask.
Start with $10 in free credits
Change the runner label in your workflow and keep the rest of your GitHub Actions setup. Runner time is billed per minute.