Security
How RunsOn protects code, secrets, and runner state — shared model for Flex and Fleet, with the small differences in GitHub boundary spelled out.
RunsOn handles security differently from hosted runner SaaS products because the runtime path stays in your AWS account. This applies to both products:
- Flex — per-job ephemeral runners launched in response to GitHub webhooks.
- Fleet — ephemeral runners launched from a standardized catalog of runner fleets, fed by GitHub runner scale sets.
Both products spawn a fresh EC2 instance for every job. Neither runs your workflow on shared infrastructure. The only meaningful security difference between them is the GitHub boundary — how jobs reach the runners. That section is called out explicitly below.
Usage
Flex
Keep workflow permissions narrow and target an approved runner environment:
permissions: contents: read id-token: write
jobs: build: runs-on: runs-on=${{ github.run_id }}/runner=2cpu-linux-x64/env=productionFleet
For Fleet, runner groups make the GitHub access boundary explicit:
resource "github_actions_runner_group" "ci" { name = "ci-runners" visibility = "selected" selected_repository_ids = [github_repository.app.repo_id]}
fleets = { linux-ci = { runner = "small-x64" runner_group = github_actions_runner_group.ci.name }}See networking, environments, and Fleet runner groups for the controls that shape the security boundary.
High-level guarantees
For both Flex and Fleet:
- Runner VMs are ephemeral EC2 instances and isolated by default — destroyed when the job finishes.
- Caches, logs, queues, and GitHub App credentials stay in your AWS account by default.
- The RunsOn control plane runs in your AWS account with a limited IAM role.
- RunsOn-side data flows are limited to license validation, product telemetry sent to
runs-on.com, and normal commercial or support communications.
The problem with self-hosted runners
People looking for cheaper or faster runners often choose one of the following routes:
- Keep using GitHub-hosted runners. Pay premium price, with limited access to more powerful instance types.
- Switch to a third-party SaaS like Namespace, Blacksmith or Warpbuild to get cheaper and more powerful self-hosted runners, but hand a third party access to code, secrets, and runtime data.
- Maintain a pool of long-lived self-hosted runners — patching drift, state leakage between jobs, and a much larger attack surface.
A design rule of RunsOn is that it always spawns a new runner for each workflow run. That makes job isolation straightforward and avoids persistent runner state leaking into later workflows. Since RunsOn and its runners live in your own AWS account, your code and secrets never move into a third-party shared runner control plane.
SSH access to runners can be restricted to a specific CIDR block, or disabled entirely.
Related concept pages: networking, images, integrations, and environments.
What stays in your AWS account
By default, the following remain in your environment for both Flex and Fleet:
- Runner VMs and workflow execution data.
- S3 cache contents and CloudWatch logs created by the deployed stack.
- Queue and state payloads used to coordinate job demand.
- Private GitHub App credentials (or enterprise PAT for Fleet enterprise mode) stored in AWS Secrets Manager.
- IAM roles used by the control plane and runner instances.
Runner EBS volumes are not encrypted at rest by default, since encryption slows instance boot. Set the EncryptEbs=true stack parameter to encrypt them with the alias/aws/ebs KMS key.
Public base images (AMIs)
RunsOn maintains public AMIs for the base images used by both Flex and Fleet runners, in each region where RunsOn is officially available. These images are built from the public runner-images-for-aws ↗ repository and updated within at most 15 days of an official new release by GitHub.
Published base AMIs are inspected nightly with Amazon Inspector EC2 scanning for newly disclosed CVEs and related image findings.
For maximum supply-chain control, you can build your own images from the provided templates or generate entirely custom AMIs.
RunsOn control plane
The control plane is deployed from a Docker image built by RunsOn and published in a public ECR registry. It runs in your AWS account on ECS/Fargate with a limited IAM role — same runtime for both Flex (the webhook-driven worker) and Fleet (fleetd).
The control plane validates the RunsOn license against a runs-on.com API endpoint. That request includes the GitHub organization (or enterprise name), AWS region, license key, and app version needed for the license check.
GitHub boundary
This is where Flex and Fleet differ — the only meaningful security difference between the two products.
| Aspect | Flex | Fleet |
|---|---|---|
| Direction | Push (webhook) | Pull (fleetd polls scale-set demand) |
| Public ingress | API Gateway + Lambda | None |
| WAF | ✓ (GitHub IP ranges) | n/a |
| Access boundary | Stack environment + job labels | GitHub runner groups |
| Workflow can mutate runtime shape | ✓ via labels | — (runner fleet settings stay in Terraform) |
Flex — webhook ingress
Flex is push-based. Public setup, health-check, and webhook traffic reaches the stack through API Gateway and Lambda ingress. GitHub posts workflow_job events to that endpoint, and the Flex control plane decides whether to launch a runner.
After setup, the public admin/setup routes can be disabled with EnableAdminRoutes=false. You can also enable the built-in WAF with EnableWAF=true, which attaches the RunsOn-managed Web ACL for the public ingress and limits webhook traffic to GitHub’s published IP ranges.
Per-job labels in workflow YAML pick the runner shape, image, and extras.
Fleet — pull-based, no inbound webhooks
Fleet is pull-based. fleetd does not receive GitHub webhooks. It pulls organization or enterprise scale-set demand from GitHub, claims jobs, and launches runners from fixed Terraform-reviewed fleet settings.
Network policy can focus on outbound access from fleetd to GitHub and AWS APIs, plus the normal runner-registration path from ephemeral EC2 runners. There is no public ingress endpoint to harden.
Fleet runs one active GitHub boundary per runtime, in one of two modes:
- Organization mode — one GitHub organization owns the repositories that can use Fleet. The GitHub App needs organization self-hosted runner write access.
- Enterprise mode — one enterprise runner group serves multiple organizations. Uses a classic PAT with enterprise runner management permission.
Within either mode, GitHub runner groups are the access boundary. Runner groups decide which repositories, organizations, and workflows can target a runner fleet. Treat runner groups as the GitHub access boundary and runner fleets as the AWS capacity boundary. Use separate runner groups when the access policy, network policy, or IAM blast radius differs.
Workflow authors can target an approved runner fleet but cannot mutate the runner fleet’s underlying settings from workflow YAML — runner policy stays with the platform team.
See the Fleet installation guide for the concrete Terraform inputs and Fleet networking and IAM for the network controls.
RunsOn agent telemetry
A small agent runs on the EC2 instances launched by both Flex and Fleet. It improves boot behavior and handles metadata generation, spot interruption handling, and workflow lifecycle on the runner.
When the agent starts on a newly launched runner, it sends limited technical telemetry to a runs-on.com API endpoint. The event fires per runner launch — in normal operation one per GitHub Actions job — which is also what RunsOn uses to measure monthly runner volume for licensing:
- Current time, org or account identifier, app version, AWS region, platform, instance architecture, instance type, instance lifecycle, instance boot timings.
- Whether the stack uses private networking, whether it targets GitHub Enterprise Server, enabled integrations, networking stack, enabled extras, pool metadata when applicable.
This telemetry is used to understand product usage, administer licensing and usage limits, and improve compatibility, performance, and reliability. It is not in the main workflow execution path and does not by default include repository contents, secrets, or runner filesystem contents.
RunsOn-side security controls and vendor roles
RunsOn-side systems only handle limited data flows compared with the core product runtime:
- HTTPS/TLS is used for the telemetry and license-validation endpoints.
- Access to support materials is intended to be limited to authorized personnel with a need to know.
Current public procurement documents:
Supply-chain and service risks
Main risks and corresponding mitigations:
- Malicious code injected into the base AMIs — audit the published AMIs or build your own from the provided templates.
- Malicious code injected into the control plane (Flex worker or
fleetd) — audit the source or images available under the relevant license model, or rebuild and publish your own image. - Malicious code injected into the agent component — audit the source or published artifacts and, if needed, rebuild for your own images.
- Compromise of the limited
runs-on.comservices used for telemetry or license validation — these flows are separate from the core runner execution path in your AWS account. - (Flex only) Compromise of the public ingress endpoint in your AWS account — the endpoint is internet-facing to receive GitHub webhooks, but the deployed control plane uses limited IAM roles; after setup you can disable public setup routes and enable the managed WAF so webhook access is restricted to GitHub IP ranges.
Vulnerability reporting
Report suspected vulnerabilities to security@runs-on.com. Please include:
- affected RunsOn version;
- deployment model and relevant configuration;
- reproduction steps;
- impact assessment;
- logs or screenshots with secrets removed;
- preferred contact details.
Do not access, modify, delete, or exfiltrate data that does not belong to you. Do not perform denial-of-service testing, social engineering, physical attacks, or attacks against third-party services.
RunsOn aims to acknowledge vulnerability reports within five (5) business days.
Safe harbor
RunsOn will not pursue legal action against security researchers who make a good-faith vulnerability report and comply with the rules above. This safe harbor does not apply to unlawful activity, extortion, privacy violations, data exfiltration, persistence, denial-of-service activity, social engineering, physical attacks, or attacks against third-party services.
Conclusion
RunsOn’s security model starts with keeping the workload path in your infrastructure and keeping RunsOn-side processing narrow. Flex and Fleet share the same runner-isolation, AMI, telemetry, and IAM model — they differ only in how GitHub reaches the runners. If anything here is unclear or you need a procurement answer tied to a specific data flow, contact ops@runs-on.com.