Runners

GitHub Actions


GitHub Actions

Assistance managed runners let GitHub Actions jobs run on self-hosted capacity that is designed, secured, monitored, and operated inside an agreed customer or Assistance-managed boundary. Use this page when you are moving selected workflows from GitHub-hosted runners to managed self-hosted runners, need private-network access, or need a clearer operating model for runner security and support.

For the general managed runner onboarding flow, start with Managed runner onboarding. For baseline hardening controls, see Runner security hardening. For day-2 operations, see Runner monitoring and support and Troubleshooting.

Where GitHub runners can be attached#

GitHub Actions self-hosted runners can be registered at different scopes. Assistance will recommend the narrowest scope that still meets your delivery needs.

ScopeBest forUser impactNotes
Repository runnerOne repository, sensitive workload, or pilot migrationJobs in that repository can target the runner labelsEasiest to reason about; useful for production deploy repos or proof-of-value migrations
Organization runnerShared runner pool across multiple repositoriesApproved repositories in the organization can use the runner groupCommon for platform teams; requires clear repository access controls
Enterprise runnerShared capacity across multiple organizations in GitHub EnterpriseEnterprise policy controls which organizations and repositories can use the poolUseful for large estates; needs stronger governance and change records

Runner scope affects who can see the runner, who can route jobs to it, and how blast radius is controlled. Assistance usually separates production, non-production, privileged, and high-resource workloads into different runner groups and labels.

Runner groups and labels#

GitHub routes jobs by matching the workflow runs-on value to available runner labels and group access. Assistance uses labels as a user-facing contract: a workflow asks for a capability, not for a specific machine.

Example label patterns:

LabelIntended meaning
self-hostedRequired GitHub marker for self-hosted runners
assistanceRunner capacity operated by Assistance
linux or windowsOperating system family
x64 or arm64Architecture
standard, large, gpuSize or accelerator profile
prod-deployRestricted deployment runner with approved network access
private-networkRunner can reach agreed internal services

A typical production-safe pattern is to give build/test jobs broad labels and deployment jobs restricted labels. Do not put secrets, customer names, or sensitive infrastructure details in labels.

Ephemeral and persistent runners#

Assistance will document whether each runner profile is ephemeral or persistent.

ModeWhat it meansWhen to use itTrade-offs
Ephemeral runnerA fresh runner handles one job and is destroyed or reset after completionUntrusted pull requests, secrets-heavy builds, production deploys, regulated workloadsStrong isolation; may need additional cache design to keep jobs fast
Persistent runnerA runner process remains available for multiple jobsLow-risk internal jobs, fixed hardware, very large local caches, specialized devicesFaster warm state; requires stronger cleanup, patching, and drift controls

Assistance prefers ephemeral runners for jobs that handle secrets, production credentials, customer data, or private network access. Persistent runners are only used when the workload requires them and the cleanup, monitoring, and access model is explicit.

Workflow examples#

Route a job to Assistance managed runners#

yaml
1
name: ci
2
3
on:
4
pull_request:
5
push:
6
branches: [main]
7
8
jobs:
9
test:
10
runs-on: [self-hosted, assistance, linux, x64, standard]
11
steps:
12
- uses: actions/checkout@v4
13
- uses: actions/setup-node@v4
14
with:
15
node-version: '22'
16
cache: 'pnpm'
17
- run: corepack enable
18
- run: pnpm install --frozen-lockfile
19
- run: pnpm test

Use a restricted deployment runner#

yaml
1
name: deploy
2
3
on:
4
push:
5
branches: [main]
6
7
permissions:
8
contents: read
9
id-token: write
10
11
environment: production
12
13
jobs:
14
deploy:
15
runs-on: [self-hosted, assistance, linux, x64, prod-deploy, private-network]
16
steps:
17
- uses: actions/checkout@v4
18
- name: Authenticate with cloud provider
19
run: ./scripts/authenticate-with-oidc.sh
20
- name: Deploy
21
run: ./scripts/deploy.sh

