Skip to content

GitHub Actions with cloud providers

Route claude-code-action through Amazon Bedrock, Google Cloud's Agent Platform or Microsoft Foundry using OIDC, with no long-lived cloud keys in the repo.

Out of the box, Claude Code GitHub Actions calls the Claude API with an API key or subscription token. If your organisation buys Claude through a cloud provider, you can send inference there instead. The workflow proves who it is with GitHub's OpenID Connect (OIDC) token, your cloud swaps that for short-lived credentials, and nothing long-lived sits in your repository secrets.

This page assumes you already understand the basic workflow and only covers what changes.

Pick the provider

Use whichever cloud already has Claude model access for your organisation. One input on the action selects it:

ProviderInput
Amazon Bedrockuse_bedrock: "true"
Google Cloud's Agent Platformuse_vertex: "true"
Microsoft Foundryuse_foundry: "true"

What you need first

  • Repository admin, to install an app and add secrets.
  • Rights to create identity resources in the cloud: IAM roles and OIDC providers on AWS; Workload Identity Federation resources and service accounts on Google Cloud; Entra applications on Azure.
  • Claude model access:
    • Bedrock: access granted to the Claude models. Cross-region inference profiles (the us. style IDs) need access in every region of the group. See Amazon Bedrock.
    • Agent Platform: a project with the Agent Platform API enabled and Claude access. See Google Cloud's Agent Platform.
    • Foundry: a resource with a Claude deployment. See Microsoft Foundry.

Step 1: choose how the action talks to GitHub

The action needs a GitHub identity to push commits and comment. With a cloud provider you pick it yourself:

OptionTrade-off
Official Claude GitHub AppEasiest; install it on the repo. Comes with its full shared permission set
Your own GitHub AppLeast privilege: only Contents, Issues and Pull requests (read and write). More setup
The built-in GITHUB_TOKENNothing to install, but GitHub will not trigger CI on commits it makes

To create your own app, register a new GitHub App with webhooks disabled (they are not used), grant the three permissions above, generate a private key (keep the .pem), note the App ID, and install it on the repository.

Step 2: make your cloud trust GitHub

All three providers trust the issuer https://token.actions.githubusercontent.com. Lock trust down to your repository in every case.

Amazon Bedrock

Following AWS's guide to OIDC identity providers:

  1. Add a GitHub OIDC provider: URL https://token.actions.githubusercontent.com, audience sts.amazonaws.com.
  2. Create an IAM role trusted by it as a web identity. Attach a scoped policy granting bedrock:InvokeModel, bedrock:InvokeModelWithResponseStream, bedrock:ListInferenceProfiles and bedrock:GetInferenceProfile, plus the two aws-marketplace subscription actions described in the Bedrock IAM section.
  3. In the trust policy, restrict the subject, e.g. repo:northwind/api:*. GitHub's OIDC hardening guide explains the claim format.

Record the role ARN.

Google Cloud's Agent Platform

Following Google's Workload Identity Federation docs:

  1. Enable IAM Credentials, Security Token Service and the Agent Platform API (aiplatform.googleapis.com).
  2. Create a Workload Identity Pool with a GitHub OIDC provider (issuer as above) and an attribute condition limiting it to your repository.
  3. Create a dedicated service account with only roles/aiplatform.user (Vertex AI User) and let the pool impersonate it.

Record the provider's full resource name and the service account email.

Microsoft Foundry

Following Microsoft's guide to authenticating from GitHub Actions:

  1. Register an Entra application (or use a user-assigned managed identity) and add a federated identity credential trusting your repository's tokens.
  2. Give it the Azure AI User role on the Foundry resource, or a narrower custom role (see Foundry RBAC).

Record the client ID, tenant ID and subscription ID.

Step 3: add secrets

SecretForHolds
AWS_ROLE_TO_ASSUMEBedrockIAM role ARN
GCP_WORKLOAD_IDENTITY_PROVIDERAgent PlatformProvider resource name
GCP_SERVICE_ACCOUNTAgent PlatformService account email
AZURE_CLIENT_IDFoundryApplication client ID
AZURE_TENANT_IDFoundryEntra tenant ID
AZURE_SUBSCRIPTION_IDFoundrySubscription ID
APP_IDCustom GitHub AppApp ID
APP_PRIVATE_KEYCustom GitHub AppContents of the .pem

None of these is a long-lived cloud credential; they are identifiers. The private key belongs to your GitHub App, not your cloud.

Step 4: write the workflow

Every variant shares the same shape: trigger on @claude, check the commenter, get a GitHub token, sign in to the cloud with OIDC, run the action. The job must have id-token: write, or GitHub will not issue the OIDC token.

