2
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

AgentCore+Strands AgentsからVertex AI経由でセキュアにGeminiを利用する

2
Posted at

はじめに

各社から AI エージェントの開発・運用基盤が次々とリリースされ、自社のクラウド基盤次第では、クロスクラウド構成になってくるケースもでてきました。たとえば、Amazon Bedrock AgentCore 上で Strands Agents を動かしつつ、LLM バックエンドには Google Cloud Vertex AI (Gemini) を採用する、といった構成です。

こうしたクロスクラウド構成で課題になるのが 認証 です。サービスアカウントキー(JSON キーファイル)を使う方法もありますが、キーの漏洩リスクやローテーション管理の手間を考えるとセキュリティ的なリスクが伴います。

本記事では、Workload Identity Federation (WIF) を活用し、 AWS の IAM ロールと GCP のサービスアカウントを紐づけてセキュアな認証を実現する方法を紹介します。

Workload Identity Federation とは

サービスアカウントキーの代わりにフェデレーション ID を使用して、オンプレミスまたはマルチクラウドのワークロードに Google Cloud リソースへのアクセス権を付与することができるGoogle Cloudのサービスです。

以下はサービスアカウントキーによる認証とWorkload Identity Federationによる認証の比較です。

サービスアカウントキー Workload Identity Federation
キーの管理 JSON ファイルを安全に保管・配布が必要 秘匿情報ではないためSecretとしての管理が不要
漏洩リスク 高い(長期間有効なキー) 低い(一時トークンのみ)
セットアップ シンプル やや複雑(初回のみ)

google-auth ライブラリがこの一連の認証フローを自動的に済ませてくれるため、アプリケーション側では認証情報をライブラリに渡すだけで済みます。

GCP コンソールでの設定手順

1. Workload Identity Pool の作成

まず、外部 ID を管理する「プール」を作成します。

  1. GCP コンソールで [IAM と管理] > [Workload Identity 連携] に移動
  2. [プールを作成] をクリック

image.png

設定項目 説明
プール名 aws-agentcore-pool 任意の識別名
プール ID aws-agentcore-pool API で使用される一意 ID
説明 AWS AgentCore からのアクセス用 任意

2. AWS Provider の追加

プール内に AWS 用のプロバイダを追加します。

image.png

設定項目 説明
プロバイダの選択 AWS AWS アカウントからのアクセス
プロバイダ名 aws-agentcore-provider 任意の識別名
プロバイダ ID aws-agentcore-provider API で使用される一意 ID
AWS アカウント ID 123456789012 接続元の AWS アカウント ID

AWS アカウント ID を指定することで、そのアカウント内のリソースのみがこのプロバイダを通じて認証できるようになります。

3. 属性マッピングの設定

AWS の属性を GCP の属性にマッピングします。AWS プロバイダを選択すると、以下のデフォルトマッピングが設定されます。

image.png

Google 属性 AWS 属性
attribute.aws_account assertion.account
attribute.aws_role assertion.arn.extract('assumed-role/{role}/')
google.subject assertion.arn

4. 属性条件の設定

属性条件を設定することで、認証を許可する ID のサブセットを制限できます。

image.png

設定項目
条件 CEL assertion.arn.startsWith('arn:aws:sts::<AWSアカウントID>:assumed-role/')

この条件により、AssumeRole 経由のアクセスのみが許可されます。IAM ユーザーの直接アクセスなど、意図しない経路からの認証を防止できます。

5. Service Account への権限付与

WIF 経由でアクセスする際に使用するサービスアカウントに、適切な権限を付与します。

# サービスアカウントの作成(未作成の場合)
gcloud iam service-accounts create my-agent-sa \
    --display-name="Agent Service Account" \
    --project=my-gcp-project

# Vertex AI 利用権限の付与
gcloud projects add-iam-policy-binding my-gcp-project \
    --member="serviceAccount:my-agent-sa@my-gcp-project.iam.gserviceaccount.com" \
    --role="roles/aiplatform.user"

# WIF からのサービスアカウント権限借用を許可
gcloud iam service-accounts add-iam-policy-binding \
    my-agent-sa@my-gcp-project.iam.gserviceaccount.com \
    --project=my-gcp-project \
    --role="roles/iam.workloadIdentityUser" \
    --member="principalSet://iam.googleapis.com/projects/PROJECT_NUMBER/locations/global/workloadIdentityPools/aws-agentcore-pool/attribute.aws_role/arn:aws:sts::123456789012:assumed-role/MY_AGENTCORE_ROLE"

Python 実装

Strands Agents で Vertex AI (Gemini) を利用する

Strands Agents の公式ドキュメントでは、API キーによる Google AI 経由の利用方法が紹介されています。しかし、本構成では Vertex AI 経由 で Gemini を利用します。

両方式の違いを比較します。

