
Removing an AWS access key from GitHub does not make a deployment pipeline least privileged. An overly broad federation rule can still let an unintended workflow obtain production credentials. A narrowly trusted workflow can still deploy code into a workload with far more access than its deployment role appears to hold.
This guide treats GitHub Actions OIDC security as a deployment boundary across AWS or Azure. It assumes a team-controlled repository and a staged cloud environment. The configuration fragments are examples to adapt, not a complete production deployment. Acceptance requires both an approved workflow that succeeds and unintended callers that fail.
1. Inventory the deployment authority
Record the repository, workflow, triggering event, branch or tag, deployment environment, cloud identity, and target resources. Name the owners who can change workflow files, approve deployments, update federation trust, or assign cloud roles. Include reusable workflows and third-party actions in this inventory.
Start with one service and one environment. Give development and production separate deployment identities and resource scopes. A single role shared across repositories makes the review harder because each repository becomes a potential route to the same resources.
Trace indirect privileges. If a deployer can replace code running as an application identity, it may gain effective access to that application’s data or secrets. If it can alter a role assignment or attach a stronger identity, the apparent resource boundary can expand. Our AWS and Azure zero-trust engineering guide provides the wider flow inventory for this review.
2. Define which token claims the cloud will trust
OIDC allows the workflow to exchange an identity token for cloud credentials without storing a long-lived cloud password or access key. The cloud must validate the expected issuer, audience, and caller conditions. Authentication establishes the workload identity; the resulting cloud permissions determine what it can do.
Write the allowed deployment context before configuring trust. Avoid a repository-wide wildcard merely because it resolves a failed test. Check the exact subject format used by the repository. GitHub’s current documentation describes both older name-based subjects and newer subjects containing immutable owner and repository IDs. A copied example may therefore fail even when the visible repository name is correct.
The GitHub AWS OIDC guide documents audience and subject conditions. When a job uses an environment, its subject context differs from a branch-based job. Apply supported environment protection and deployment restrictions deliberately rather than assuming that an environment name proves a particular branch was reviewed.
Keep token evidence out of shared logs
Establish the necessary claim values through an approved inspection process. Record the selected non-secret claim fields and configuration version. Do not print complete identity tokens, cloud credentials, or bearer headers into build logs or paste them into external debugging sites.
3. Constrain AWS role assumption and permissions separately
Create or review the GitHub OIDC provider in the intended account, then define the deployment role’s trust policy. For the standard AWS credential exchange, the expected audience is sts.amazonaws.com. Match the intended subject explicitly using the format actually issued for the approved job.
The following is a condition fragment for that role’s trust policy, not a complete IAM policy. Replace the placeholder with the verified subject, including any immutable identifiers or environment context. Do not deploy the literal placeholder.
{
"Condition": {
"StringEquals": {
"token.actions.githubusercontent.com:aud": "sts.amazonaws.com",
"token.actions.githubusercontent.com:sub": "EXACT_APPROVED_JOB_SUBJECT"
}
}
}
The surrounding trust statement must name the intended federated provider and permit the appropriate web-identity role assumption operation. Follow AWS guidance for OIDC roles when constructing the complete statement. A trust policy answers who may assume the role; it does not grant deployment access by itself.
Build the role’s permissions from the deployment operations and target resources. Include any required role-passing permissions as a separate review item, with narrowly selected target roles. Do not use administrator access as a permanent workaround for a missing deployment action. Test the smallest workable policy in the staged account.
4. Bind Azure federation to a scoped deployment identity
For Azure, select a supported application identity or user-assigned managed identity and configure a federated identity credential for the intended external workload. Record its owner and the Azure role assignments separately. Adding federation establishes a credential path; it does not justify subscription-wide deployment rights.
Microsoft’s workload identity federation guidance requires the configured issuer, subject, and audience to match the presented token. Review case sensitivity and the actual subject format. A display name matching the repository is insufficient if the credential contains a different subject.
The GitHub Azure OIDC procedure recommends api://AzureADTokenExchange as the audience for its documented flow. Scope Azure RBAC to the intended resource group or resources where the deployment supports it. Review permissions that can change role assignments, managed identities, or the application configuration.
For a first pilot, verify the effective cloud identity with read-only inspection and then deploy a harmless change to a designated test resource. Do not grant broader rights just because the sign-in action succeeded but the deployment failed. Authentication and resource authorisation need separate diagnosis.
5. Protect the workflow that receives credentials
Grant id-token: write only to the jobs that need token issuance. Keep repository-token permissions minimal and review the interaction between build and deployment jobs. Token issuance permission does not itself grant AWS or Azure resource access; cloud trust and permissions remain the enforcement points.
Use the relevant supported cloud login action and verify its source. Pin third-party actions to reviewed full commit hashes and maintain an update process. Protect workflow changes with the repository’s review controls. Follow GitHub’s workflow security guidance for dependency and untrusted-code risks.
Do not execute untrusted pull-request code inside a job that can obtain production credentials. Review event types, checkout behaviour, artifact inputs, and reusable-workflow callers together. A deployment job can consume attacker-controlled output even when its own workflow file has not changed.
Where available for the repository and plan, require independent environment approval and restrict deployment branches or tags. Check who can bypass those rules or change the environment. An approval gate loses value if the same person can change the workflow and silently remove the gate.
6. Test permitted and forbidden deployment contexts
Run the approved workflow against a staged target and record the resulting cloud principal and permitted operation. Then test a deliberately unauthorised context within controlled repositories. Choose the negative cases from the threat model rather than relying only on a successful login.
- Approved job and environment: expected credential exchange and scoped deployment.
- Unapproved branch or deployment context: expected refusal by the configured boundary.
- Separate controlled repository: expected failure to obtain the production role.
- Correct identity requesting an unrelated resource: expected authorisation failure.
- Deployment role attempting to change trust or expand its own permissions: expected denial.
Identify the enforcement point for every failure. A workflow that never starts is evidence about repository controls, not proof that the cloud would reject its token. Likewise, a missing resource can produce an error without demonstrating a permissions boundary. Use known test resources and record the relevant cloud audit event.
Preserve workflow run identifiers, commit hashes, environment decisions, cloud principal identifiers, and request results. Link them to the approved trust and permission configuration. Unexpected successes require investigation even when the deployment itself was harmless.
7. Remove the old credential path after the pilot
Once approved deployment and rollback tests pass, retire the replaced long-lived credential through the normal change process. Check repository secrets, organisation secrets, external automation, and recovery procedures for dependencies. Leaving the old key active maintains an alternate entry point outside the new trust design.
Rollback should restore a specific reviewed configuration or deployment version. Avoid treating a permanent administrator key as the default recovery mechanism. Monitor changes to federation trust, workflow protections, and role assignments, then rerun boundary tests after material changes.
Keep recovery administration outside the application’s normal deployment authority. Use our ransomware resilience guide to review that separation, and the Entra ID hardening guide for the human administrators who control Azure identity configuration.
8. Frequently asked questions
Does OIDC prevent a compromised workflow from accessing the cloud?
It removes the need for a stored long-lived cloud credential in the supported flow. A compromised job that satisfies the configured trust conditions can still use its authorised access. Workflow integrity, narrow permissions, and tested boundaries remain necessary.
Why does a correct repository name still fail federation?
The actual token subject can include an environment, branch context, custom format, or immutable identifiers. Compare the issued claim with the configured condition instead of widening trust until the exchange succeeds.
Should AWS and Azure share one deployment identity?
Each platform needs its own supported trust and permission configuration. Keep their scopes and evidence separate, even when one reviewed workflow deploys to both. This makes failures and excessive access easier to attribute and correct.
9. Conclusion: prove the deployment boundary
A useful OIDC deployment design constrains the caller, protects the job, and limits its effective cloud authority. The evidence should show an approved deployment working and an unintended caller failing at the expected enforcement point.
For a review of federation trust, deployment privileges, and workload boundaries, see StackLocked Cloud Security consulting. Bring the workflow inventory and current cloud role assignments so the assessment can focus on actual production access.
Continue the engineering library
Entra ID App Permissions Audit: Microsoft 365 Service Principal Security →
Ransomware Recovery Testing: A Checklist for AWS and Azure →
Ransomware Resilience: Immutable Backups and Tested Recovery Engineering →
Zero-Trust Cloud Architecture: AWS, Azure and Microservice Isolation →
Microsoft 365 & Entra ID Hardening: Conditional Access to Privileged Identity →