Threat-model your pipeline
Poisoned deps, leaked runners, tampered artifacts.
The core idea of this whole section: your pipeline is production. It holds credentials to your registry and cloud, it can deploy to production, and it runs code on every push — so it is exactly as valuable a target as the servers it deploys to, and often less defended. Before hardening individual pieces, it helps to see the attack surface as a whole, because the controls that follow each close one of these paths.
The highest-leverage risks
Three stand out in practice. A malicious merge request that runs on a runner holding production secrets — because CI runs contributor code. A leaked CI/CD variable — a token printed to a log, or exposed to a fork pipeline. And a tampered artifact — the thing you built is not the thing you deployed, because nothing verified it in between. Notice these are not exotic exploits; they are configuration and trust failures, which is exactly why they are preventable.
Assume breach, limit blast radius
You cannot make CI perfectly safe — it runs code, by definition — so the goal is to limit what a compromised job can reach. Least-privilege everywhere: scoped, short-lived tokens instead of standing admin credentials; isolated runners so a bad job cannot touch production ones; protected branches/environments so only reviewed changes deploy; and signed artifacts so a swap is detectable. Every subsequent lesson is one layer of that blast-radius reduction.