A CI/CD pipeline is one of the most privileged identities in any organisation. It reads source code, pulls dependencies, builds artefacts, holds signing keys and deploys to production, usually without a human watching each step. Pipelines are also full of non-human identities: repository tokens, cloud credentials, registry passwords, package publishing tokens and deployment keys. Attackers know this. Compromising a single pipeline component, or a single token it holds, can give them source code, secrets and the ability to ship malicious code to every customer. This guide covers the identities in CI/CD, how they are attacked and how to secure them.
Key takeaways
- Treat pipeline identities as privileged identities: least privilege, short-lived credentials and monitoring.
- Replace long-lived cloud keys in CI/CD variables with OIDC workload identity federation, with trust policies pinned to specific repositories, branches, workflows and environments.
- Untrusted code and input must never run with privileged credentials. Separate pull request builds from privileged workflows.
- Pin and verify third-party actions, plugins and dependencies; many recent incidents started there.
- Protect publishing and signing credentials as the highest-value secrets in the software supply chain.
The identities in a pipeline
| Identity | Used for | Typical risk |
|---|---|---|
| Repository tokens (built-in job tokens, personal access tokens, app tokens) | Checkout, commenting, pushing, releasing | Default write permissions; personal tokens with broad scope |
| Cloud credentials | Deploying infrastructure and applications | Static access keys stored as variables; admin roles |
| Container registry credentials | Pushing and pulling images | Shared across projects; push access from untrusted builds |
| Package publishing tokens | Publishing to npm, PyPI and similar | Long-lived, account-wide tokens enabling supply chain attacks |
| Signing keys | Signing code, artefacts and releases | Keys stored as files or variables |
| Deployment keys and SSH keys | Reaching servers and clusters | Unrotated, shared across environments |
| Runner identities | Self-hosted runners' host credentials and cloud roles | Persistent runners reachable by untrusted jobs |
| Third-party integration tokens | Code scanning, notifications, test services | Over-scoped tokens held by vendors |
How pipelines are attacked
- Compromised third-party actions: the tj-actions/changed-files compromise and the reviewdog action attack exposed secrets from workflows that used them. The chain was traced to a leaked SpotBugs personal access token.
- Self-propagating package malware: the Shai-Hulud and Miasma and Hades worms stole credentials, including publishing tokens, and used them to infect further packages.
- Compromised CI platforms: the CircleCI breach required customers to rotate every secret stored in the platform; the Codecov breach modified a script to harvest CI environment variables.
- Poisoned pipeline execution: attackers submit pull requests or edit configuration so their code runs in a workflow with access to secrets. See the CI/CD pipeline exploitation case.
- Over-trusting federation: OIDC trust policies that accept any repository in an organisation, or any branch, let unintended workflows assume privileged roles (OWASP NHI6 Insecure Cloud Deployment Configurations).
Controls
Go keyless for cloud access
- Use the CI platform's OIDC tokens with cloud workload identity federation instead of stored access keys.
- Pin trust policies to the exact repository, workflow, branch or tag, and deployment environment. Review them like firewall rules.
- Use separate roles per environment, with production roles only assumable from protected branches and environments.
See the NHI Authentication Guide and workload identity federation article.
Minimise token permissions
- Set the built-in job token to read-only by default and grant write permissions per job only where needed.
- Replace personal access tokens with app-based or fine-grained tokens scoped to specific repositories and expiring.
- Use trusted publishing (OIDC-based publishing to package registries) where supported, instead of long-lived publishing tokens.
Separate untrusted from privileged
- Run builds for pull requests from forks without secrets or write tokens.
- Avoid workflow triggers that run untrusted code with the base repository's privileges; if needed, do not check out or execute the contributor's code in those jobs.
- Require approval before running workflows from first-time or external contributors.
- Use ephemeral runners for untrusted jobs; never share persistent self-hosted runners between trusted and untrusted workloads.
Control dependencies and actions
- Pin third-party actions and plugins to full commit hashes, not tags.
- Maintain an allowlist of approved actions.
- Route dependency installs through a proxy registry with policy, and use lock files.
Protect secrets that remain
- Store them in a secrets manager or the platform's environment-scoped secrets, available only to specific jobs and protected branches.
- Mask secrets in logs and avoid printing environment variables.
- Rotate after any suspected exposure, and immediately after a CI platform or dependency compromise.
Sign and verify
- Sign artefacts and generate provenance, using keyless signing with workload identity where possible.
- Verify signatures and provenance before deployment.
- Consider the SLSA framework for build integrity levels.
Monitor
- Alert on changes to workflow files, branch protection, deployment environments and federation trust policies.
- Monitor cloud activity by pipeline roles for unusual actions or sources.
- Scan build logs and artefacts for secrets.
AI agents in pipelines
AI agents increasingly run inside CI/CD to review code, fix issues and respond to comments. They process untrusted text such as issue bodies and pull request descriptions, so they must never run with write tokens or secrets on events triggered by outsiders. See the AI Coding Agents Security Guide.
Practitioner checklist
- Inventory every credential used by pipelines, runners and CI integrations.
- Replace stored cloud keys with OIDC federation pinned to repository, branch, workflow and environment.
- Default job tokens to read-only; replace personal access tokens with scoped, expiring app tokens.
- Use trusted publishing for package registries.
- Keep secrets away from untrusted builds; use ephemeral runners.
- Pin actions and plugins to commit hashes and allowlist them.
- Sign artefacts and verify before deploy.
- Monitor pipeline configuration changes and pipeline role activity.
Standards and references
- OWASP Top 10 CI/CD Security Risks
- OWASP Non-Human Identities Top 10 (2025): NHI2, NHI6, NHI7
- SLSA: Supply-chain Levels for Software Artifacts
- NIST SP 800-218: Secure Software Development Framework
- NIST SP 800-204D: Software Supply Chain Security in DevSecOps CI/CD Pipelines
Related NHI Mgmt Group resources: Secrets Management Guide · Cloud Workload Identity Guide · Guide to the Secret Sprawl Challenge · AI Coding Agents Security Guide