skip to content

Pipeline & Supply-Chain Security

Treating the pipeline itself as production infrastructure: least-privilege tokens, pinned dependencies, and provable provenance for what you ship. Increasingly asked because build systems are now the preferred way into an organisation.

on this pageshow

questions

6

Why is a CI/CD pipeline treated as production infrastructure rather than as a developer convenience, and what does that change about how you secure it?

level: juniorimportance: must knowfreq 48%

answer

  1. who else holds these credentials?
  2. nothing re-reads the build output
  3. building code means running code
  4. one build, many downstream consumers

basics

~10 s

A CI/CD pipeline holds the credentials that reach production and its output is deployed without anyone re-reading it, so compromising the build is equivalent to compromising every system that build can deploy to.

solid answer

~50 s

Three properties make the pipeline production. First, it holds the most privileged credentials in the organisation — deploy roles, registry push rights, signing keys — often broader than any single engineer's access. Second, its output is implicitly trusted: an artifact that comes out of CI is deployed without a second review, so anything injected during the build reaches production having passed no human eyes. Third, it executes third-party code by default — build plugins, shared build steps, packages with install hooks — on the machine holding those credentials. So the controls you would apply to a production host apply here: least-privilege, short-lived job credentials rather than one standing admin token; change control and audit on the pipeline definition itself; pinned, verifiable inputs; and isolation for anything that runs untrusted contributions. Attackers target build systems precisely because one compromise fans out to every downstream consumer.

go deeper

for a junior

Be able to say plainly that the build system holds deploy credentials and that whatever it produces goes to production without another review. Naming those two facts is most of the answer at this level.

for a middle

Explain the mechanics: which credentials a job actually receives, where third-party code enters a build, and why scoping tokens per job shrinks what a single compromised step can reach.

for a senior

Show you have operated this. Describe how you would inventory what a pipeline can reach today, split privileged steps away from untrusted input, and what your first move would be if a build machine were suspected compromised.

for a principal

Own the tradeoff between developer autonomy and build-system control: who may change pipeline definitions, whether teams may self-host runners, and how much friction the organisation will absorb for a given reduction in blast radius.

## The claim, stated precisely "The pipeline is production" is not a slogan about how important builds are. It is a statement about blast radius: if an attacker gets arbitrary code execution inside a build job, what do they get? For most organisations the honest answer is *more* than they would get from compromising any single production server, because the build machine can write to the thing every production server pulls from. ## Property 1: it is the most privileged identity you have To do its job, CI must be able to push container images or packages to a registry, read source, write status back to the repository host, and assume a cloud role that can change running infrastructure. Those permissions are usually granted once, broadly, at the project level, because scoping them per job is work. The result is a non-human identity with more standing authority than the engineers it serves, no MFA, and no one watching its login pattern. The corrective is ordinary least privilege applied to jobs rather than people: the job that runs unit tests needs no deploy credential at all; the job that publishes needs push rights to one repository, not to the registry; credentials should be minted per run and expire in minutes rather than living as static configuration. ## Property 2: its output is trusted without further review Code review inspects source. Deployment consumes *artifacts*. Between those two points sits the build, and nothing re-reads what it produced. A compiler flag flipped, an extra file copied into an image, a dependency swapped during resolution — none of it appears in any diff a human looks at. This is why supply-chain attacks aim at the build step specifically: it is the one place where you can change what ships without changing what was reviewed. The corrective is to make the artifact traceable back to a reviewed commit and a known builder, and to make the pipeline definition itself a reviewed, protected artifact rather than a file any branch can rewrite. ## Property 3: it runs other people's code as a matter of routine A typical build downloads and executes: a package manager's dependency tree (some of which run install-time scripts), reusable build steps published by strangers, a base container image, a tool installer fetched over HTTPS and piped straight into a shell, and the test suite of whatever branch triggered the run. Every one of those is code execution inside the credential-holding environment. "We only build code here" is false in a way that matters — building code *is* running code. ```bash # this is a remote code execution channel, not a download curl -fsSL https://tools.example.com/install.sh | sh ``` ## What changes in practice - **Treat job credentials like production credentials.** Scope per job, prefer short-lived tokens, and default the automatically-injected pipeline token to read-only, elevating only the one job that needs more. - **Put change control on the pipeline definition.** A change to the build is a change to production and deserves the same review and audit trail as a change to the deployment manifest. - **Pin what executes.** Mutable references — tags, branches, floating version ranges — let a third party change your build with no commit on your side. - **Separate the untrusted from the privileged.** Work that runs unreviewed contributions should run with nothing worth stealing; publishing and deploying belong to runs on trusted refs. - **Keep records.** Build logs, provenance and an inventory of what shipped are what make the difference between "we were affected" and "we cannot tell" during an incident. ## The framing an interviewer wants to hear Candidates who answer this well do not list tools. They say: the pipeline is where the organisation's trust boundary actually sits, because it is simultaneously the highest-privilege identity, the last unreviewed transformation before production, and a routine executor of third-party code. Security work on delivery is about reducing each of those three, not about bolting a scanner onto the end.

  • If the pipeline is production, what is the CI equivalent of the blast radius of a compromised production host?
    Larger, usually. A compromised host serves its own traffic; a compromised build writes the artifact every host pulls, so the compromise propagates on the next deploy and survives rebuilding the hosts. That asymmetry is why build systems are attractive targets and why recovery means rebuilding and re-verifying artifacts, not just replacing machines.
  • A team says their pipeline is safe because it runs on a private network. Why is that insufficient?
    Network position is not a trust boundary here. The dangerous code arrives through the front door — dependencies, build steps and the branch under test are all fetched and executed deliberately. Outbound egress from that private network is usually unrestricted, so exfiltration works fine. Network controls reduce exposure; they do not address code the build was told to run.
  • Which single control tends to give the biggest reduction in blast radius first?
    Removing standing high-privilege credentials from ordinary build jobs. Most pipelines give every job the same token, so a compromise anywhere is a compromise everywhere. Splitting build from publish and deploy, and giving each job only what it needs, shrinks what an attacker gains from the easiest foothold without requiring any new tooling.

