All knowledge articles

Threat Modeling a CI/CD Pipeline

A structured method for threat modeling a CI/CD pipeline's trust boundaries — from commit to deployment — using a fictional example pipeline.

Threat ModelingCI/CD PipelinesSupply Chain Security

A CI/CD pipeline is not a single system to secure — it is a chain of trust decisions, each one inherited by the stage after it. Threat modeling a pipeline means treating every handoff (commit to build, build to artifact, artifact to deployment) as a boundary that must justify the trust it extends, rather than treating the pipeline as one black box that either 'has security' or doesn't.

Fictional CI/CD pipeline trust boundariesA developer commits to source control, which triggers a build runner, which publishes to an artifact registry, which deploys to a target environment. Interactive: switch between the normal build/deploy flow and a failure mode showing how a compromised dependency can inject code into the build runner, and explore each node's role in the trust boundary.DeveloperSourcecontrolCompromiseddependencyBuildrunnerArtifactregistryDeploymenttarget

Hover or focus a node to explore it.

Fictional pipeline: developer → source control → build runner → artifact registry → deployment target. In the failure mode, a compromised dependency injects code during the build; the artifact registry's provenance check is the boundary that decides whether the tainted artifact ever reaches deployment.
01

Executive summary

This guide walks through threat modeling a fictional pipeline — developer commit, source control, build runner, artifact registry, deployment target — using a repeatable method: enumerate boundaries, ask what enforces each one, trace the worst case forward, and record the outcome as a mitigation, a plan, or an accepted risk. The example pipeline and every identifier in it are fictional; no real repository, credentials, or production system is described.

02

What you will learn

  • How to decompose a CI/CD pipeline into trust boundaries instead of treating it as a single unit.
  • A repeatable threat-enumeration method (assets, boundaries, threats, mitigations, residual risk) applied to a concrete fictional pipeline.
  • Why the artifact registry's verification step is usually the last meaningful checkpoint before a compromised build reaches production, and what 'meaningful' requires of it.
  • How to record findings so that 'we haven't checked' and 'we checked and it's fine' don't get collapsed into the same status.
03

Intended audience

  • Developers who maintain or depend on a CI/CD pipeline and want to reason about what it actually trusts.
  • DevOps practitioners responsible for runner configuration, artifact promotion, and deployment gating.
  • Security engineers supporting a supply-chain or pipeline-hardening review.
04

Problem or security question

It is common to secure the parts of a pipeline that are easiest to see — a linter here, a dependency scanner there — while leaving the trust relationships between stages unexamined. A pipeline can pass every individual scan and still have no enforced boundary between 'a build ran' and 'this specific build is safe to deploy.' Threat modeling closes that gap by asking, stage by stage, what would have to be true for an attacker to move from one boundary to the next.

The risk is not hypothetical in shape, even in a fictional illustration: a build runner typically has more reach than any single stage's obvious purpose suggests — network egress to fetch dependencies, short-lived credentials to publish results, and often a wider blast radius than the team maintaining it has actually inventoried.

05

Threat model or relevant risk

Assets: the source-control history and its integrity, the build runner's execution environment and credentials, the artifact registry's record of what was actually built and by what process, and the deployment target's running state.

Trust boundaries, in order: developer workstation → source control (first boundary — is this commit legitimate and reviewed), source control → build runner (second boundary — does triggering a build require anything beyond a plausible-looking event), build runner → artifact registry (third boundary — is the published artifact actually what the runner claims to have built), and artifact registry → deployment target (fourth boundary — is a request to deploy verified against the same evidence).

Representative threats: an attacker who can push directly to a protected branch bypasses the first boundary entirely. A compromised or dependency-confused third-party package executes attacker code inside the build runner during a routine build. A build runner with standing (not job-scoped) credentials lets a single compromised build reach far more than that build's own artifact. An artifact registry that stores builds without verifying their provenance turns 'the registry has the file' into a false signal of trust.

The interactive diagram accompanying this article shows the failure case concretely: a compromised dependency reaches the build runner during a normal-looking build, and the artifact registry's provenance check is the boundary that decides whether that tainted artifact is ever eligible to reach the deployment target.

