すべてのGitHub Actionsワークフロー実行は、GitHubがホストするイシュアー(https://token.actions.githubusercontent.com)から署名付きIDトークンをリクエストできます。「Workload Identity Federation」(ワークロードアイデンティティフェデレーション)を使用すると、ワークフローはそのトークンを短期間有効なAnthropicアクセストークンと交換できるため、リポジトリにANTHROPIC_API_KEYシークレットを保存することなく、CIジョブからClaude APIを呼び出すことができます。
トークンのsubクレームは、リポジトリとトリガーコンテキストをエンコードします。ブランチへのプッシュの場合、repo:<owner>/<repo>:ref:refs/heads/<branch>という形式になります。プルリクエストの実行ではrepo:<owner>/<repo>:pull_requestが使用され、環境でゲートされたデプロイメントではrepo:<owner>/<repo>:environment:<name>が使用されます。フェデレーションルールは、このクレーム(およびrepository_ownerやrefなどの他のクレーム)と照合して、どのワークフロー実行に認証を許可するかを決定します。
id-token: write権限を付与できるGitHubリポジトリ。GitHubは、明示的にリクエストしたジョブにのみIDトークンを発行します。ワークフローレベルまたはジョブレベルでid-token: write権限を追加してください。
permissions:
id-token: write
contents: readジョブ内では、ランナーが2つの環境変数ACTIONS_ID_TOKEN_REQUEST_URLとACTIONS_ID_TOKEN_REQUEST_TOKENを公開します。リクエストトークンをベアラー認証情報として、選択したオーディエンスをクエリパラメータとしてリクエストURLを呼び出し、返された「JSON Web Token」(JSONウェブトークン)、すなわちJWTをファイルに書き込みます。
- name: Fetch GitHub OIDC token
run: |
curl -sS -H "Authorization: Bearer $ACTIONS_ID_TOKEN_REQUEST_TOKEN" \
"$ACTIONS_ID_TOKEN_REQUEST_URL&audience=https://api.anthropic.com" \
| jq -r .value > /tmp/gha-jwtJavaScriptを使用する場合、actions/github-scriptはcore.getIDToken(audience)を通じて同じ機能を提供します。
- name: Fetch GitHub OIDC token
uses: actions/github-script@v8
with:
script: |
const fs = require('fs');
const token = await core.getIDToken('https://api.anthropic.com');
fs.writeFileSync('/tmp/gha-jwt', token);デコードされたトークンには、ワークフロー実行を記述するクレームが含まれています。フェデレーションルールはこれらと照合します。
{
"iss": "https://token.actions.githubusercontent.com",
"sub": "repo:your-org/your-repo:ref:refs/heads/main",
"aud": "https://api.anthropic.com",
"repository": "your-org/your-repo",
"repository_owner": "your-org",
"ref": "refs/heads/main",
"sha": "abc123...",
"workflow": "CI",
"actor": "octocat",
"event_name": "push"
}sub形式の完全なリストについては、GitHubのOIDCサブジェクトクレームリファレンスを参照してください。
セットアップウォークスルーに従って、Claude Consoleでフェデレーションイシュアーを登録し、Anthropicサービスアカウントを作成し、フェデレーションルールを作成します。以下のGitHub Actions固有の値を使用してください。
フェデレーションイシュアー: GitHubはOIDCディスカバリドキュメントとJWKSを公開しているため、ディスカバリモードを使用します。GitHubがキーをローテーションすると、Anthropicは自動的にキーを更新します。
{
"name": "github-actions",
"issuer_url": "https://token.actions.githubusercontent.com",
"jwks_source": "discovery"
}フェデレーションルール: 信頼する予定のワークフロー実行のみに一致させます。これらのクレームを安全にスコープ設定する方法については、認証できるワークフローを制限するを参照してください。
{
"name": "gha-main",
"issuer_id": "fdis_...",
"match": {
"subject_prefix": "repo:your-org/your-repo:ref:refs/heads/main",
"audience": "https://api.anthropic.com",
"claims": {
"repository_owner": "your-org"
}
},
"target": {
"type": "service_account",
"service_account_id": "svac_..."
},
"workspace_id": "wrkspc_...",
"oauth_scope": "workspace:developer",
"token_lifetime_seconds": 600
}ワークロードが許す限り具体的に指定してください。subject_prefixをrepo:your-org/your-repo:*に緩める(claims.ref制約と組み合わせる)のは、ルールが同じリポジトリからの複数のイベントタイプに一致する必要がある場合のみにしてください。subの末尾セグメントは、ref:...、environment:...、pull_requestイベントの間で異なるためです。
ジョブにフェデレーション環境変数を設定し、通常どおりSDKを呼び出します。Anthropic()はANTHROPIC_IDENTITY_TOKEN_FILEを読み取り、最初のリクエストでJWTを交換し、有効期限が切れる前にアクセストークンを自動的に更新します。
import anthropic
# ANTHROPIC_FEDERATION_RULE_ID、ANTHROPIC_ORGANIZATION_ID、
# ANTHROPIC_SERVICE_ACCOUNT_ID、ANTHROPIC_WORKSPACE_ID、ANTHROPIC_IDENTITY_TOKEN_FILE を
# ジョブ環境から読み取ります。
client = anthropic.Anthropic()
message = client.messages.create(
model="claude-sonnet-4-6",
max_tokens=1024,
messages=[{"role": "user", "content": "Hello, Claude"}],
)
print(message.content[0].text)GitHubが発行する各IDトークンは、発行後約5分で有効期限が切れます。トークンリクエストエンドポイント(ACTIONS_ID_TOKEN_REQUEST_URL)はジョブ全体を通じて有効なため、いつでも新しいトークンを取得できます。SDKは初回使用時にトークンを交換し、結果として得られるAnthropicアクセストークンをキャッシュします。Anthropicトークンの有効期間よりも長く実行されるジョブの場合、SDKは更新のたびにANTHROPIC_IDENTITY_TOKEN_FILEを再読み込みするため、取得ステップを定期的に再実行する(またはバックグラウンドループでラップする)ことでファイルを最新の状態に保ってください。あるいは、ファイルパスを使用する代わりに、ACTIONS_ID_TOKEN_REQUEST_URLを直接呼び出すトークンプロバイダーコールバックをSDKに渡すこともできます。
交換が成功すると、sk-ant-oat01-で始まるaccess_tokenと、秒単位のexpires_in値が返されます。400 invalid_grantが発生した場合は、失敗した交換のトラブルシューティングを参照してください。GitHub Actions側で最も一般的な原因は、subクレームの形式が一致しないことです(末尾セグメントはref:...、environment:...、pull_requestイベントの間で異なります)。
repo:your-org/*というsubject_prefixだけでは、組織内のすべてのリポジトリに一致し、ref制約がない場合はフォークからトリガーされたpull_request実行にも一致します。一致するリポジトリに対してプルリクエストを開くことができる人なら誰でも、フェデレーションされたAnthropicトークンを取得できてしまいます。
ルールのmatchブロックを、ユースケースに適した最も狭いスコープにロックしてください。
subject_prefix: "repo:your-org/your-repo:*"を使用して、組織内の他のリポジトリが一致しないようにします。claimsの下に"ref": "refs/heads/main"(またはリリースブランチ)を追加して、プルリクエスト実行やフィーチャーブランチが一致しないようにします。sub解析のエッジケースに対する多層防御として、claimsの下に"repository_owner": "your-org"を追加します。subject_prefix: "repo:your-org/your-repo:environment:production"に一致させ、GitHubでその環境に必須レビュアーを設定してゲートします。Was this page helpful?