Use GitHub Environments, required reviewers, and branch protection for production deployments. The runner label alone is not an approval control.

Permissions, OIDC, and secrets#

Self-hosted runners should not be treated as a reason to broaden workflow credentials. Keep job permissions explicit and minimal.

Recommended user practices:

  • set permissions: at workflow or job level instead of relying on defaults;
  • prefer OpenID Connect (OIDC) federation to long-lived cloud keys when the cloud provider supports it;
  • store repository, organization, and environment secrets in the narrowest GitHub scope that works;
  • use GitHub Environments for production secrets, approvals, and deployment history;
  • avoid printing secrets, tokens, private URLs, or full environment dumps in job logs;
  • do not run unreviewed fork pull-request code on runners that can reach secrets or private networks.

Assistance can help design the OIDC trust relationship, runner network boundary, secret naming convention, and evidence needed for access review. The customer remains responsible for approving who can create workflows, approve deployments, and access protected secrets.

Caching and artifacts#

Managed runners can improve performance, but cache behavior must match the runner mode.

NeedRecommended approach
Dependency cacheUse actions/cache or tool-specific cache support such as actions/setup-node with cache:
Build artifactsUse actions/upload-artifact and actions/download-artifact for handoff between jobs
Docker layersUse a documented registry or build-cache backend; avoid relying on undeclared local daemon state
Ephemeral runnersExpect local disk to disappear after the job; use remote caches for reusable state
Persistent runnersDocument cleanup rules, maximum cache size, and when stale state is purged

Example dependency cache:

yaml
1
- uses: actions/setup-node@v4
2
with:
3
node-version: '22'
4
cache: 'pnpm'
5
- run: pnpm install --frozen-lockfile

Cache keys must not include secrets. Artifacts should have retention periods appropriate to the data they contain.

Private network access#

A major reason to use managed runners is controlled access to private services: package registries, databases used for integration tests, internal APIs, artifact repositories, Kubernetes clusters, or deployment targets.

Before enabling private access, confirm:

  • which repositories and branches need the access;
  • whether access is read-only, deploy-only, or administrative;
  • whether the runner can reach production, staging, or only isolated build services;
  • what source IPs, security groups, firewall rules, VPNs, or private links are required;
  • what logs prove that access was used as intended;
  • how access is revoked during an incident.

Private access should be attached to restricted runner groups and labels. Avoid giving generic build runners broad network paths to production.

Registration and token handling#

GitHub runner registration uses short-lived registration tokens generated from repository, organization, or enterprise settings/API. These tokens allow a runner to attach to GitHub and must be treated as sensitive during provisioning.

Assistance handles registration tokens according to the agreed operating boundary:

  • tokens are generated only when a runner is being registered or replaced;
  • tokens are not committed to repositories, copied into tickets, or reused as long-lived credentials;
  • runner names, groups, and labels are recorded in the customer runbook;
  • decommissioned runners are removed from GitHub and from the underlying infrastructure;
  • emergency revocation steps are documented for suspected compromise.

Customers should grant Assistance only the administrative access needed to register and operate the agreed runners, or provide registration tokens through an approved secure channel when Assistance does not hold platform admin access.

Maintenance and operations#

Assistance managed GitHub Actions runners include an agreed day-2 operating model. The exact scope depends on the statement of work or support agreement, but typical operational activities include:

  • operating system and runner binary updates;
  • base image and toolchain refreshes;
  • capacity, queue-time, failure-rate, and utilization monitoring;
  • log and metric review for runner health;
  • cache cleanup and disk pressure handling;
  • label, group, and repository access changes through approved requests;
  • incident triage and provider escalation when GitHub platform behavior is involved;
  • periodic review of security posture, labels, secrets, and network access.

See Runner monitoring and support for the support workflow and Troubleshooting for escalation inputs.

Troubleshooting quick checks#