06

Main technical content

Start by drawing the pipeline as boundaries, not tools. It is tempting to threat model by product name — 'we use a build tool, a container registry, an orchestrator' — but a boundary-first view forces the useful question at each step: what is trusted here, and why. The fictional pipeline in this guide has four boundaries: source control, the build runner, the artifact registry, and the deployment target. A real pipeline may have more (a staging environment, a separate signing service) or fewer, but the method is the same regardless of stage count.

At the source-control boundary, the question is whether a commit's presence in the trigger branch is meaningful evidence of review. Branch protection that the author of a change can disable, or that accepts unsigned commits from any authenticated identity, provides less assurance than its configuration screen suggests. This boundary matters disproportionately because every downstream stage inherits whatever it lets through.

At the build-runner boundary, the central question is scope: what can this specific job reach that it does not need? A runner with broad network egress can fetch a compromised dependency; a runner with standing credentials (rather than credentials minted fresh and narrowly scoped per job) turns a single compromised build into a much larger incident. Ephemeral, single-use runner environments reduce persistence risk — a compromise that doesn't survive past one job is a materially smaller problem than one that does.

At the artifact-registry boundary, the useful distinction is between a registry that stores artifacts and a registry that verifies them. Storage alone gives you a copy of whatever the build runner produced, trustworthy or not. Verification — checking that an artifact's provenance (source revision, build identity, and an intact signature) matches what was expected before allowing promotion — is what makes this boundary an actual control rather than a filing cabinet. This is also usually the last point where a compromised build can still be stopped before it reaches anything that matters.

At the deployment-target boundary, confirm that the deployment step itself re-checks verification rather than trusting that 'it's in the registry, so it must have passed.' A deployment process that pulls the newest artifact without re-validating provenance re-opens a boundary that the registry step just closed.

Throughout, separate what you have observed from what you have verified. A build runner reporting success, a registry accepting a push, or a deployment completing without error are all observations — none of them, on their own, is evidence that the relevant boundary actually enforced anything. Where you cannot test a boundary directly, say so and mark the finding UNVERIFIED rather than letting an unexamined assumption stand in for a checked control.

07

Requirements

  • A documented pipeline diagram (even a rough one) showing every stage from commit to running artifact, not just the parts a team happens to control.
  • Enough authority or influence to ask 'why' about each stage's trust decisions — a threat model that nobody with a mandate reads or acts on is a diagram, not a control.
  • A working definition of the pipeline's assets: what an attacker gains by compromising each stage (source, build-time secrets, the artifact itself, or the deployment target).
  • Willingness to record 'we don't know' as an explicit finding rather than assuming a control exists because a tool is installed.
08

Procedure

  • Draw the pipeline as a sequence of trust boundaries, not just a sequence of tools. For the fictional pipeline in this article, that is: developer workstation → source control → build runner → artifact registry → deployment target. Each arrow is a place where trust is extended, and each box is a place where it can be misused.
  • For each boundary, ask what currently enforces it and what evidence supports that. 'Branch protection is configured' is an observation; 'branch protection was tested by attempting a direct push and it was rejected' is evidence. Keep the two separate in your notes — the publication-safety policy's caution about not inferring effectiveness from a running process applies here too.
  • Enumerate realistic threats per boundary using a structured prompt (STRIDE, or simply 'what would a moderately resourced attacker who fully compromises this one stage be able to do next'). For a build runner specifically: can it read secrets it doesn't need, reach networks it doesn't need, or persist beyond a single job?
  • Trace the worst case for each threat forward to the deployment target. A compromised dependency that reaches the build runner is bad; a compromised dependency that reaches the build runner *and* the runner's output is trusted without verification is the difference between an incident and a non-event.
  • For every threat, record one of three outcomes: an existing mitigation with evidence, a planned mitigation with an owner and a date, or an accepted residual risk with a named approver. A threat model with no accepted-risk entries has usually just hidden them, not resolved them.
  • Re-run the exercise whenever a stage changes meaningfully — a new dependency source, a new runner type, a new deployment target, or a change to who can approve a merge. A threat model that was accurate at design time and never revisited degrades silently.
