Hook
OIDC in CI/CD solves a very practical problem: how to let a pipeline access cloud without placing a permanent key in secrets. Instead of relying on a key that may sit in settings for years, the pipeline receives a short-lived token for each run.
For beginners, this can sound like one more security acronym. The idea is simpler than it looks: the deployment service trusts the verified identity of a specific workflow, not a random secret string.
Problem / Context
A classic CI/CD setup often starts with a long-lived key. Someone creates a cloud access key, adds it to GitHub Actions secrets or another CI/CD system, the pipeline deploys, and everything feels fine. Until the first leak.
The problem is that a static key does not understand much context. If the key is copied, it may work from somewhere else. If it has too many permissions, it can do more than the pipeline needs. If nobody rotates it, it may live longer than the project plan. If the secret accidentally appears in logs, an issue, a fork, or a local .env, the team has an incident.
OIDC changes the model. The pipeline does not store a permanent cloud key. During a run, it asks an identity provider to issue a token. Cloud checks that token through a trust policy: which repository made the request, which branch, which workflow, which environment, and which service the token is meant for. If the checks match, cloud returns short-lived credentials.
So the secret no longer sits in CI/CD like a permanent spare key. Access is created for one run and tied to one context.
Why it matters
CI/CD has powerful permissions. A pipeline can build code, publish packages, run Terraform, deploy to Kubernetes, update serverless functions, read secrets, and touch production. If pipeline access is built around one long-lived key, that key becomes a very valuable target.
OIDC reduces risk in three places.
First, there is no static secret in the repository or CI/CD storage. There is less to accidentally print in logs or copy to someone’s laptop.
Second, access is short-lived. Even if a token is exposed somewhere, its lifetime is limited. That is not magic protection, but the impact is usually smaller than leaking a key that works for a year.
Third, the trust policy can be precise. You can allow production deploys only from main, only through a protected environment, only from a specific repository, and only for a specific audience. Staging can have looser rules, while production stays strict.
This matters even more as a team grows. With only a few people and repositories, static keys feel convenient. Once there are several environments, contractors, preview deploys, self-hosted runners, and Terraform, old keys quickly become security debt.
The mental model
Think about three sides.
The first side is the CI/CD pipeline. It runs from a specific repository, branch, workflow, and environment.
The second side is the identity provider. In GitHub Actions, this is GitHub’s OIDC provider. It can say: “yes, this run really came from this repository and has these claims.”
The third side is cloud or the deployment service. It does not trust the pipeline just because the pipeline asks nicely. It reads the token, verifies issuer, audience, subject, and extra claims, then decides whether to issue temporary credentials.
A healthy setup looks like this:
- the workflow requests an OIDC token only when it truly needs access;
- the cloud trust policy accepts tokens only from the expected identity provider;
- the policy checks repository, branch, environment, and audience;
- the role has minimum permissions for the specific task;
- staging and production use separate roles;
- old static keys are revoked after migration.
The key point: OIDC does not mean “any workflow can enter cloud.” It means “cloud can verify which exact workflow is requesting access and grant permissions only by policy.”
How to do it
1. Inventory current secrets
Start with the access map, not the cloud console. Find all CI/CD secrets that look like cloud keys, deploy tokens, service account keys, or Terraform credentials. For each one, write down:
- where it is used;
- which permissions it has;
- who created it;
- when it was last rotated;
- whether it is needed for staging, production, or both;
- what breaks if it is revoked.
This list immediately shows where OIDC brings the most value. Common first candidates are cloud deploys, Terraform apply, container registry push, and Kubernetes deploys.
2. Create separate roles for staging and production
Do not create one universal “ci-admin” role. It is convenient, but risky. Prefer separate roles:
- staging deploy role;
- production deploy role;
- read-only Terraform planning role;
- package publishing role;
- emergency role, if one is truly needed.
Each role should receive only the permissions required for its action. If a workflow publishes a container image, it does not need permission to delete databases.
3. Describe trust policy with claims
The most important part of OIDC is not enabling it. The important part is the trust conditions. The trust policy should answer: which exact CI/CD run do we trust?
For GitHub Actions, teams commonly check repository, branch or tag, environment, workflow, issuer, audience, and subject. For production, it is better to bind access to a protected environment or release process, not to every push from every branch.
Example thinking:
- staging may be allowed from
mainor preview branches with a limited role; - production only from
mainand only through theproductionenvironment; - Terraform apply only from a dedicated workflow;
- package publishing only from a release tag.
If the policy is too broad, OIDC loses much of its value. “Any repository in the organization can assume the production role” is almost the same spare key, just in newer packaging.
4. Enable OIDC in the workflow
The CI/CD workflow needs permission to request an identity token. In GitHub Actions, this usually means the id-token: write permission, then an official cloud action or SDK exchanges the OIDC token for short-lived credentials.
Important detail: id-token: write should not be added everywhere by default. Give it only to workflows that actually need cloud access. Jobs that only run tests or lint do not need it.
5. Check audit logs
After the first test run, do not stop at the green checkmark. Open audit logs in cloud or the deployment service and verify:
- which role was assumed;
- which repository and workflow appeared in claims;
- which audience was used;
- how long access lived;
- whether the pipeline received unnecessary permissions.
This is where mistakes often appear. For example, a staging workflow may accidentally receive a production role, or a trust policy may accept all branches instead of one.
6. Revoke old keys
OIDC does not deliver its full benefit if old static keys remain active “just in case.” After migration, prepare a controlled rollback plan, revoke old keys, remove them from CI/CD secrets, and confirm the pipeline no longer depends on them.
If revoking a key feels scary, that is a signal. The team may not yet understand where the key is used. Finish the access map first.
Anti-patterns
- leaving the old cloud key active after moving to OIDC;
- allowing a production role for all branches or all repositories;
- using one role for staging, production, and Terraform admin;
- adding
id-token: writeto every workflow without need; - checking repository but not environment, branch, or workflow;
- skipping audit logs after the test run;
- confusing OIDC for CI/CD with user login flows;
- assuming a short-lived token fixes overly broad permissions.
Conclusion / Action Plan
OIDC in CI/CD replaces long-lived secrets with verified identity and short-lived access. It does not replace permissions, code review, protected branches, or audit logs, but it removes one painful failure point: a permanent key inside the pipeline.
Start with the practical minimum:
- find static keys in CI/CD;
- choose one staging deploy as the first candidate;
- create a separate role with minimum permissions;
- configure trust policy by repository, branch, environment, and audience;
- add OIDC only to the workflow job that needs it;
- check audit logs;
- repeat for production with stricter rules;
- revoke old keys after successful migration.
Good OIDC access feels less magical than static keys. It has more explicit rules: who is asking, from where, for what purpose, and for how long. That is exactly what makes it a better foundation for modern CI/CD.
Official sources:
- https://openid.net/developers/how-connect-works/
- https://docs.github.com/en/actions/deployment/security-hardening-your-deployments/about-security-hardening-with-openid-connect
- https://docs.aws.amazon.com/IAM/latest/UserGuide/id_roles_providers_create_oidc.html
- https://cloud.google.com/iam/docs/workload-identity-federation
Quick checklist
- Find long-lived cloud keys in CI/CD secrets and decide which ones can be replaced with OIDC.
- Describe the trust policy using repository, branch, environment, workflow, and audience.
- Separate staging and production roles instead of giving one workflow broad access.
- Check audit logs after a test run: who got access, to what, and for how long.
- After a successful migration, revoke old static keys and remove them from secret storage.
Prompt Pack: plan OIDC access for CI/CD
Help me plan OIDC access for CI/CD without long-lived cloud keys. Input data: - git platform and CI/CD: GitHub Actions, GitLab CI, Azure DevOps, or another system; - cloud or deployment service: AWS, Azure, GCP, Kubernetes, Terraform Cloud, Vercel, and so on; - which repositories, branches, environments, and workflows may deploy; - which roles or permissions are needed for staging and production; - which long-lived secrets currently exist in CI/CD; - which audit logs are available for login and deployment checks. Return: 1. the target trust model between CI/CD, the OIDC provider, and cloud; 2. the claims that should be checked; 3. separate rules for staging and production; 4. minimum permissions for each role; 5. a migration plan away from long-lived secrets; 6. a verification checklist before the first production deploy. Response format: model, claims, access rules, permissions, migration, checklist.