Developer Workflows
GitHub Actions OIDC: Review the Trust Policy Before Removing Secrets
Use GitHub Actions OIDC with verified claims, narrow roles, and environment checks so removing static secrets does not create overly broad deployment trust.
In this article
OpenID Connect can let a CI job obtain short-lived cloud access without storing a long-lived cloud credential in the repository. That is useful, but the trust policy becomes a critical boundary. If the cloud accepts tokens from too many workflows, removing a static secret can still leave broad deployment access.
GitHub Actions OIDC review therefore starts with who may request a token and what the cloud permits afterward. Treat identity matching and resource permissions as separate checks. A successfully exchanged token proves that the exchange worked, not that the role is appropriately restricted.
Understand the two-step exchange
GitHub issues an identity token for an eligible workflow job. A supporting cloud provider validates that token against a configured trust relationship and may issue short-lived credentials for a role. The role's permissions govern the resulting resource access.
GitHub's OIDC overview explains this exchange and the claims involved. Use the current documentation for your repository and provider. Don't copy an old subject example without checking the format emitted by your actual environment.
Provider support and configuration differ. Identify the official login action or SDK path for the cloud you use, and review its permissions. An OIDC design is not a universal command that works unchanged with every service.
Define the permitted workflow identity
Write down the repository, environment, branch or other execution context allowed to deploy. Decide whether reusable workflows have an additional identity requirement. Avoid a broad trust rule that accepts every repository in an organisation merely because that is easy to configure.
Check issuer, audience, and the relevant claims using the provider's supported validation mechanism. Claim values are identity evidence only after the token is cryptographically validated. A decoded JSON payload from an arbitrary string isn't proof of a real workflow.
The JWT Decoder can illustrate claims using a synthetic token, but it does not verify signatures, issuer, audience, or authorisation. Don't paste a live OIDC token into a public debugging example. Use sanitised claim records in review materials.
Verify current claim formats
Repository identity formats can evolve. Consult the GitHub OIDC reference and the cloud provider's guidance rather than assuming a repository-name string is the only relevant identifier.
Capture the safe claim metadata from an authorised test run and compare it with the intended trust conditions. Where stable identifiers are available and supported, assess how they behave during repository renames or transfers. Don't guess at matching semantics from a token sample alone.
Record which conditions are mandatory and which are optional. A condition omitted during troubleshooting can become a permanent broadening of access if nobody reviews the final policy.
Keep an approved example of both an accepted identity and a rejected identity in the review record. Use synthetic claim values where possible. This makes later policy edits easier to assess without asking a reviewer to reconstruct the entire trust model from memory. Link the expected outcome to a repeatable staging test.
Keep the cloud role narrow
Limit the role to the deployment resources and actions needed. Separate staging and production where appropriate. Short-lived credentials still have the power of their role for the time they are valid.
Also review workflow permissions. Grant the ability to request an identity token only where it is needed, alongside minimal repository permissions. A job that merely checks formatting shouldn't inherit production deployment access.
Protect production environments through the platform's supported controls and your release process. An approval gate and a narrow trust policy solve different problems. Test that the gate and policy both apply to the job that actually receives credentials.
Remove static credentials after proving the new path
Use an authorised staging run to validate the exchange and intended operations. Confirm that forbidden operations fail. Then update the release workflow and remove or revoke the replaced static credential through the provider's process.
Don't leave both methods active indefinitely without a documented reason. An old credential forgotten in a repository or runner can undermine the benefit of federation. Track cleanup as a release task rather than an optional follow-up.
Use JSON Diff on sanitised trust-policy revisions where the policy is JSON. Review changed conditions and allowed actions, not just whether the document parses. Valid JSON can describe an unsafe policy.
Test negative identities and untrusted inputs
Test a non-production branch, an unapproved environment, and a separate test repository. Each should receive only the access the contract permits. Record the observed cloud outcome and avoid using production resources for exploratory checks.
Review what code runs before and after credential acquisition. A narrow token identity doesn't help if the job executes untrusted code with those credentials. See untrusted pull-request workflow safety for that separate CI boundary.
Preserve audit evidence tying the deployment to the job and role. Exclude live tokens from logs. Troubleshooting should explain the identity decision without creating another copy of usable credentials.
Conclusion
OIDC removes one secret-management burden while making trust configuration central. Verify current claims, constrain accepted identities, narrow the cloud role, and test denied cases. Remove the replaced credential only after the new path works, and keep untrusted code away from privileged jobs.