A CI/CD pipeline typically holds the keys to the kingdom. Credentials for cloud environments, registry push access, deployment permissions, signing keys. If an attacker can influence what the pipeline executes or what it does with its credentials, they can affect everything downstream. This is a more attractive target than compromising individual application instances, because a single pipeline compromise can poison every release for weeks before being detected.
The supply chain attack surface extends beyond the pipeline itself. Third-party GitHub Actions, npm packages, pip packages, and base container images are all inputs to the build. Malicious or compromised third-party inputs can insert code into artifacts without the pipeline operator's knowledge. This is why dependency pinning, artifact verification, and careful review of new external dependencies are security controls, not just operational hygiene.
The right mental model is to treat every external input to the pipeline as untrusted until it has been verified. Code from contributors outside the organization, third-party actions pinned to mutable tags, base images without digest pinning, and unverified build tools are all potential injection points. Defense in depth means that even if one input is compromised, the overall pipeline still limits what the attacker can do with the resulting artifact.
Separation of concerns is the organizing principle for pipeline security. Untrusted contributor-driven steps (building and testing a PR from a fork) should never have access to production secrets, signing keys, or deployment permissions. Only trusted, reviewed code on protected branches should be able to trigger the steps that access sensitive credentials or publish official artifacts.