Skip to content
RESEARCH INDEX BREACHROAD / INTELLIGENCE NOTE
Cloud Security

CI/CD OIDC workload identity security guide

Replace static CI/CD cloud keys with OIDC, restrict trust by audience, subject and environment, and test AWS, Azure and Google Cloud federation.

PUBLIC RESEARCH
AUTHOR
/ Penetration Tester (OSCP, PNPT)
PUBLISHED
25 April 2026
READING TIME
19 min read
TOPIC
Cloud Security
CI/CD OIDC workload identity security guide

OIDC workload identity in CI/CD lets a pipeline obtain short-lived cloud credentials without storing a long-lived access key in repository secrets. It is not an automatic security guarantee. A broad trust relationship may let an unintended repository, branch or environment from the same issuer assume a production role. A defensible design binds the token to a precise issuer, audience, organisation, repository, ref or protected environment, then limits the resulting cloud session.

This guide explains how to design and penetration-test federation from GitHub Actions or another CI platform into AWS, Microsoft Entra ID and Google Cloud. The goal is more than deleting a secret: it is to create an auditable trust boundary that can be monitored, changed and revoked without distributing another static credential.

What OIDC changes in a deployment pipeline

In the traditional model, a job reads an access key or application secret from a secret store. That credential may remain valid for months, and a copied value can often be used outside CI. In a federated model, the job asks its CI provider for a signed OIDC token. The cloud verifies the signature and claims, then issues its own short-lived session credential.

The exchange crosses four boundaries:

  1. the workflow receives permission to request an OIDC token;
  2. the CI issuer signs a token describing the current job;
  3. the cloud security token service compares iss, aud, sub and any additional claims with its trust policy;
  4. the service issues a session constrained by role, scope and lifetime.

OIDC removes a static secret, but it does not remove workflow takeover risk. If an attacker can change the workflow, execute a job in a trusted context and satisfy the federation conditions, the attacker receives a legitimate token. Federation therefore belongs alongside branch protection, CI-file review, environment controls and software supply-chain security.

Claims that belong in the threat model

A GitHub Actions token contains standard OIDC claims and information about the repository and workflow run. Three fields form the core of the decision:

ClaimControl questionCommon failure
issWho issued the token?trusting an unintended or additional issuer
audWhich service is the token intended for?missing validation or an unnecessarily broad audience set
subWhich workload does the token represent?a wildcard covering any repository, ref or environment

GitHub documents subject formats that depend on the job context. A job associated with an environment can receive a subject that identifies the organisation, repository and environment name. Without an environment, the subject may identify a branch, tag or pull-request context. Do not build a policy from memory. Capture the non-sensitive claims from a controlled run, compare them with the issuer’s current documentation and only then write the condition.

Claims are security inputs, but their presence does not mean the cloud automatically enforces them. The federated credential or trust policy must narrow the accepted values explicitly. A valid signature proves that a trusted issuer created the token; it does not prove that every workload from that issuer should receive production access.

The minimum viable trust policy

A production trust relationship should answer five questions:

  • is the issuer exactly the configured CI issuer;
  • does the audience identify the expected token-exchange service;
  • are the repository owner and repository correct;
  • did the job originate from the protected environment or approved ref;
  • are role permissions and session lifetime minimal for this stage?

Do not reuse one trust relationship for build, test, staging and production. A build may need a dependency registry but no deployment permission. An image publisher does not need to administer a virtual network. A database migration deserves its own identity. Separation reduces blast radius and produces clearer audit records.

A wildcard may be reasonable for a controlled family of development branches, but it is a poor production default. A pattern that accepts every repository in an organisation makes the least protected repository an entry point into the cloud. A pattern that accepts every branch may let a contributor bypass review by using a new ref. This is the difference between a working integration and a security boundary.

GitHub Actions: token minting is a privilege

A GitHub Actions job that uses federation receives permissions: id-token: write. This permission allows the job to request an OIDC token; it does not by itself grant write access to cloud resources. It should nevertheless exist only on the job performing the exchange, not at workflow level by default.

Set all other GITHUB_TOKEN permissions explicitly. A checkout step usually needs contents: read, while packages: write, pull-requests: write or repository administration should not be granted pre-emptively. Pin third-party actions to an immutable commit identifier. A compromised action running in a job with token-minting permission can request a token in that job’s security context.

