Hands-on: connect GitHub Actions to Azure, AWS and Google Cloud without stored keys

Abstract cover on a deep navy background: a single point of light on the right splits into three glowing ribbons in blue, amber and teal, each ending at a softly glowing ring, suggesting one trusted handshake reaching three clouds.

A deployment pipeline that holds a long-lived cloud key is one leaked log away from an incident. GitHub Actions can instead ask Azure, AWS or Google Cloud for short-lived credentials using an OpenID Connect token. This walkthrough sets that up on all three clouds from the official documentation.

Level: Developer. Format: Hands-on Learning. If the idea is new to you, read our explainer Workload identity federation: cloud access without stored keys first.

What is it?

Think of a hotel that phones the front desk of your company to confirm who you are, instead of asking you to carry a master key. Each workflow run gets a signed token from https://token.actions.githubusercontent.com. The cloud checks three fields in it: the issuer, the audience and the subject (which repository, branch or environment is asking). If all three match a trust rule you created, it hands back credentials that expire on their own.

What changed?

Two details catch people who copy older guides. First, GitHub’s documentation now says repositories created after July 15, 2026, and repositories renamed or transferred after that date, use immutable subject claims that include owner and repository IDs, for example repo:octo-org@123456/octo-repo@456789:ref:refs/heads/main. Older repositories keep the name-only format unless they opt in. A trust rule written for the wrong format simply fails to match. Second, AWS IAM checks the role trust policy when you save it, requiring a token.actions.githubusercontent.com:sub condition whose value is not only a wildcard.

Diagram titled Keyless deploys from GitHub hinge on three fields each cloud must match. A GitHub Actions job box lists the workflow permission id-token: write, the issuer https://token.actions.githubusercontent.com, and subject examples for a branch and an environment. An arrow leads to three cards. Azure, Microsoft Entra federated credential: audience api://AzureADTokenExchange, exact subject match with no wildcards, up to 20 federated credentials per app or managed identity. AWS, IAM OIDC provider and role trust policy: audience sts.amazonaws.com, a condition on the sub claim that IAM rejects if it is only a wildcard, action sts:AssumeRoleWithWebIdentity. Google Cloud, workload identity pool and OIDC provider: mapping google.subject=assertion.sub, an attribute condition that limits tokens to your organization, and access by direct principalSet grant or service account impersonation. A note says repositories created after July 15, 2026 emit ID-based subjects.
The issuer, audience and subject each cloud checks before it exchanges a GitHub Actions token for credentials.

Before you start

  • Admin rights on one GitHub repository, ideally a test repository.
  • For each cloud you try: rights to create identities and role assignments in a sandbox subscription, account or project.
  • Cost and risk warning. AWS states that IAM is offered at no additional charge; we did not find an equivalent statement for the other two clouds, so check your own pricing pages. The real cost risk is what the credential can do: grant read-only access for this exercise, never Owner or AdministratorAccess. Workflow runs also use GitHub Actions minutes under your plan.

Step 1: allow the workflow to request a token

Add a permissions block with id-token: write and contents: read to the job. GitHub’s OpenID Connect concepts page notes this lets the job fetch a token but grants no write access to your resources. Use a GitHub environment, such as prod, with protection rules, so the subject names the environment rather than any branch.

Step 2: Azure

Create a Microsoft Entra app registration or a user-assigned managed identity, then add a federated credential with issuer https://token.actions.githubusercontent.com, audience api://AzureADTokenExchange and your exact subject. Microsoft’s trust configuration page says wildcards are not supported and allows up to 20 federated credentials per app or identity. Assign the Reader role on one resource group, store the client, tenant and subscription IDs as the secrets AZURE_CLIENT_ID, AZURE_TENANT_ID and AZURE_SUBSCRIPTION_ID, and call the azure/login action as shown in Microsoft Learn. The Learn sample uses v2; the action’s README marks v3 as the supported release.

Step 3: AWS

In the IAM console, add an OpenID Connect provider for token.actions.githubusercontent.com with audience sts.amazonaws.com. Create a role whose trust policy allows sts:AssumeRoleWithWebIdentity with StringEquals conditions on the audience and on your exact subject. Attach ReadOnlyAccess for the test. In the workflow, pass the role ARN as role-to-assume and a Region as aws-region to configure-aws-credentials, whose README says the Region is always required.

Step 4: Google Cloud

Following Google’s deployment pipelines guide, create a workload identity pool and an OIDC provider with the GitHub issuer, the mapping google.subject=assertion.sub and an attribute condition that limits tokens to your organization. The guide prefers mapping the numeric repository_id and repository_owner_id claims, because names can be reused by someone else. Grant a viewer role directly to the pool principal, or let it impersonate a service account where a product does not support principal sets. In the workflow, give google-github-actions/auth the full provider name as workload_identity_provider.

Step 5: test and clean up

Run a read-only command on each cloud, such as listing resource groups, calling aws sts get-caller-identity or listing projects. Then change the subject in one trust rule to a different environment name, rerun, and confirm the login is refused. Delete the test identities and role assignments when you finish.

Where is it heading? (analysis)

This is our analysis, not vendor roadmap. Subject formats are moving from names to stable IDs, and clouds are starting to reject loose trust rules at save time. Expect auditors to ask for an inventory of federated trusts, the way they once asked for an inventory of access keys.

What should I do?

  • Developers: replace one stored cloud secret in a pipeline this sprint, starting with a read-only job.
  • Platform teams: publish one approved trust template per cloud, keyed to environments, and check which subject format each repository emits.
  • Security teams: search for wildcard subjects and organization-wide trusts, and remove stored keys once federation works.

Join the discussion

Which cloud was hardest to federate from your pipelines, and did the new ID-based subject format break any of your trust rules? Share what you found in the comments.

Sources

Last verified: November 10, 2026

Leave a Reply