API キー方式(公式ドキュメント) Vertex AI + WIF 方式(本記事)
認証方法 API キー WIF → サービスアカウント
エンドポイント Google AI (generativelanguage.googleapis.com) Vertex AI (aiplatform.googleapis.com)
セキュリティ API キーの管理が必要 キーレス
セットアップ GeminiModel(client_args={"api_key": "..."}) GeminiModel(client=client) + WIF credentials

以下、認証からGemini利用までの実装を順に見ていきます。

WIF 認証情報の取得

WIF の設定ファイルは、GCP コンソールの [Workload Identity 連携] からプロバイダを選択し、[クライアント ライブラリの構成をダウンロード] で取得できます。ダウンロードされる credentials-configuration-file.json の内容は以下のようになります。

{
    "universe_domain": "googleapis.com",
    "type": "external_account",
    "audience": "//iam.googleapis.com/projects/000000000000/locations/global/workloadIdentityPools/aws-agentcore-pool/providers/aws-provider",
    "subject_token_type": "urn:ietf:params:aws:token-type:aws4_request",
    "service_account_impersonation_url": "https://iamcredentials.googleapis.com/v1/projects/-/serviceAccounts/my-agent-sa@my-gcp-project.iam.gserviceaccount.com:generateAccessToken",
    "token_url": "https://sts.googleapis.com/v1/token",
    "credential_source": {
        "environment_id": "aws1",
        "region_url": "http://169.254.169.254/latest/meta-data/placement/availability-zone",
        "url": "http://169.254.169.254/latest/meta-data/iam/security-credentials",
        "regional_cred_verification_url": "https://sts.{region}.amazonaws.com?Action=GetCallerIdentity&Version=2011-06-15"
    }
}

AWSの一部サービスでは上記の情報に加え、 IMDSv2(Instance Metadata Service Version 2)が要求されます。
2026/3時点ではGoogle Cloudコンソールではimdsv2_session_token_urlが自動で生成されないため、下記のように手動で追加する必要があります。これを忘れると、AgentCoreからの認証に失敗するので注意してください。

{
    "universe_domain": "googleapis.com",
    "type": "external_account",
    "audience": "//iam.googleapis.com/projects/000000000000/locations/global/workloadIdentityPools/aws-agentcore-pool/providers/aws-provider",
    "subject_token_type": "urn:ietf:params:aws:token-type:aws4_request",
    "service_account_impersonation_url": "https://iamcredentials.googleapis.com/v1/projects/-/serviceAccounts/my-agent-sa@my-gcp-project.iam.gserviceaccount.com:generateAccessToken",
    "token_url": "https://sts.googleapis.com/v1/token",
    "credential_source": {
        "environment_id": "aws1",
        "region_url": "http://169.254.169.254/latest/meta-data/placement/availability-zone",
        "url": "http://169.254.169.254/latest/meta-data/iam/security-credentials",
        "regional_cred_verification_url": "https://sts.{region}.amazonaws.com?Action=GetCallerIdentity&Version=2011-06-15",
        "imdsv2_session_token_url": "http://169.254.169.254/latest/api/token" <-- これを手動で追加
    }
}

Python での WIF 認証情報の利用

ここまでで取得した credentials-configuration-file.json を Python コードで読み込み、認証情報を取得します。

"""GCP認証モジュール。"""

import json

from google.auth import aws
from google.auth.transport.requests import Request

logger = logging.getLogger(__name__)


def get_credentials():
    logger.info("Using Workload Identity Federation (AWS → GCP)")

    with open("credentials-configuration-file.json") as f:
        config = json.load(f)

    credentials = aws.Credentials.from_info(
        config,
        scopes=["https://www.googleapis.com/auth/cloud-platform"],
    )
    credentials.refresh(Request())
    return credentials

Strands Agents での AI エージェント実装

あとはWIF で取得した認証情報を google-genai クライアントに渡すだけで、Strands Agents の GeminiModel を通じて Vertex AI経由でGeminiを呼び出せます。

from google import genai
from strands.models.gemini import GeminiModel
from bedrock_agentcore.runtime import BedrockAgentCoreApp

from auth import get_credentials

GOOGLE_CLOUD_PROJECT = "my-gcp-project"
GOOGLE_CLOUD_LOCATION = "global"

credentials = get_credentials()

client = genai.Client(vertexai=True, project=GOOGLE_CLOUD_PROJECT, location=GOOGLE_CLOUD_LOCATION, credentials=credentials)
model = GeminiModel(client=client, model_id="gemini-2.5-flash")

app = BedrockAgentCoreApp()

@app.entrypoint
async def invoke(payload: Dict[str, Any]):
    agent = Agent(
        model=model,
        name="SampleAgent",
        system_prompt="あなたは優秀なアシスタントです。ユーザーの質問に対して、適切な回答を提供してください。",
    )

    stream = agent.stream_async(user_message)
    async for event in stream:
        yield event

if __name__ == "__main__":
    app.run()

参考リンク

2
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?