Bind production to a GitHub Environment. Configure required reviewers, deployment branch or tag restrictions and environment-specific protection rules. Then restrict the cloud-side subject to that environment. A control on only one side is weaker: environment protection cannot compensate for a role that trusts every repository, while a narrow subject cannot replace review of workflow changes.

Reusable workflows need separate attention. Identify which repository owns the called workflow, what the subject represents, which inputs cross the boundary and whether callers can influence scripts or artifact locations. A central deployment workflow is useful only when its callers, permissions and trusted code are equally constrained.

AWS: OIDC provider, role trust and STS

In AWS, GitHub Actions exchanges the token by using an IAM role and an OIDC identity provider. AWS IAM documentation requires a GitHub trust policy to constrain the sub claim rather than leaving it null or universally wildcarded. In a typical integration, aud is sts.amazonaws.com, while sub identifies an exact organisation and repository plus a branch, tag or environment context.

The role trust policy decides who can assume the role. The role permission policy decides what the resulting session can do. Both layers require least privilege. A precise subject does not justify Action: * and Resource: *. Separate image publication, service updates and parameter reads. Apply resource-level scoping and service-specific conditions wherever the API supports them.

An assessment should also cover maximum session duration, iam:PassRole, permissions to modify the role’s own trust, and any escalation routes. These are explored more broadly in our AWS, Azure and GCP penetration-testing guide. A deployment role must not be able to rewrite the policy that limits it or disable the logs used to investigate its actions.

CloudTrail should make the web-identity exchange and subsequent API activity attributable. Preserve run identifiers through session names or supported tags where possible. The exact fields depend on the integration, so validate what reaches the audit record rather than assuming that repository and commit context survive the exchange.

Microsoft Entra ID: federated identity credentials

In Microsoft Entra ID, a federated identity credential establishes trust between an external issuer and an application or managed identity. Matching uses the issuer, subject and audiences. The design rule remains the same: a separate identity for each security boundary, a precise subject and minimal Azure RBAC assignments.

Avoid connecting unrelated pipelines to one application with broad subscription rights. That architecture obscures attribution and makes compromise of one repository affect every deployment. Prefer an identity per application and environment, scope roles to a resource group or specific resource, and control who can add or modify federated credentials.

Microsoft also provides flexible federated identity credential matching. Expressiveness should not become a rule that accepts the entire issuer. Test boundary values, encoding, repository rename behaviour and the differences among branch, tag, pull-request and environment claims. Inventory legacy client secrets and certificates: adding federation without removing unused static credentials leaves the original attack path intact.

Privileged Microsoft Graph or directory permissions deserve a distinct review. A workload that deploys an Azure resource rarely needs broad directory access. Treat application ownership and the right to edit service-principal credentials as escalation paths, not routine administration.

Google Cloud: Workload Identity Federation

Google Cloud Workload Identity Federation maps claims from an external token to Google attributes and can apply an attribute condition. Restrict the provider as well as the organisation, repository and deployment context. Google notes that name-based claims can be reused if an organisation or repository name is deleted and registered again; where an issuer provides stable numeric identifiers, include them in the mapping and conditions.

Use separate service accounts and bindings for environments. Review the ability to impersonate a service account because the workload identity binding is part of the trust boundary. Do not keep an old service-account JSON key in secrets as an emergency fallback. That retains the long-lived credential risk that federation is intended to remove.

Also review the permissions of the principal that administers pools, providers and service-account policies. If the pipeline can modify its own provider condition or grant itself impersonation of a stronger account, its nominal workload role is not an effective boundary.

Threat model for CI/CD workload identity

A meaningful penetration test asks more than whether authentication succeeds. It examines whether an attacker can reach a trusted context by another route. The principal scenarios are:

  • changing the workflow through a pull request or a compromised maintainer account;
  • using a third-party action, installer or dependency to request or exfiltrate the token during the job;
  • running the workflow from an unexpected branch, tag, fork or reusable-workflow caller;
  • confusing pull_request with pull_request_target and executing untrusted code in a privileged context;
  • accepting an overly broad subject, the wrong audience or an additional federated credential;
  • replacing an artifact between the build and deployment jobs;
  • assuming a minimally protected role that can escalate through PassRole, impersonation or policy administration;
  • losing attribution between cloud activity, workflow run and approved commit.

The most dangerous design mixes untrusted code with a privileged job. A workflow processing a forked pull request must not execute contributor-controlled code while holding production federation rights. An artifact that moves from a less trusted build job into deployment needs a stable identity, integrity verification and provenance. The surrounding controls are covered in CI/CD agent prompt-injection defence and AI coding-agent supply-chain security.

