Security

Follow one job through Overline.

CI runs your code with your secrets, so "trust us" isn't enough. Here is every step a job takes, from the moment you push to the moment its machine is gone, and what protects it at each one.

In short
  • Every job runs in its own VM, deleted when it ends.
  • Jobs can't reach each other or anything else on our hosts.
  • Secrets go from GitHub straight to your job.
  • The GitHub App has three permissions and can't read your code.
  1. Step 01

    You push, and GitHub tells us

    When a job asks for runs-on: overline, GitHub sends our GitHub App an event. That event is the only way a job reaches us, so we check that it really came from GitHub.

    • Every event is verified against its HMAC-SHA256 signature. Unsigned or altered requests are rejected before anything runs.
    • We act as a GitHub App with installation tokens that expire within the hour, never a personal access token.
    WebhookSignature verified
    GitHubOverline · Signed
    Anyone elseRejected
    GitHub
    Signs every event
    Overline
    Checks it first
    Anyone else
    Rejected
  2. Step 02

    We register a one-time runner

    For each job we ask GitHub for a runner registration that can only ever run one job, and hand it to a single machine.

    • The registration is single-use: after one job it can't pick up another, not even another of yours.
    • Only the machine it was made for can collect it, using a random token unique to that machine.
    Runner registrationSingle use
    RegistrationJob machine
    RegistrationAlready used
    Registration
    One job only
    Collected by
    One machine
    Afterwards
    Can't run again
  3. Step 03

    Your job gets a fresh machine

    The job runs inside its own virtual machine, isolated from other jobs at the hardware level, not in a container sharing a kernel.

    • Each machine has its own kernel, 2 vCPUs and 8 GB of memory.
    • It boots from a read-only base image; everything the job writes goes to a disk created for that job alone.
    • We rebuild the base image regularly with the latest Ubuntu security updates.
    Job machine2 vCPU · 8 GB
    Job machine
    KernelOwn
    Base imageRead-only
    Job diskThis job only
    Kernel
    Its own
    Base image
    Read-only
    Disk
    This job only
  4. Step 04

    It runs on its own network

    Every machine gets a private network of its own. Your job can reach the internet like it would on GitHub, and nothing else.

    • Traffic between machines is dropped, so one job can't see another.
    • From inside a job, a single port on the host is reachable, and every request to it must be authenticated. Nothing else on our servers is.
    NetworkOne per job
    Internet
    Job 1
    Net 1
    Job 2
    Net 2
    Job 3
    Net 3
    Internet
    Reachable
    Other jobs
    Dropped
    Our host
    One port
  5. Step 05

    Your secrets and logs

    Secrets are part of the job GitHub sends to the runner inside the machine. They take the direct route, and we keep them out of what we store.

    • GitHub sends secrets over an encrypted connection straight to the runner; our servers never see them.
    • Logs go through the same secret masking as GitHub's own runners before they're written.
    • Logs and CPU/memory are stored for your dashboard, which requires authentication to view.
    SecretsNever on our servers
    GitHubYour job
    Our serversNo access
    log API_KEY=***
    From
    GitHub
    Straight to
    Your job
    Logs
    Masked
  6. Step 06

    The job ends, and the machine is gone

    When the job finishes, everything it touched is deleted. The next job, yours or anyone's, starts from the clean image.

    • The machine and its disk are deleted as soon as the job ends.
    • Its runner registration is already used up, so nothing can run on it again.
    After the jobDeleted
    Job machineDeleted
    Next jobFresh machine
    Machine
    Deleted
    Disk
    Deleted
    Next job
    Clean image

Permissions

Everything the GitHub App can do.

This is the complete list. The app can't read your code, your secrets, pull requests or issues.

PermissionAccessWhy
Self-hosted runnersread & writeRegister a single-use runner for each job, at the organization level.
ActionsreadReceive job events and show job and step status in the dashboard.
MetadatareadRequired by GitHub for every app.