Claude Platform Docs
管理IDプロバイダー

Google Cloud で WIF を使用する

静的なAPIキーの代わりに Google 署名付き ID トークンを使用して、Google Cloud ワークロード(Cloud Run、Cloud Functions、App Engine、GCE、GKE)を Claude API にフェデレーションします。

インスタンスメタデータサーバーにアクセスできる Google Cloud のコンピュート環境(Cloud Run、Cloud Functions、App Engine、Compute Engine(GCE)、および Workload Identity を有効にした GKE)であれば、アタッチされたサービスアカウント用の Google 署名付き ID トークンをリクエストできます。トークンの発行者(issuer)は https://accounts.google.com であり、Anthropic は標準の OIDC ディスカバリーを通じてこれを直接検証できるため、Google Cloud 側で追加の設定は必要ありません。

このガイドでは、Google の発行者を Anthropic に登録し、Google サービスアカウントを Anthropic サービスアカウントにバインドし、ワークロードが自身の ID トークンを有効期間の短い Claude API アクセストークンと交換する方法を説明します。

前提条件

  • WIF の概念(サービスアカウント、フェデレーション発行者、フェデレーションルール)を理解していること。
  • Cloud Run、Cloud Functions、App Engine、Compute Engine、または GKE 上でワークロードが稼働している Google Cloud プロジェクト。
  • そのワークロードにアタッチされたユーザー管理の Google サービスアカウント(Compute Engine のデフォルトサービスアカウントではないもの)。
  • Anthropic 組織の Claude Console でサービスアカウント、フェデレーション発行者、フェデレーションルールを作成する権限。

Google Cloud を設定する

Google は、サービスアカウントがアタッチされたすべてのワークロードに対して ID トークンを自動的に発行します。Google 側では適切なサービスアカウントをアタッチする以外に有効化すべきものはありませんが、標準のコンピュート環境と GKE では手順が若干異なります。

専用のサービスアカウントをサービスまたはインスタンスにアタッチします。

CLI
gcloud run deploy my-service \
  --service-account inference-worker@my-project.iam.gserviceaccount.com

ワークロード内では、メタデータサーバーがオンデマンドで署名付き ID トークンを返します。Anthropic 側に登録する予定の audience を指定してリクエストし、レスポンスに email クレームが含まれるように format=full を付けてください。

GET http://metadata.google.internal/computeMetadata/v1/instance/service-accounts/default/identity?audience=https://api.anthropic.com&format=full
Metadata-Flavor: Google

または、gcloud CLI を使用する場合:

CLI
gcloud auth print-identity-token \
  --audiences="https://api.anthropic.com" \
  --include-email

SDK での同等の処理はトークンを取得して使用するに示しています。

デコードしたトークンのペイロードは次のようになります。

{
  "iss": "https://accounts.google.com",
  "aud": "https://api.anthropic.com",
  "sub": "104892...",
  "azp": "104892...",
  "email": "inference-worker@my-project.iam.gserviceaccount.com",
  "email_verified": true,
  "exp": 1775527120
}

sub クレームは Google サービスアカウントの不透明な数値の一意 ID です。email クレームは人間が読めるサービスアカウントのアドレスです。フェデレーションルールでは subemail の両方でマッチさせてください。

Anthropic を設定する

Claude Console で Settings → Workload identity を開き、Connect workload をクリックして Google Cloud タイルを選択します。ウィザードに従って、発行者の登録、サービスアカウントの作成、フェデレーションルールの作成を行います。

ウィザードがこれらのリソースを作成します。ウィザードに入力する場合でも、Admin APIに送信する場合でも、以下の値を使用してください。

フェデレーション発行者: Google は OIDC ディスカバリードキュメントを公開しているため、ディスカバリーモードを使用します。この単一の発行者で、すべての Google Cloud サーフェス(Cloud Run、GCE、Cloud Functions、App Engine、および Workload Identity を有効にした GKE)をカバーできます。ワークロードの区別は発行者ではなくルールで行ってください。

{
  "name": "gcp",
  "issuer_url": "https://accounts.google.com",
  "jwks": { "type": "discovery" }
}

フェデレーションルール: sub クレームと email クレームの両方でマッチさせます。email は読みやすいサービスアカウントのアドレスです。sub はサービスアカウントの数値の一意 ID で、Google はこれを再利用しないため、固定しておくことで、サービスアカウントが削除され、後に同じメールアドレスで新しいものが作成された場合でもルールを保護できます。一意 ID は gcloud iam service-accounts describe SA_EMAIL --format='value(uniqueId)' で確認できます。