Penetration-testing methodology

Agree the test with both the cloud and repository owners. Avoid a real production change when a harmless identity call or a dedicated test resource proves the same condition. The purpose is to demonstrate trust-boundary failure, not to create an outage.

1. Inventory every relationship

Collect issuers, providers, federated credentials, roles, service accounts, audiences, subject patterns, attribute mappings and maximum session durations. Map each relationship to a workflow and business owner. An orphaned trust is a finding even if the current pipeline no longer refers to it.

2. Observe effective claims safely

Run a controlled job with no production secrets and record only the claims required for analysis—never the raw JWT. Compare subjects for a branch, tag, environment, pull request and reusable workflow. Check encoding and the effects of renaming a repository or environment.

3. Run negative tests

Attempt an exchange from an untrusted test branch, an unapproved environment, a different controlled repository and a deliberately incorrect audience. The expected outcome is rejection by the token service. Any accepted case shows which condition is broader than intended.

4. Analyse effective cloud permissions

With an authorised test session, enumerate effective actions, permission boundaries, organisation policies and role-passing or impersonation paths. Determine whether the identity can change its own trust, permissions, logging or resource protection. Use non-mutating API calls wherever possible.

5. Verify build-to-deploy integrity

Determine whether deployment rebuilds code or downloads an artifact. Bind the artifact digest to the approved commit, tests and attestation. An OIDC token identifies a workload; it does not prove that the file being deployed is the reviewed file.

6. Test monitoring and revocation

Inspect cloud token-exchange logs and workflow history, then prove that they can be correlated. Rehearse revocation by removing the credential, changing the trust condition and blocking the environment in a test setup. Short sessions reduce exposure, but they do not replace an incident procedure.

Telemetry that exposes misuse

Record at least the role or service-account identifier, issuer, subject, audience, repository, workflow, branch or environment, commit SHA, run ID, initiating actor and the operations performed after exchange. Do not store the raw OIDC token in logs.

Alert on first use of a new subject, production sessions without a corresponding deployment approval, changes to providers or trust policies, a sudden increase in role permissions, and cloud activity inconsistent with the known runner infrastructure. Self-hosted runners also need host-integrity controls and restricted network egress because persistence on the runner can survive beyond a single workflow.

Monitoring must connect the CI control plane with the cloud control plane. An AWS STS or equivalent token-exchange event alone may not show who changed the workflow. A GitHub audit event alone cannot show what the resulting session did. Correlate both through your SIEM, XDR or EDR architecture and managed security monitoring.

Secure deployment checklist

  • Remove static cloud keys after federation works and repository history has been checked.
  • Use distinct identities for build, staging and production.
  • Restrict issuer, audience, repository and branch, tag or environment.
  • Grant id-token: write only to jobs that perform the exchange.
  • Minimise GITHUB_TOKEN and pin external actions to commit SHAs.
  • Protect workflow files through CODEOWNERS, branch rules and required reviews.
  • Never execute untrusted pull-request code in a job with production federation.
  • Scope the cloud role to the required actions and resources.
  • Monitor changes to providers, credentials, trust policies and identity bindings.
  • Repeat negative tests after claim-format, provider or pipeline changes.
  • Maintain a tested revocation process and an emergency deployment procedure that does not reintroduce a permanent key.

Frequently asked questions

Does OIDC eliminate all pipeline secrets?

It replaces long-lived cloud credentials for a supported exchange. A pipeline may still need credentials for services that do not support federation. Inventory, scope and rotate each of those separately.

Is a short token lifetime enough?

No. It narrows the time available to abuse one stolen session, but an overly broad trust lets an attacker mint another token. Precise conditions and workflow integrity are the primary controls.

Is one organisation-wide role easier to maintain?

It may be operationally simpler, but it greatly expands blast radius and weakens attribution. Identities per application and environment are easier to audit, tune and revoke.

How often should federation be audited?

Review it after workflow, provider, repository-name, environment-model or permission changes and on a recurring schedule. Orphaned trusts and emergency exceptions accumulate just like forgotten keys.

Audit both sides of the federation boundary

The security outcome is not merely “no static keys”. It is evidence that only an approved workload can obtain a minimal session and that each exchange can be tied to reviewed code and a deployment decision. Breachroad combines cloud penetration testing, pipeline review and IAM path analysis so the report identifies both the weak trust condition and its practical impact.

Primary sources

SHARE / COPY