跳到主要內容

Harden build runners with ephemeral execution and least privilege

Implementation Effort: High – Moving to ephemeral, least-privilege runners requires re-architecting build infrastructure with on-demand provisioning and teardown and maintaining it as workloads change. User Impact: Low – Runner hardening is an infrastructure change owned by platform teams; developers' pipelines keep running and end users are not affected. Lifecycle Stage: Build

Overview

Use ephemeral, least-privilege build runners so each pipeline job runs in a fresh, isolated environment that is destroyed after execution.

Build runners and agents are among the most privileged components in a software delivery pipeline. They execute arbitrary code from repositories, hold deployment credentials, and often run with administrative permissions on the host operating system. When a runner persists between jobs, every job inherits the residue of previous executions — cached credentials, modified system files, installed tooling, and potentially malicious processes planted by a prior workflow.

Hardening build runners with ephemeral execution means each job gets a fresh, clean environment that is destroyed immediately after the job completes. Least-privilege runner configuration requires runners to operate with only the permissions necessary for the specific job they execute.

Persistent runners frequently accumulate permissions over time as teams add service connections, tokens, and network access to support different workflows. Ephemeral runners reverse this pattern because each runner can be provisioned on demand, scoped to a single job, and destroyed immediately afterward.

In GitHub Actions, prefer GitHub-hosted runners where possible. When custom environments are required, use ephemeral self-hosted runners such as runner ephemeral mode, runner scale sets, or Actions Runner Controller on AKS.

If you host runners on Azure yourself, use disposable compute such as Azure Container Instances or virtual machines with explicit runner registration and teardown automation. Azure Container Apps Jobs is also a supported pattern for running self-hosted GitHub Actions runners or Azure Pipelines agents on fully managed Azure infrastructure, where the underlying infrastructure is managed by Azure but you remain responsible for the runner configuration, lifecycle, and job execution model.

Container Apps Jobs have workload-specific limitations, including no Docker-in-Docker support, limited persistent storage, and execution time constraints. Evaluate whether these constraints fit your build workload before adopting this pattern.

In Azure DevOps, Microsoft-hosted agents already provide a fresh virtual machine for each job. For self-hosted Azure DevOps agents, use VM scale sets or other disposable worker patterns only if you also reimage or destroy the worker after each run.

Without ephemeral execution, organizations face a growing attack surface in their build infrastructure. A threat actor who compromises a persistent runner can install a backdoor that intercepts every subsequent build, exfiltrate secrets from unrelated projects, or tamper with artifacts destined for production. Persistent runners also create compliance gaps because there is no guarantee that the build environment matches the expected baseline. Ephemeral runners, combined with unprivileged execution and restricted network access, transform the build layer from a high-value persistent target into a transient, hardened execution environment. By giving each job a fresh, isolated environment scoped to only the permissions it needs, this task supports Use least privilege access and Assume breach.

Reference