Skip to main content
RunBook Academy

Git, CI/CD & GitOpsCXVIII · Final Reference ArchitectureCI

The GitHub Actions control plane — the CI fleet

Advanced⏱ ~26 mingitgh

What you'll learn

  • Identify the four primitives a production Actions fleet depends on: reusable workflows, composite actions, environment protection rules, and OIDC tokens
  • Distinguish the Actions control plane (GitHub) from the runner fleet (customer-operated)
  • Recognise why environment protection rules are the only admission-control mechanism built into the CI plane
  • Configure an Actions workflow that authenticates to the cloud with an OIDC token scoped by sub and aud

Prerequisites

Verified against Git 2.55.x teaching target; 2.40+ minimum · GitHub Actions continuous service; Aug 2026 documentation baseline · Argo CD v3.5.x teaching target; v3.0+ minimum · Flux v2.9.x · Sigstore Cosign v3.1.x · SLSA v1.2 · OCI Distribution Specification v1.1 · Git LFS v3.7.1 · Kubernetes (cross-course target) 1.36.x

Not yet marked complete on this device.

The Actions fleet is the CI control plane this course is written against: workflows, reusable workflows, composite actions, environment protection rules, OIDC tokens, and the runner fleet that executes them. Treating Actions as a fleet - with named owners, an SLA, and a backlog - is what turns CI from “scripts in .github/workflows” into the admission-control plane for every artefact the rest of the system deploys.

The four primitives

A production Actions fleet depends on four primitives. Forgetting any one of them turns the CI plane into a place where scripts can run but no one can prove what they did.

flowchart LR
    WF["Reusable workflow"] -->|"calls"| CA["Composite action"]
    CA -->|"runs on"| RUN["Ephemeral runner"]
    RUN -->|"emits OIDC token"| WF
    WF -->|"targets"| ENV["Environment with protection rules"]
    ENV -->|"gates"| DEPLOY["Deploy step"]
  • Reusable workflows. A workflow that is called by other workflows with a typed contract. The reusable workflow defines what inputs are accepted, what secrets are required, and what outputs are produced. Production teams maintain one reusable workflow per pipeline shape
    • build, test, deploy, plan - and call it from every application repo rather than copying the steps.
  • Composite actions. A bundle of steps that runs on the same runner and shares environment. Used for cross-cutting concerns: setting up a toolchain, signing an artefact, configuring a registry login.
  • Environments and protection rules. An environment is a named target with required reviewers, wait timers, and branch restrictions. The only built-in admission-control mechanism in Actions; the gate every production deploy passes through.
  • OIDC tokens. A short-lived identity issued by GitHub to the running workflow, scoped to the repository, the workflow, and the environment. The only way a production workflow should authenticate to a cloud; the alternative - long-lived secrets - is what collapses B2 and B5 into one identity.

The control plane is separate from the fleet

GitHub operates the Actions control plane: the workflow runtime, the secret store, the OIDC issuer, the protection rules. The customer operates the runner fleet: the machines that execute the steps. The split is deliberate. A team that relies entirely on GitHub-hosted runners has outsourced execution but still owns the workflow definition; a team that runs self-hosted runners owns execution as well.

The split has three consequences:

  • Trust is not uniform. The workflow definition is trusted by GitHub’s controls; the runner is trusted by the customer’s controls. The two together make the audit chain.
  • Pinning the runner image is the customer’s job. GitHub-hosted runners are pinned by GitHub; customer runners are pinned by the image the team builds, which is the topic of the runner-fleet lesson.
  • OIDC token issuance is the control plane’s job. Anyone who can edit a workflow in the repo can cause an OIDC token to be issued; the trust placed in the workflow definition is therefore the trust placed in the people who can edit it. Branch protection is part of the fleet, not just the source plane.

Operating the fleet

The Actions fleet is operated as a product. Three operational patterns recur in mature organisations:

  • One reusable workflow per pipeline shape. Build, test, plan, deploy. Application repos call into them by name; no application repo defines its own build steps from scratch.
  • Environments map to deploy targets. An environment named production carries a required reviewer list and a wait timer; an environment named staging carries no wait timer but is restricted to the main branch.
  • OIDC audiences are namespaced. One IAM role per environment; the audience claim of the OIDC token selects the role. A workflow with audience aws:prod cannot assume the aws:staging role.
echo "Inspect the OIDC token issued to a workflow run:"
gh run view "$RUN_ID" --json jobs \
  | jq '.jobs[].steps[] | select(.name=="Configure AWS credentials") | .conclusion'

The configuration above uses gh run view and jq; both are first-class citizens of the Actions fleet on a production engineer’s laptop.

Production discipline

  1. Reusable workflows for everything that is cross-repo. Copying a workflow is a future incident waiting to happen.
  2. Environments for everything that is high-blast-radius. A production deploy that does not pass through an environment with required reviewers is a deploy that cannot be gated after the fact.
  3. OIDC audiences for everything that touches the cloud. A long-lived cloud credential in the Actions secrets is a B2/B5 violation waiting to be exploited.

Cross-course references

  • This course, Part XIV (ReusableWorkflows) - the pattern this lesson applies at fleet scale.
  • This course, Part XXIII (OIDC) - the trust mechanism the fleet standardises on.
  • GitHub Docs - security hardening for Actions - the fleet hardening checklist.

Quiz

Knowledge check · 4 questions

  1. Q1. A team uses GitHub Actions for both staging and production. They store one long-lived AWS access key in the repo secrets and use it from a single workflow with environment variables to choose the role. What is the audit failure?

  2. Q2. Environment protection rules in GitHub Actions are the only built-in admission-control mechanism for production deploys and are sufficient on their own if reviewers and wait timers are configured.

  3. Q3. Name the four primitives a production Actions fleet depends on, and explain why a workflow that defines its own build steps from scratch, instead of calling a reusable one, is a fleet-violation.

  4. Q4. Redesign the Actions fleet so that the audit chain is intact and the cloud credentials are short-lived.

    A team has 40 application repositories. Each one defines its own build workflow inline in `.github/workflows/build.yml`. The same workflow file is copied and edited 40 times. The cloud credential is a long-lived AWS access key in the repo secrets. There is no production environment; staging and production are deployed by the same workflow with environment variables. Three of the 40 builds have introduced supply-chain vulnerabilities that were patched in only some of the copies.

Passing score: 75%. Answers are checked in this browser.