Warning: On a public repository, anyone can post a comment containing @claude. The action checks write access, but only after earlier steps have minted an app token and signed in to your cloud, leaving audit log entries and burning minutes. Put a permission check first, as below.

Here is the Bedrock version in full:

name: claude-bedrock

on:
  issue_comment:
    types: [created]
  pull_request_review_comment:
    types: [created]
  issues:
    types: [opened]

permissions:
  contents: write
  pull-requests: write
  issues: write
  id-token: write

jobs:
  claude:
    if: >
      contains(github.event.comment.body || '', '@claude') ||
      contains(github.event.issue.body || '', '@claude') ||
      contains(github.event.issue.title || '', '@claude')
    runs-on: ubuntu-latest
    timeout-minutes: 30
    steps:
      - name: Require write access
        env:
          GH_TOKEN: ${{ github.token }}
          ACTOR: ${{ github.actor }}
        run: |
          perm=$(gh api "repos/${{ github.repository }}/collaborators/$ACTOR/permission" --jq .permission)
          case "$perm" in admin|maintain|write) ;; *) echo "No write access for $ACTOR"; exit 1;; esac

      - uses: actions/checkout@v6

      - name: GitHub App token
        id: app-token
        uses: actions/create-github-app-token@v2
        with:
          app-id: ${{ secrets.APP_ID }}
          private-key: ${{ secrets.APP_PRIVATE_KEY }}

      - name: AWS credentials via OIDC
        uses: aws-actions/configure-aws-credentials@v4
        with:
          role-to-assume: ${{ secrets.AWS_ROLE_TO_ASSUME }}
          aws-region: eu-west-1

      - uses: anthropics/claude-code-action@v1
        with:
          github_token: ${{ steps.app-token.outputs.token }}
          use_bedrock: "true"
          claude_args: "--model eu.anthropic.claude-sonnet-4-6 --max-turns 15"

The credentials step exports AWS_REGION for the rest of the job. Bedrock model IDs carry a cross-region prefix (us., eu. and so on); use the one for the region group where you have access.

Swapping the cloud step for Agent Platform

Replace the AWS step and the action step with:

      - name: Google Cloud auth
        id: auth
        uses: google-github-actions/auth@v2
        with:
          workload_identity_provider: ${{ secrets.GCP_WORKLOAD_IDENTITY_PROVIDER }}
          service_account: ${{ secrets.GCP_SERVICE_ACCOUNT }}

      - uses: anthropics/claude-code-action@v1
        with:
          github_token: ${{ steps.app-token.outputs.token }}
          use_vertex: "true"
          claude_args: "--model claude-sonnet-5 --max-turns 15"
        env:
          ANTHROPIC_VERTEX_PROJECT_ID: ${{ steps.auth.outputs.project_id }}
          CLOUD_ML_REGION: europe-west1

The project ID comes from the auth step's output, so you do not hard-code it. Set CLOUD_ML_REGION to your region.

Swapping the cloud step for Foundry

      - name: Azure login
        uses: azure/login@v2
        with:
          client-id: ${{ secrets.AZURE_CLIENT_ID }}
          tenant-id: ${{ secrets.AZURE_TENANT_ID }}
          subscription-id: ${{ secrets.AZURE_SUBSCRIPTION_ID }}

      - uses: anthropics/claude-code-action@v1
        with:
          github_token: ${{ steps.app-token.outputs.token }}
          use_foundry: "true"
          claude_args: "--model claude-sonnet-5 --max-turns 15"
        env:
          ANTHROPIC_FOUNDRY_RESOURCE: northwind-ai-uks

ANTHROPIC_FOUNDRY_RESOURCE is your Foundry resource name; Claude Code builds the endpoint from it. The azure/login step signs in with OIDC, and Claude Code picks the credentials up through Azure's default credential chain. Use a model ID that matches a deployment in that resource.

If you chose a different GitHub identity

  • Official Claude GitHub App: delete the app token step and the github_token line.
  • Built-in token: delete the app token step and set github_token: ${{ secrets.GITHUB_TOKEN }}.

In every variant, --max-turns in claude_args keeps runs and spend bounded. See GitHub Actions cost tips.

Step 5: test

Comment @claude on an issue or PR and watch the run under the repository's Actions tab. Claude replies on the same thread.

Troubleshooting

Authentication failures are nearly always OIDC configuration:

  • Is id-token: write present?
  • Does the trust condition match the repository exactly (owner and name, case included)?
  • Do the secret names in the workflow match the ones you created?

Triggers or CI misbehaving work the same as with the Claude API; see the GitHub Actions troubleshooting.