SymptomWhat to check firstLikely owner
Job waits for a runnerruns-on labels, runner group repository access, online runner capacity, concurrency limitsAssistance for capacity/config; customer for workflow labels
Job starts on the wrong profileLabel mismatch or overly broad labelsCustomer updates workflow; Assistance adjusts label contract if needed
Secret is emptyGitHub secret scope, environment protection, branch rules, fork PR restrictionsCustomer repository/platform owner
OIDC authentication failspermissions: id-token: write, trust policy audience/subject, branch/environment conditionsShared: customer cloud owner and Assistance platform support
Private endpoint is unreachableRunner network route, firewall allowlist, DNS, VPN/private link, target service healthAssistance for runner path; customer for target service unless contracted
Cache misses unexpectedlycache key, branch restore keys, runner mode, retention policyCustomer workflow owner with Assistance advice
Disk fills upartifact/cache size, Docker layers, persistent runner cleanup scheduleAssistance for runner operations; customer for job behavior
Runner shows offlinehost health, runner service, GitHub connectivity, registration stateAssistance

When opening a support request, include the repository, workflow run URL, job name, runner labels, approximate time, recent changes, and business impact. Do not paste secrets or registration tokens into tickets.

Migration from GitHub-hosted runners#

A safe migration is incremental. Assistance normally recommends:

  1. Inventory workflows — capture current runs-on, duration, failure rate, cache use, secrets, environments, and private-network needs.
  2. Select pilot jobs — start with high-cost or slow jobs that do not deploy to production.
  3. Define labels — map GitHub-hosted labels such as ubuntu-latest to Assistance labels such as [self-hosted, assistance, linux, x64, standard].
  4. Run in parallel where possible — compare duration, logs, cache behavior, and failure patterns.
  5. Move privileged jobs last — production deployments need environment approvals, OIDC/secrets review, and restricted runner groups.
  6. Document rollback — keep a tested path back to GitHub-hosted runners or an alternate managed profile until the migration is accepted.
  7. Review after rollout — compare queue time, spend, reliability, and support load.

Not every workflow should move. GitHub-hosted runners may remain appropriate for simple public CI, low-volume repositories, or workloads that do not justify a managed operating surface.

EU security and compliance notes#

Assistance can design runners to support EU-aligned operating requirements, but the exact legal position depends on the customer, data, vendors, and contracts.

User-facing points to confirm during onboarding:

  • runner region and hosting model, including whether compute runs in customer cloud, Assistance-managed infrastructure, or a hybrid design;
  • whether source code, artifacts, logs, caches, and telemetry remain inside agreed EU locations;
  • data classification for build inputs, artifacts, logs, and test data;
  • access-review cadence for GitHub admins, environment approvers, cloud roles, and Assistance operators;
  • evidence retained for changes, incidents, runner registration, secrets review, and patching;
  • subprocessors and SaaS services involved, including GitHub and any external cache, artifact, or monitoring services.

Assistance can provide technical evidence, hardening recommendations, and operational records. Legal determinations, regulatory filings, and formal compliance guarantees must come from the customer's legal/compliance process or from an explicit contractual commitment.

Customer and Assistance responsibilities#

AreaAssistance typically operatesCustomer typically owns
Runner infrastructureProvisioning, scaling, patching, monitoring, replacement, decommissioningApproving hosting model, cost limits, and production impact
GitHub configurationRunner groups/labels within delegated access, registration workflow, support notesRepository/org/enterprise permissions, branch protection, environments, approvers
WorkflowsReview and recommended changes when in scopeJob logic, test commands, deployment scripts, application behavior
Secrets and identityOIDC design support, secret-boundary recommendations, rotation runbooksSecret values, cloud IAM approvals, access grants, data classification
Network accessRunner-side network path, firewall requests, connectivity troubleshootingTarget service ownership, production access approvals, business risk acceptance
Compliance evidenceOperational logs, change records, maintenance notes, technical evidenceLegal interpretation, audit submissions, regulatory responsibility

Getting started#

Open an onboarding or support request with the GitHub scope, repositories, required labels, security constraints, network needs, deadline, and current workflow examples. Assistance will confirm the operating boundary before registering runners or making production-impacting changes.