Use layered controls. Keep dependency installation read-only, keep release credentials out of build contexts, and assign distinct service accounts to fetch, build, and publish stages. The point is not to distrust every package equally. The point is to stop untrusted code from inheriting the same identity that can release or republish software.
Why package trust and identity trust need different control planes in CI
CI is safer when the thing you are consuming and the authority you are using are treated as separate problems. Package trust is about whether a dependency, artifact, or action should be admitted into the build. Identity trust is about what the build system itself is allowed to do, especially when it can read secrets, sign artifacts, or publish releases.
That separation matters because the same pipeline often touches both untrusted code and high-value credentials. If those boundaries blur, a compromised dependency can inherit the privileges of a trusted release path, turning a normal build step into a software supply-chain compromise.
In practice, the trust decision for packages should stay narrow and read-only, while the identity decision for CI should stay staged and least-privileged. That means the build can evaluate inputs, but it should not also carry the authority to promote those inputs into production or to mint new trust for them.
How to separate package admission from release authority
Use distinct identities for distinct stages. A fetch or analysis stage can run with only the permissions needed to resolve dependencies, a build stage can compile and test with no release authority, and a publish stage can use a separate credential path that is unavailable to the earlier stages.
That pattern limits the blast radius of malicious or poisoned inputs. A package may be trusted enough to inspect or compile, but not trusted enough to gain access to signing keys, package registry write access, or deployment credentials. The build system should verify inputs without inheriting the right to release them.
Keep high-value credentials outside the build context entirely. Release tokens, signing material, and registry write access should not be present in the same runtime environment that executes third-party code, because any code that can influence the build can also try to exfiltrate or reuse those credentials.
Where possible, use short-lived and stage-specific identities rather than shared credentials. A distinct service account for fetch, build, and publish makes it much easier to reason about which action was authorized, which credential was used, and where a compromise would stop.
What good separation looks like in a CI pipeline
The cleanest design is one where each stage has a single job and a single trust boundary. Dependency resolution should be as read-only as possible, build jobs should not be able to publish, and publish jobs should receive only the minimal authority needed to ship a vetted artifact.
That also means avoiding “identity reuse” across stages. Reusing the same service account for package download, test execution, artifact signing, and release publication erases the distinction between untrusted inputs and trusted actions. A pipeline that reuses one powerful identity is easy to operate, but hard to secure.
Teams should also treat the package source and the publishing destination as separate trust domains. A package registry may be a source of code, but the release registry is a destination for artifacts. The first should not inherit the privileges of the second.
This is why CI hardening guidance increasingly emphasizes workload identity, token scope reduction, and separation of duties. For a broader control model, CI/CD Pipeline Identity Security Guide is a useful reference point for keyless federation, trusted publishing, and untrusted builds.
Risk and Threat Considerations
The main risk is privilege collapse: once untrusted code runs under the same identity that can publish or sign software, package compromise becomes a release compromise. That can expose secrets, tamper with artifacts, or let an attacker move from a dependency foothold into the software distribution path.
Failure mechanism: A malicious dependency, compromised package, or poisoned build step steals or abuses the CI identity that has broader authority than the code itself should ever receive. Shared credentials, long-lived tokens, and overbroad service accounts make that escalation straightforward.
Impact: Attackers can modify build outputs, push malicious releases, sign untrusted artifacts, or pivot into downstream environments that trust the CI pipeline. The resulting failure is not only a bad build, but a trust break in the software supply chain.
That is why supply-chain guidance focuses on both package integrity and release-path integrity. OpenSSF is a relevant external authority for the broader supply-chain control model, while package-level risk patterns such as stolen credentials and malicious dependencies illustrate why the trust boundary must stay narrow.
Standards & Framework Alignment
This section maps relevant standards and security frameworks to the operational risks and controls described in this guidance.
OWASP Non-Human Identity Top 10 and OWASP API Security Top 10 address the attack and risk surface, while SLSA and NIST SP 800-53 Rev 5 set the governance and control requirements practitioners need to meet.
| Framework | Control / Reference | Relevance |
|---|---|---|
| OWASP Non-Human Identity Top 10 | NHI-05 — Overprivileged NHI | CI service accounts can become overprivileged release identities. |
| Recommendation — Split fetch, build, and publish identities; remove write and signing rights from untrusted stages. | ||
| SLSA | Supply chain provenance and integrity | The question is about protecting build and release trust boundaries in a software supply chain. |
| Recommendation — Require provenance and isolate build authority from release authority. | ||
| NIST SP 800-53 Rev 5 | IA-5 — Authenticator Management | CI trust separation depends on lifecycle control of tokens and release credentials. |
| AC-6 — Least Privilege | Separate package admission from publish authority by minimizing each stage's permissions. | |
| Recommendation — Rotate and scope CI credentials so build jobs never inherit release-capable authenticators. Grant each pipeline stage only the permissions needed for its own task. | ||
| OWASP API Security Top 10 | API8 — Security Misconfiguration | Misconfigured CI trust paths often expose publishing credentials to untrusted code. |
| Recommendation — Harden pipeline configuration so build steps cannot reach release secrets or write paths. | ||
Practitioner Guidance
What to prioritise: Start by identifying which pipeline steps consume untrusted code and which steps hold release authority. Those two sets must not share the same credential or service account.
What to verify: Confirm that dependency jobs cannot write to registries, access signing keys, or reach release tokens, and that publish jobs cannot be triggered with the same identity used for ordinary builds.
Decision rule: If a step executes third-party code, treat that step as untrusted by default, even if the repository itself is trusted. Only the final publish path should receive the minimal authority needed to release a vetted artifact.
Practitioner takeaway: The goal is not to make CI distrust every package, but to make sure no package can inherit the identity that can ship, sign, or republish software.
Related resources from NHI Mgmt Group
- How do security teams know whether a package trust issue has become an identity incident?
- How should teams respond when package trust is compromised in CI/CD?
- How should teams respond when package installs and CI/CD secrets share the same trust path?
- Why do non-human identities complicate zero trust architecture?