09

Validation

  • For each boundary, confirm the control fails closed: if the check cannot run (registry unreachable, signature service down, review system unavailable), does the pipeline stop, or does it proceed anyway?
  • For the source-control boundary, confirm review and branch-protection requirements cannot be bypassed by the same identity that authored the change.
  • For the build-runner boundary, confirm the runner's credentials and network reach are scoped to what that specific job needs, and that the runner environment does not persist state or secrets between unrelated jobs.
  • For the artifact-registry boundary, confirm that provenance or signature verification is enforced at the point of promotion or deployment, not merely available as an optional check a consumer could skip.
  • Where a control could not be tested (no lab environment, no authorized change to force a failure), record that explicitly as UNVERIFIED rather than assuming the control holds.
10

Rollback

  • If a review surfaces a boundary with no enforced control (for example, a build runner with standing production credentials or a registry that never checks provenance), do not silently tighten it in the same change — record the finding, assess blast radius, and route it through the team's normal change process so the fix itself gets reviewed.
  • If tightening a boundary breaks a legitimate workflow (for example, a stricter registry policy rejects a previously-accepted artifact type), have a documented, time-boxed exception path rather than disabling the control outright.
  • Keep the previous threat-model version alongside the new one when a review changes a finding's status — knowing that a risk was newly discovered versus newly accepted is different information for whoever inherits the pipeline next.
11

Validation or evidence

This article describes a method and a fictional illustrative pipeline; it does not reproduce a specific implementation or a completed assessment against a real system. Its evidence state is UNVERIFIED, and the recommendations should be treated as a starting checklist to adapt and then verify against your own pipeline, not as a validated result.

12

Limitations

The fictional pipeline used here is intentionally simple — four boundaries in a straight line. Real pipelines often branch (multiple deployment targets, parallel build jobs, promotion through several environments), and each additional path is its own boundary that this article's linear example does not walk through.

This guide covers pipeline-stage trust boundaries. It does not cover developer-endpoint security, identity-provider configuration, or cloud-account governance in depth — those are related but separate threat surfaces, each large enough for its own review.

A threat model is a snapshot. It goes stale the moment a stage changes meaningfully, and nothing in this article substitutes for revisiting it on that trigger.

13

Defensive recommendations

  • Require review and branch protection that the change's own author cannot bypass, and treat any bypass path as a finding, not an edge case.
  • Scope build-runner credentials and network egress to what each specific job needs; prefer short-lived, job-scoped credentials over standing ones.
  • Prefer ephemeral, single-use build environments over long-lived runners that persist state between unrelated jobs.
  • Enforce artifact provenance and signature verification at the point of promotion or deployment — not as an optional check a consumer may or may not run.
  • Make deployment re-validate provenance at deploy time rather than trusting registry presence alone.
  • Record every threat-model finding as mitigated-with-evidence, planned-with-an-owner, or accepted-with-a-named-approver — never leave a finding in an undocumented middle state.
  • Revisit the threat model whenever a pipeline stage changes meaningfully, not on a fixed calendar alone.
14

Key takeaways

  • Threat model the pipeline's trust boundaries, not its tool list — a boundary is where trust is extended and where it can be misused.
  • The build runner is usually the highest-value target; the artifact registry's verification step is usually the last meaningful checkpoint before deployment.
  • Separate observation from verification at every boundary, and record what you genuinely don't know as UNVERIFIED rather than assuming a control works.
  • A threat model is only useful if every finding resolves to a mitigation, a plan, or a named accepted risk — and if it gets revisited when the pipeline changes.
15

References

  • SLSA (Supply-chain Levels for Software Artifacts): https://slsa.dev/
  • OWASP Top 10 CI/CD Security Risks: https://owasp.org/www-project-top-10-ci-cd-security-risks/
  • NIST SP 800-218, Secure Software Development Framework: https://csrc.nist.gov/pubs/sp/800/218/final
  • CISA and NSA, Defending Continuous Integration/Continuous Delivery (CI/CD) Environments: https://www.cisa.gov/resources-tools/resources/defending-continuous-integrationcontinuous-delivery-cicd-environments