
The Role of Identity in DevSecOps: Integrating Security into the Pipeline
An examination of identity management within DevSecOps to ensure secure CI/CD pipelines through code signing and secure security integration.
In modern software delivery, the mechanism of trust within CI/CD pipelines is frequently flawed. Developers configure jobs to run on runners that authenticate to cloud providers using long-lived API keys or static access tokens. These tokens act as digital proxies for human developers, but they create a critical vulnerability: if a runner is compromised or a token is stolen, an attacker gains the same privileges as the developer. They can pull secrets, deploy code, and sign artifacts, all while the system believes the request originated from a legitimate identity. This phenomenon, known as the "Trust Gap," occurs because the pipeline trusts the session rather than the origin.
The Failure of Static Tokens
Consider a standard GitHub Actions workflow. A developer pushes code, the runner spins up, executes npm install, and then runs docker build. To push the resulting image to a registry like ECR or Docker Hub, the runner executes a CLI command using a pre-configured AWS Access Key ID and Secret Access Key.
Here is the mechanism of failure: the secret is stored in the environment variables of the runner. It is valid for months or years. If an attacker injects malicious code into the repository (e.g., via a compromised dependency), that code runs with the full privileges of the secret. The attacker can now download the secret, use it to spin up a new EC2 instance, or push a malicious image to the registry. The registry sees a valid signature from the IAM role, but it has no way to distinguish between the legitimate build and the attacker's build because the credential itself is the only proof of identity.
The mechanism here is static credential delegation. The system delegates authority to a credential, not to a specific, ephemeral event.
Workload Identity: Short-Lived Trust
To fix this, we replace static credentials with Workload Identity Federation, often implemented via OpenID Connect (OIDC). In this model, the CI/CD platform (e.g., GitHub Actions) acts as an Identity Provider (IdP) for the cloud provider.
When the workflow starts, the runner does not have a secret. Instead, it requests a temporary JSON Web Token (JWT) from the CI/CD platform. This JWT contains claims about the specific event: the repository name, the branch, the commit SHA, and the runner ID. The runner then presents this JWT to the cloud provider.
The cloud provider validates the JWT against the known public keys of the CI/CD platform. If valid, the cloud provider issues a short-lived, time-bound access token (valid for minutes) scoped strictly to the specific resource and action required.
This changes the trust model fundamentally. The attacker cannot steal the token because it expires in minutes. More importantly, they cannot forge the JWT because they do not possess the private signing key of the CI/CD platform. Even if they compromise the runner, they cannot generate a valid JWT for a different repository or branch. The identity is bound to the specific execution context.
# Example: GitHub Actions requesting a token via OIDC
# Documentation: https://docs.github.com/en/actions/deployment/security-hardening-your-deployments/about-security-hardening-with-openid-connect
# The runner automatically handles the exchange, but the underlying flow looks like this:
1. Runner sends POST request to GitHub OIDC endpoint:
{ "aud": "sts.amazonaws.com", "iss": "https://token.actions.githubusercontent.com" }
2. GitHub signs the token with its private key.
3. AWS STS validates the signature using GitHub's public key and issues a temporary token.
4. The application uses the temporary token to call the S3 or ECR API.The Cryptographic Chain: Code Signing
Once the pipeline has a secure identity, we apply that identity to the artifacts themselves. This is where Code Signing becomes the critical mechanism for supply chain security. The goal is to ensure that the binary running in production is exactly what was built in the pipeline, signed by the identity that built it.
The mechanism involves the build agent holding a private key. In a secure setup, this key is never stored on disk. It is managed by a Hardware Security Module (HSM) or a cloud-based Key Management Service (KMS) that the workload identity can access.
When the build completes, the pipeline agent requests a signature from the KMS. The KMS verifies that the request comes from a valid, authenticated workload identity (the one established in the previous section). If the identity is valid, the KMS uses the private key to sign the artifact (e.g., a container image or a binary). The signature is attached to the artifact, and the public key is made available for verification.
This creates a Chain of Custody. The artifact now contains a cryptographic proof that it was built by a specific identity at a specific time. If an attacker tries to swap the image in the registry after the build, the signature will not match the new image hash. The registry will reject it.
Tools like Sigstore and cosign automate this. In the Sigstore model, the OIDC token is used by the Cosign CLI to request a short-lived certificate from Fulcio, rather than relying on a KMS to validate a token and release a static private key. This ensures the signing process remains transient and isolated without conflating generic HSM flows with the specific Fulcio/Rekor architecture.
Verification at the Edge
The final layer of this integration is enforcement. Identity and signing are useless if the runtime environment ignores them. The pipeline must push the signed artifact to a registry that enforces signature verification.
In a Kubernetes cluster, for example, admission controllers (like Kyverno or OPA Gatekeeper) can be configured to reject any Pod deployment that references an image without a valid signature. The controller fetches the public key associated with the signing identity and verifies the signature against the image digest.
If the signature is missing, or if the signature was created by an unauthorized identity (e.g., a key belonging to a different project), the deployment is blocked. The system effectively says: "I do not care who you are, I only care if you can prove you built this image using the correct identity."
This shifts the security boundary from the perimeter to the artifact. An attacker might compromise the network, but they cannot bypass the cryptographic verification of the image identity.
Common Pitfalls
Implementing identity-based security introduces new complexities that teams often underestimate. Three common pitfalls include:
- Over-reliance on OIDC without fallback: Relying exclusively on OIDC tokens without a manual override or emergency access mechanism can lock teams out during cloud provider outages or configuration drift.
- KMS latency in high-throughput pipelines: In high-frequency CI/CD environments, synchronous calls to KMS for signing or decryption can introduce significant latency, causing build timeouts if not optimized.
- Misconfigured trust policies: Incorrectly scoped IAM roles or OIDC trust policies (e.g., allowing any branch to assume a production role) can negate the security benefits of workload identity federation.
Practical Takeaways
To successfully migrate to a cryptographic identity model, consider these actionable steps:
- Audit your current CI/CD runners immediately to identify and eliminate any usage of long-lived static secrets or API keys.
- Implement OIDC federation for your cloud providers first, replacing static credentials with short-lived tokens before moving to artifact signing.
- Adopt Sigstore or cosign to automate code signing without the operational overhead of managing long-term private keys.
FAQ
Q: Can I use Workload Identity Federation with legacy CI systems? A: Yes, provided the CI system supports custom scripts to generate OIDC tokens or has a plugin ecosystem that facilitates the token exchange, though native support is preferred.
Q: How does Sigstore handle key management compared to traditional HSMs? A: Sigstore uses Fulcio to issue short-lived certificates based on OIDC tokens, eliminating the need to store long-term private keys in an HSM or KMS for the signing process itself.
Q: What happens if the OIDC issuer is compromised? A: The risk is mitigated because the tokens are short-lived. However, the cloud provider's trust policy must be updated to revoke the issuer's public key immediately to prevent further token validation.
Conclusion
Integrating identity into DevSecOps is not about adding more login screens. It is about replacing static secrets with ephemeral, verifiable cryptographic proofs. By using OIDC for authentication and code signing for artifact integrity, we ensure that every step of the pipeline is traceable to a specific, authorized event. The pipeline stops trusting "users" and starts trusting "proofs."
This approach eliminates the blast radius of stolen credentials and ensures that only artifacts built by the trusted pipeline identity can reach production. It is the only mechanism that scales with the speed of modern development while maintaining the rigor required for security.
Related posts
Zero Trust for CI/CD: Securing the Software Delivery Pipeline
An examination of zero trust principles applied to CI/CD pipelines, focusing on DevSecOps, SLSA standards, and ephemeral credentials for supply chain security.
Why Multi-Cloud Identity Fragments
An examination of identity fragmentation across AWS, Azure, and GCP, comparing identity models to understand multi-cloud challenges.
AWS Alerting: Fire on Real Threats
Reduce alert fatigue in AWS by configuring EventBridge and GuardDuty to fire only on high-fidelity threats.