Threat Modelling Framework For CI/CD Pipelines
Protect the crown jewels at the heart of your software delivery
Background
CI/CD pipelines are a foundation of modern software delivery. To ship high quality products, builder teams need fast and reliable feedback, which is enabled through CI automation. When done well, CI/CD automation strengthens security by limiting ad-hoc access to production environments and enabling repeatable deployments.
At the same time, CI/CD pipelines are becoming of the the most attractive targets for threat actors, driven by the fact that they enable privileged access to production environments. A holistic product security program must carefully consider CI/CD pipelines as part of the threat landscape.
Over the last 2 years, I’ve spent a considerable amount of time thinking about and improving security of our CI/CD configurations. This post outlines my mental model that was formed by that work and a practical threat modelling framework for CI/CD pipelines.
Table Stakes
Before diving into the framework, I want to call out 2 baseline assumptions. These are foundational security considerations, but they are broad enough and depend on specific tech stack:
Ephemeral, locked down runners. In my view, relying on persistent runners is a major security liability. Reliably isolating pipeline runs on a long-lived runner is extremely difficult, if not impossible. Whenever feasible, I avoid using persistent runners, and I do not cover any related issues below.
CI/CD VCS credentials. How your CI/CD pipeline accesses your version control system (VCS) depends on the type of CI/CD tool you use. For the purposes of this framework, I assume that CI/CD access to the VCS is configured using a secure mechanism, recommended by your platform.
The Framework
CI/CD workflows are, generally, a set of steps that are executed on some trigger:
The steps could be things like cloning a source code repository, running builds, running tests, running security scans, publishing build artifacts, deploying to test or production environments, etc. This picture is obviously an oversimplification, but it’s good enough for our purposes.
We need consider the pipeline end to end, from the inputs and triggers to the first step, to the outputs (build artifacts, deployments etc.) of the final step. We can then use the following questions to guide the creation of a threat model.
At the whole pipeline level:
Workflow triggers
What are the triggers for the workflow?
Can the workflow be triggered manually, and if yes by whom?
Can the workflow be triggered by unreviewed code changes (i.e. from unprotected branches)?
Workflow definition
Where is the workflow defined and who can modify it?
If the workflow is defined in the same repository on which it is executed, it is important to understand whether the workflow definition comes from a predefined protected branch, or from the branch on which the workflow is executed. The latter is the case for GitHub Actions and means that anybody with write access to the branch can modify the workflow!
Assume anybody who can controls the workflow has full access to the workflow secrets and credentials (see below)!
For each of the steps individually:
Inputs
Where do the workflow inputs come from and who can control those inputs? The answer to this is not obvious, consider these:
Branch and tag names could be used in the step logic (i.e. are inputs).
Similarly, pull request titles are often used as inputs.
Branch protection
How “trusted” in the source code that is used for the step execution?
If the workflow can be executed on an unprotected branch, the source code is fully controlled by the developer who created the branch and might not have been reviewed.
For protected branches, also consider who is able to bypass the branch protection rules.
Secrets
What secrets and credentials are exposed to the workflow and what level of access do they provide?
This drives a big part of the potential impact of a security incident involving the workflow.
If some secrets are defined but not “injected” into the workflow, consider whether that can be changed by a threat actor.
Consider credentials for both deployment environments as well as VCS (version control system, i.e. source code repository) credentials. VCS credentials might have permissions not normally available to , like ability to bypass branch protection rules.
Consider both long lived and short lived (eg. OIDC) credentials. Just the fact that the credentials are short lived, doesn’t make them immune to compromise, just reduces the window of exposure.
Workflow code
CI/CD tools are essentially “code execution as a service”. What does the step do, and who can affect what is executed as part of the step?
Example: running unit tests in most cases executes arbitrary code from the repository.
Consider injection issues. As a GitHub Actions specific example, a simple
echo “${{ github.event.pull_request.title }}”can turn into arbitrary code execution.
Third party dependencies
What third party dependencies do you have for the step?
Are you comfortable trusting the author(s) of that dependency?
Is it pinned to specific hash? (Can help with some scenarios where the dependency is compromised)
I found answering to these questions drives creation of threat scenarios that are relevant to your configuration, for example:
A third party dependency is compromised and a new, malicious, version is published.
A developer bypasses branch protection rules by modifying the workflow to use VCS credentials available to the workflow to approve their own PR.
Conclusions
I’m a big believer that getting the fundamentals right has a much bigger impact on security than shiny new tools, and hence should come first. The best way to secure your CI/CD pipelines is to start with a threat model created by engineers that intimately know your configuration.
This framework intentionally focuses on the CI/CD pipelines and workflows and doesn’t cover other product security risk areas. It offers a series of questions that surface common attack vectors, prompt meaningful discussions about pipeline configurations, and help create threat scenarios tailored to your environment.
I would love to evolve this approach further, please reach out if you have any feedback or comments. Happy threat modelling!



