Securing the CI/CD Pipeline: Every Stage Is an Attack Surface
The CI/CD pipeline is the most privileged system most organisations barely secure. It holds credentials to production, it can deploy code to every environment, and everything downstream trusts whatever it emits without question. To an attacker, that is close to ideal: compromise the pipeline once and you do not need to breach production directly — you let the pipeline deploy your payload for you, signed and trusted. Securing CI/CD means treating each stage from commit to deploy as its own attack surface.
The reason the pipeline is such a target is trust concentration. A developer's laptop is trusted a little; the pipeline is trusted absolutely. It reads source, pulls dependencies, runs arbitrary build scripts, produces artifacts, and pushes them to production with credentials that would make any attacker's week. Each of those actions is a seam. The mistake is to picture 'pipeline security' as one control; it is a chain of distinct trust boundaries, and the attacker only needs the weakest link.
The source stage: trust in what enters
It begins at the commit. A malicious change can arrive through a compromised developer account, a poisoned pull request from a fork, or a subtle modification to the pipeline's own configuration — which, crucially, often lives in the repository as code. If a fork's pull request can trigger a build that runs with real secrets, an outside contributor can exfiltrate them without ever being trusted. Branch protection, required review, signed commits and careful handling of pull-request triggers are the controls that keep the front of the pipeline honest.
The build stage: arbitrary code with real credentials
The build is where the pipeline is most dangerous, because it runs arbitrary code — your build scripts, and every build script of every dependency — with access to the pipeline's secrets. A single malicious package pulled during the build executes in that trusted context. This is the mechanism behind real-world build-system compromises: the attacker does not attack production, they attack the thing production trusts. Isolated, ephemeral build runners, pinned dependencies, and secrets scoped to the minimum a job needs are what contain a poisoned build.
- Treat pipeline config as production code. The workflow files decide what runs with your secrets; they deserve the same review, protection and change control as the application.
- Scope and short-live every secret. Prefer OIDC-based short-lived credentials over long-lived tokens; a job should hold only the access it needs, only while it runs.
- Isolate and dispose of build runners. Ephemeral, single-use runners stop one poisoned build from contaminating the next and limit what a compromise can reach.
- Pin dependencies and actions by digest. A build that pulls
latestor a mutable tag inherits whatever an upstream account was persuaded to publish. - Sign what you ship and verify before deploy. Artifact signing and provenance let the deploy stage refuse anything the pipeline did not actually produce.
Artifact and deploy: trust on the way out
Past the build, two risks remain. The artifact must be tamper-evident — if an attacker can swap the image in the registry between build and deploy, every upstream control is moot; signing and verification close that gap. And the deploy stage holds the crown-jewel credentials that push to production, which is why those credentials should be short-lived, tightly scoped, and never sitting in a plaintext variable a leaked log could reveal. The pipeline's output is only as trustworthy as its weakest handoff.
- Check whether a pull request from a fork can trigger a workflow that has access to repository secrets. If it can, an untrusted contributor may be able to exfiltrate them.
- Look at how your deploy job authenticates to production. A long-lived static token stored as a variable is a far bigger prize than a short-lived OIDC credential.
These checks probe two seams; mapping trust and privilege across every stage of your pipeline is what our assessment does end to end.
Most organisations cannot list all the pipelines that can reach their production environments — the ones a single team wired up are exactly the ones with unreviewed secrets. Securing CI/CD begins with finding every pipeline, because you can't defend what you haven't discovered.