BedrockでClaude Code Actionを実行するまで(OIDC)

日本には、Anthropicとの直接契約はないが、AWSとの契約はあるという開発環境が多く存在していると思います。この記事では、そのような環境でBedrock経由でClaude Code Actionを実行するための手順を記載します。公式のREADMEは5/24時点では不完全な状態で、issueを参照しながら必要な設定をまとめています。
~~READMEに書かれたymlの内容に過不足があったので、その内容を記録するためだけに記事を書いていたら、予想以上に前提やらを書くことになってしまった~~
ymlの設定だけが気になる方は「.github/workflows の設定」を見てください。
また、どんな感じのことができるか、については「おためし実行」を見てください。

# 前提の整理

**Claude Code Action** とは、Claude CodeをGitHub Actionで動かして、issueからPRを作成させたり、その他Claude Codeで可能なことをGitHubで発生するイベントをトリガーとしてGitHub Actionの環境で実行させるものです。
https://github.com/anthropics/claude-code-action

**Claude Code** は、利用者が任意の指示を与えることで、その指示をリモートに存在するClaudeに送信してClaudeにそれを実現するための作業を考えさせ、その作業や求められたソースコードの内容などをClaudeに追加で送信することを繰り返して指示を実現する、という仕組みです。Claude CodeのクライアントはPCなどで動作し、そのPCにあるリポジトリの内容などをClaudeに送信しながら、Claudeに解析処理を行わせ、必要であればPC内のソースコードを編集し、（ローカルで）commitすることもできます。^[ちなみに、Claude Codeを（GitHub Actionを使わずに）Bedrockで動作させる方法については [AI コーディングアシスタント Claude Code を Amazon Bedrock で試してみた](https://zenn.dev/morisawa/articles/claude-code-bedrock) という記事に記載があります。ただし、GitHub Actionの環境を構築するうえでは、ここに書かれている設定をする必要は一切ありません。]
ただし、Claude CodeはPCなどで動作するものなので、単独ではGitHubのイベントをトリガーにして動作することはありません。通常のClaude Codeの利用においては、人間がissueに対応するにあたってローカルでClaude Codeを実行する、といったことが想定されています。
そこで、GitHub Actionによって、GitHubのイベントをトリガーにして、GitHub Actionで用意されるDocker環境でClaude Codeを動かし、そこからClaudeに通信させる、というのがClaude Code Actionのやりたいことです。例えば、GitHubにissueを立てて`@claude`というようにメンションすれば、GitHub Actionによってbotがそれっぽく応答して、それっぽく対応してPR作成（の手前）までやってくれる、ということになります。

**Claude** は、Anthropicが提供しているAIの名前です。ClaudeはAnthropicのAPIで直接利用することができますが、AWSの提供しているBedrock、Googleの提供しているVertexなどのいくつかのモデルをまとめたインターフェイスを経由して呼ぶこともできます。今回は、AWSでの契約がすでにあり、Bedrockを使ってClaudeを呼ぶ場合を対象としています。

## 連携の仕様・制約

Claude Code ActionでBedrockを利用するには、それを利用するための権限と認証が必要になります。具体的には、AWS側でIAMロールを作成し、このIAMロールをOIDCによってGitHub Action側で利用できるように設定する必要があります。また、このOIDCを利用するために、**GitHub Appをカスタムで作成する必要があります。**

## 概念的な連携の整理

連携を概念的に整理すると以下のようになります。^[実際にはGitHubの操作をするために必要なトークンの作成などもやっていますが、省略しています。なお、5/25 7:00時点のREADMEではOIDCの説明においてカスタムアプリの設定も書いてありますが、カスタムアプリの設定は必要ありません。]

![](https://storage.googleapis.com/zenn-user-upload/8898bf7ca2c5-20250525.png)

# 必要な設定

それでは、実際に必要な設定について説明していきます。

## AWS側での設定

### BedrockおよびClaudeを利用可能にする

もしBedrockでClaudeを利用したことがない場合は、Claudeを利用可能にするための申請が必要になります。

【重要】リージョンについてはus-west-2が無難かもしれません。2025/5/25時点ではcross-region inferenceによってap-northeast-1でもあまり問題がない可能性があります。

手順については、[Amazon BedrockのIAMポリシーとユースケースの詳細を申告してからチャットを試すまで](https://qiita.com/mkin/items/2f60566d15777557d533)などに記載があります。
※最新のUIでは内容が変わっている可能性があります。

（なお、これはうろ覚えですが、最初にinference profileを利用するときに、inference profileを使う設定を管理画面で行ったような記憶があります。ひょっとすると今は必要ないかも？）

### OIDCプロバイダとしてGitHubを登録する

OIDCを利用するためには、AWS側でGitHub(GitHub Actions)をプロバイダとして登録する必要があります。手順は以下を参照してください。
[GitHub Actions で OIDC を使用して AWS 認証を行う](https://zenn.dev/kou_pg_0131/articles/gh-actions-oidc-aws)
※最新のUIでは内容が変わっている可能性があります。

この手順で、次のIAMロール登録で利用する信頼関係の `oidc-provider/token.actions.githubusercontent.com` が利用できるようになります。

### IAMロールを登録する

以下のポリシーおよび信頼関係を持つIAMロールを作成します。

ポリシー：
```json
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": [
                "bedrock:InvokeModel",
                "bedrock:InvokeModelWithResponseStream"
            ],
            "Resource": "*"
        }
    ]
}
```

信頼関係：「123456789012」の部分にはアカウントID（ハイフン無し）を入力します。
```json
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "RoleForGitHubActions",
            "Effect": "Allow",
            "Principal": {
                "Federated": "arn:aws:iam::123456789012:oidc-provider/token.actions.githubusercontent.com"
            },
            "Action": "sts:AssumeRoleWithWebIdentity",
            "Condition": {
                "StringEquals": {
                    "token.actions.githubusercontent.com:aud": "sts.amazonaws.com"
                },
                "StringLike": {
                    "token.actions.githubusercontent.com:sub": "repo:uniaim-ticket/*:*"
                }
            }
        }
    ]
}
```

登録が完了したら、ロールのARNをコピーしておきます。ARNは
`arn:aws:iam::123456789012:role/ROLE_NO_NAMAE_DAYO`
のような形式です。

## GitHubのWebでの設定

### ClaudeのGitHub Appをインストールする

対象のリポジトリまたはorganizationにClaudeをインストールします。
https://github.com/apps/claude

なお、このアプリの代わりにカスタムアプリを自作して、それを利用することもできます。（おまけに記載）

### シークレット「AWS_ROLE_TO_ASSUME」を設定する

対象のリポジトリのシークレット「AWS_ROLE_TO_ASSUME」に、先程作成したロールのARNを入力します。以下のような形式になっているはずです。
`arn:aws:iam::123456789012:role/ROLE_NO_NAMAE_DAYO`

## .github/workflows の設定

ここまでの設定ができたら、GitHub Actionsを設定していきます。リポジトリに.github/workflowsが存在しなければフォルダを作成し、任意の名前（たとえばclaude.yml）で以下のようなymlを作成します。
注意事項として、リージョン指定している箇所が2箇所あります。us-west-2としており、またcross region inferenceで使用しているモデルのIDもusのものとなっています。リージョンを変更する場合はこれらに注意してください。

```yml:claude.yml
name: Claude Assistant
on:
  issue_comment:
    types: [created]
  pull_request_review_comment:
    types: [created]
  issues:
    types: [opened, assigned]
  pull_request_review:
    types: [submitted]

jobs:
  claude-code-action:
    if: |
      (github.event_name == 'issue_comment' && contains(github.event.comment.body, '@claude')) ||
      (github.event_name == 'pull_request_review_comment' && contains(github.event.comment.body, '@claude')) ||
      (github.event_name == 'pull_request_review' && contains(github.event.review.body, '@claude')) ||
      (github.event_name == 'issues' && contains(github.event.issue.body, '@claude'))
    runs-on: ubuntu-latest
    env:
      ANTHROPIC_BEDROCK_BASE_URL: "https://bedrock-runtime.us-west-2.amazonaws.com"
    permissions:
      contents: read
      pull-requests: read
      issues: read
      id-token: write
    steps:
      - name: Checkout repository
        uses: actions/checkout@v4
        with:
          fetch-depth: 1

      - name: Configure AWS Credentials (OIDC)
        uses: aws-actions/configure-aws-credentials@v4
        with:
          role-to-assume: ${{ secrets.AWS_ROLE_TO_ASSUME }}
          aws-region: us-west-2

      - uses: anthropics/claude-code-action@beta
        with:
          model: "us.anthropic.claude-sonnet-4-20250514-v1:0"
          use_bedrock: "true"

```

ここまでの設定をしてpushすると、Claude Code Actionが実際に動作するようになります。地味に重要なのが`ANTHROPIC_BEDROCK_BASE_URL`で、これがないと動きません、、、

**なお、OIDCのためにid-tokenの権限が必要ですが、カスタムアプリを使わない場合はactions/create-github-app-token@v2を明示的に利用してトークン生成する必要はありません（claude-code-actionが勝手にやってくれる）。**

# おためし実行

## PRレビューコメント

実際に動かしてみます。上記の変更を含むPRを作成して`@claude`を含むPRレビューのコメントを作成するか、または上記の変更をデフォルトブランチに取り込んで`@claude`を含むissueを作成すると、Claude Code Actionが起動します。
この記事を作成するためにwriteやreadの権限を試していた箇所について、Claude Code Actionに説明させた場合の例は次のとおりです。まず命令に対してTODOリストを作成して、そのTODOを実行していくという形でClaude Codeのタスクが進行して、最終的な回答がコメントに記載されます。（少なくともこのPRの中の）コミット履歴も追いかけてコメントしてくれるようです。

![](https://storage.googleapis.com/zenn-user-upload/1c74382054d0-20250525.png)

![](https://storage.googleapis.com/zenn-user-upload/b77c38dcd575-20250525.png)

なお、このissueの実行に際してのコストなどはGitHubのActionタブで確認できます。（単位は米ドル）

![](https://storage.googleapis.com/zenn-user-upload/0030fedb0918-20250525.png)

## issueに対応させる

issueを作って、issue内での言及またはissueコメントでの言及によってClaude Code Actionを動かしてみます。カスタムアプリを使ったので若干見た目が違いますが、以下のように対応してくれます。

### issueにコメントをつけて指示

![](https://storage.googleapis.com/zenn-user-upload/bad76dfe07a9-20250525.png)

Create PRのリンクで、メッセージが入力された状態のPRを作成できます。

### PRを修正

上記のPRを作成したところ、eslint(prettier)でエラーになったので、エラーを修正させます。これで実際に直りました。

![](https://storage.googleapis.com/zenn-user-upload/f6f08888a92a-20250525.png)

![](https://storage.googleapis.com/zenn-user-upload/4df5738ea1e6-20250525.png)

# おまけ（カスタムアプリ）

Claude Code Actionの連携先としてカスタムアプリを指定することで、GitHub上に出てくるアプリ名やアイコンなどを自由に変更できます。

## GitHub側の設定（カスタムアプリ）

カスタムアプリを登録して、秘密鍵を生成します。
このアプリを使いたいリポジトリ（またはorganization）にインストールします。

## GitHub側の設定（シークレット）

APP_IDとAPP_PRIVATE_KEYを登録します。なお、このシークレット名は後述のymlと一緒のものを使っていればなんでもいいです。
APP_IDはカスタムアプリのID（数字で7桁ぐらいのもの）、APP_PRIVATE_KEYは`-----BEGIN RSA PRIVATE KEY-----`から始まる秘密鍵の内容すべて（-----BEGINや-----ENDも含む全ての行）です。

## ymlの編集

claude.yml（または任意の名称）として保存しているymlに、以下の内容を`- uses: anthropics/claude-code-action@beta`の前に追加し、また`use_bedrock: "true"`の次の行にgithub_tokenの設定を追加します。


```yml:anthropics/claude-code-action@betaの前
      - name: Generate 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 }}
```


```yml:use_bedrockの次の行
          github_token: "${{ steps.app-token.outputs.token }}"
```

ymlの編集が終わったら、pushします。これでカスタムアプリで動作するようになります。