saying these in an interview costs you the question

  • The pipeline only builds code, so it holds nothing valuable
  • Code review already covers it — CI runs reviewed code
  • It is internal, so network access control is enough
  • Securing CI means adding a vulnerability scanner at the end
  • Only the deploy step is sensitive; build steps are harmless

context

open as a page

Nearly everything a CI job pulls in at run time — shared build steps, container images, tool installers, dependency version ranges — is referenced by a mutable name. Why is that a code-execution risk, and what does pinning to a digest or commit change?

level: middleimportance: must knowfreq 52%

basics

~20 s

A mutable reference resolves at build time to whatever the publisher has there now, so a third party can change what your build executes with no commit and no review in your repository. A digest names the exact bytes, making substitution impossible.

open as a page

A CI job's shell step embeds the pull request title into a command using the CI engine's template syntax. Why does that hand a contributor code execution on the runner, and how do you write the step safely?

level: middleimportance: should knowfreq 45%

basics

~20 s

The CI engine substitutes the title into the script text before any shell runs, so an attacker-chosen title becomes part of the program rather than data. Bind such values to environment variables and reference them quoted instead.

open as a page

An outside contributor cannot merge anything to your main branch, but they can open a pull request that triggers CI. What can they still make your pipeline execute, and how do you limit it?

level: seniorimportance: should knowfreq 38%

basics

~20 s

They control the branch the build checks out, so they control the build scripts, test files and configuration the pipeline invokes — and often the pipeline definition itself. Running the branch's tests is running their code.

open as a page

Your build already publishes an SBOM for every artifact. What does a build provenance attestation tell a consumer that the SBOM cannot, and what does verifying one actually check?

level: seniorimportance: should knowfreq 32%

basics

~20 s

An SBOM lists what is inside an artifact; provenance is a signed statement about how the artifact was produced — which builder, which source repository and commit, which parameters. Verification checks that statement against a policy, bound to the artifact's digest.

open as a page

As of SLSA v1.0, what do Build levels 1, 2 and 3 require, and how would you decide how far to push a large organisation up that ladder?

level: principalimportance: nice to knowfreq 24%

basics

~20 s

SLSA v1.0's Build track defines three levels: L1 produces provenance, L2 signs it and has a hosted build platform generate it, L3 hardens that platform so build steps cannot forge provenance. Levels apply per artifact and pay nothing unless someone verifies.

open as a page