{
  "name": "gcp-inference-worker",
  "issuer_id": "fdis_...",
  "match": {
    "audience": "https://api.anthropic.com",
    "claims": {
      "sub": "104892101234567890123",
      "email": "inference-worker@my-project.iam.gserviceaccount.com"
    }
  },
  "target": {
    "type": "service_account",
    "service_account_id": "svac_..."
  },
  "workspace_id": "wrkspc_...",
  "oauth_scope": "workspace:developer",
  "token_lifetime_seconds": 600
}

トークンを取得して使用する

Google Cloud ワークロード内で、メタデータサーバーから ID トークンを取得し、POST /v1/oauth/token で交換し、返されたベアラートークンを使用して Claude API を呼び出します。以下の例に示すように、メタデータサーバーから新しい ID トークンを返すトークンプロバイダーの callable を指定すると、各 Anthropic SDK が交換と更新のループを自動的に処理します。

import os
import anthropic
import google.auth.transport.requests
import google.oauth2.id_token
from anthropic import WorkloadIdentityCredentials

AUDIENCE = "https://api.anthropic.com"


def fetch_google_identity_token() -> str:
    request = google.auth.transport.requests.Request()
    return google.oauth2.id_token.fetch_id_token(request, AUDIENCE)


client = anthropic.Anthropic(
    credentials=WorkloadIdentityCredentials(
        identity_token_provider=fetch_google_identity_token,
        federation_rule_id=os.environ["ANTHROPIC_FEDERATION_RULE_ID"],
        organization_id=os.environ["ANTHROPIC_ORGANIZATION_ID"],
        service_account_id=os.environ["ANTHROPIC_SERVICE_ACCOUNT_ID"],
        workspace_id=os.environ.get("ANTHROPIC_WORKSPACE_ID"),
    ),
)

message = client.messages.create(
    model="claude-opus-5",
    max_tokens=1024,
    messages=[{"role": "user", "content": "Hello from Cloud Run"}],
)
print(next(block.text for block in message.content if block.type == "text"))

Google の ID トークンはおよそ 1 時間で有効期限が切れます。SDK は有効期限が切れる前にトークンプロバイダーを再度呼び出し、自動的に再交換します。アクセストークンの expires_in よりも長く実行されるシェルスクリプトでは、タイマーで更新し、交換を繰り返してください。

セットアップを検証する

ワークロード内から ID トークンをデコードし、クレームがルールと一致していることを確認します。

cURL
curl -sS -H "Metadata-Flavor: Google" \
  "http://metadata.google.internal/computeMetadata/v1/instance/service-accounts/default/identity?audience=https://api.anthropic.com&format=full" \
  | jq -rR 'split(".")[1] | gsub("-";"+") | gsub("_";"/") | @base64d | fromjson'

isshttps://accounts.google.comaudhttps://api.anthropic.com であり、email がフェデレーションルールの値と一致していることを確認します。次に、前のセクションの交換を実行します。交換が成功すると、sk-ant-oat01- で始まる access_token と、秒単位の expires_in 値が返されます。交換が不透明な 401 authentication_error レスポンス(メッセージ Authentication failed)で失敗した場合は、認証履歴ページで拒否理由を確認し、失敗した交換のトラブルシューティングを参照してください。Google Cloud 側で最も一般的な原因は email クレームの欠落です(含まれるように format=full を付けてトークンをリクエストしてください)。

ルールのスコープを絞る

ルールの match ブロックは、ユースケースに適合する最も狭いスコープに固定してください。

  • sub を完全一致させる: claims.sub に完全な数値の一意 ID を設定し、Google トークンには subject_prefix を決して使用しないでください。
  • email クレームを固定する: sub に加えて claims.email を追加し、安定した ID と読みやすいアドレスの両方が一致する必要があるようにします。
  • audience を固定する: audience をメタデータサーバーにリクエストする値と正確に一致させ、他の利用者向けに発行されたトークンが拒否されるようにします。
  • GKE ではプロジェクトを固定する: format=full トークンの場合、claims.google.compute_engine.project_id == "my-project" のような condition を追加して、ルールを 1 つのプロジェクトのノードに限定します。

次のステップ

  • 完全なリソースモデルと SDK の認証情報の優先順位については、Workload Identity Federation ページを参照してください。
  • 環境(本番、ステージング)ごとに個別のフェデレーションルールを追加し、他に影響を与えずに 1 つを取り消せるようにしてください。

Was this page helpful?