[Amazon Bedrock AgentCore]Identity機能を活用して、Cognito認証とAzure OpenAI連携を実現するエージェントを作ってみた
はじめに
こんにちは、コンサルティング部の神野です。
皆さんは先月プレビューリリースされたAmazon Bedrock AgentCore(以下Agent Core)を使っていますか?
Runtime、Gateway、Identity・・・などエージェント開発するための便利な機能が色々あって面白いですよね。私も最近楽しくキャッチアップ中です。
今日は数ある機能のうちIdentity機能に注目して記事を書いてみました!簡易的なエージェントを作って紹介してみたいと思います!
Identityについて
コンソール上でIdentity機能を使おうとするとAmazon Inbound AuthとOutbound Authについて説明が書かれています。
コンソール上でこんな絵を使って説明されているサービスをあまり見たことがないので、親切ですね。
IdentityではInbound AuthとOutbound Authの2種類の認証が存在します。
Inbound Auth
- エージェントを「呼び出す側」の認証です
- 「誰がエージェントにアクセスできるか」を制御します
- 例:ユーザーがエージェントを呼び出す際の認証(今回はCognitoを使います)
- メリット:複数のIdPに対応していて、認証を自前で実装せずオフロードできるのは嬉しいですね!
Outbound Auth
- エージェントが「外部サービスを呼び出す」ための認証です
- エージェントが外部APIやサービスにアクセスする際の認証情報を管理します
- 例:エージェントがAzure OpenAIのAPIを呼び出す際の認証(今回はAPI Keyを使います)
- 保存するAPI KeyはAWS Secrets Managerに保存されます
- メリット:ハードコーディングなしでセキュアな外部連携を実現することが可能なのは嬉しいですね!
- 例:エージェントがAzure OpenAIのAPIを呼び出す際の認証(今回はAPI Keyを使います)
今回実装するエージェント
今回実装するのは、2つの認証を同時に活用した、Azure OpenAIを使用するエージェントです。
- Inbound Auth: Cognitoで認証されたユーザーのみがエージェントにアクセス可能
- Outbound Auth: エージェントがAzure OpenAI APIに安全にアクセス
簡単に今回作成するエージェントの構成図を簡単に書いてみます。
全体の流れとしては下記のようになります!
- クライアントからの認証付きリクエスト
- クライアントがAmazon Cognitoから取得したアクセストークンを付けて、AgentCoreにリクエストを送信します
- Inbound Authでアクセス制御
- AgentCore Identityのインバウンド認証機能が、Cognitoのアクセストークンを検証します
- 認証に成功したリクエストのみがエージェント(Runtime)に到達できます
- エージェント起動とAzure OpenAI呼び出しの準備
- 認証を通過したリクエストでエージェントが起動します
- エージェントがAzure OpenAIを呼び出す必要が生じた際、Outbound Authが動作します
- Outbound AuthでAPIキー取得
- AWS Secrets Managerに保存されているAzure OpenAIのAPIキーを安全に取得します
- このAPIキーはAgentCore Identityのtoken-vault経由で管理されています
- Azure OpenAIへの安全なアクセス
- 取得したAPIキーを使用して、エージェントがAzure OpenAIにリクエストを送信します
- Azure OpenAIからの応答をクライアントに返します
「誰がエージェントを使えるか」をInbound Authで制御し、「エージェントが外部サービスを呼び出すための認証」をOutbound Authで制御する構造になっています!
本記事で実装したサンプルは下記レポジトリにアップロードしているので、必要に応じてご参照ください。
前提条件
必要な環境
-
AWS CLI 2.28.8
-
Python 3.12.6
-
AWSアカウント
- 使用するリージョン:us-west-2リージョン
-
Azureアカウント
gpt-4.1-mini
のデプロイ
Azure OpenAI側の準備
今回はAzure OpenAI 側でも事前準備が必要です。Azure AI Foundry でモデルをデプロイしておく必要があります。今回は gpt-4.1-mini
を使いましたが、お好みのモデルでOKです!
デプロイ後、以下の情報を控えておいてください。後ほど使用します!
-
デプロイメント名(例:gpt-4.1-mini)
- 配置情報に記載があります
-
エンドポイントURL(例:https://your-resource.openai.azure.com/)
-
APIキー
事前に準備が終わったら今度は環境準備を進めていきましょう。
環境準備
Python環境のセットアップ
まずは必要なライブラリをインストールしていきましょう。requirements.txt
を用意します。
strands-agents
strands-agents-tools
boto3
litellm
openai
bedrock-agentcore
bedrock-agentcore-starter-toolkit
python-dotenv
仮想環境を作ってライブラリをインストールします。
# 仮想環境の作成と有効化
python3 -m venv agentcore-env
source agentcore-env/bin/activate
# 依存関係のインストール
pip install -r requirements.txt
環境変数管理ファイルの準備
実装を進めていくと環境変数が増えてきて管理が大変になるので、.env
ファイルで管理することにしました。
後で埋める箇所もありますが、一旦placeholder
としています。
先ほど取得したAzure OpenAIの情報(AZURE_DEPLOYMENT_NAME
、AZURE_API_BASE
、AZURE_API_VERSION
)は記載しておきましょう!
# Cognito Configuration(後で埋める)
DISCOVERY_URL=placeholder
CLIENT_ID=placeholder
USERNAME=testuser
PASSWORD=Testpass123!
REGION=us-west-2
# IAM Role(後で埋める)
ROLE_ARN=placeholder
# Agent Name(任意のエージェント名を設定可能)
AGENT_NAME=strands_sample_agent
# Azure OpenAI Configuration
AZURE_DEPLOYMENT_NAME=gpt-4.1-mini
AZURE_API_BASE=https://your-resource.openai.azure.com/
AZURE_API_VERSION=2025-01-01-preview
最終的に必要な環境変数を一覧にまとめました。
環境変数名 | 説明 | 例 |
---|---|---|
DISCOVERY_URL |
Cognito Discovery URL | https://cognito-idp.us-west-2.amazonaws.com/{POOL_ID}/.well-known/openid-configuration |
CLIENT_ID |
Cognito Client ID | 1234567890abcdef... |
USERNAME |
テストユーザー名 | `testuser |
PASSWORD |
テストユーザーパスワード | Testpass123! |
REGION |
AWSリージョン | us-west-2 |
ROLE_ARN |
IAMロールARN | arn:aws:iam::XXXXXXXXXXXX:role/AgentCoreExecutionRole-... |
AGENT_NAME |
エージェント名(任意) | strands_sample_agent (例: xxx_agent など任意の名前でOK) |
AZURE_DEPLOYMENT_NAME |
Azureデプロイメント名 | gpt-4.1-mini |
AZURE_API_BASE |
Azure エンドポイント | https://your-resource.openai.azure.com/ |
AZURE_API_VERSION |
Azure API バージョン | 2025-01-01-preview |
Cognitoユーザープールの作成
Cognitoセットアップスクリプト
Cognitoの設定は、公式ドキュメントのAppendixにサンプルスクリプトがあります。これをベースに、今回のユースケース用に作成しました。
#!/bin/bash
# Cognito User Pool作成スクリプト
# AgentCoreはus-west-2でしか動かないので、リージョンを固定
REGION="us-west-2"
# User Poolの作成
echo "Cognito User Poolを作成中..."
POOL_ID=$(aws cognito-idp create-user-pool \
--pool-name "MyUserPool" \
--policies '{"PasswordPolicy":{"MinimumLength":8}}' \
--region $REGION | jq -r '.UserPool.Id')
# App Clientの作成(重要:USER_PASSWORD_AUTHフローを有効化)
echo "App Clientを作成中..."
CLIENT_ID=$(aws cognito-idp create-user-pool-client \
--user-pool-id $POOL_ID \
--client-name "MyClient" \
--no-generate-secret \
--explicit-auth-flows "ALLOW_USER_PASSWORD_AUTH" "ALLOW_REFRESH_TOKEN_AUTH" \
--region $REGION | jq -r '.UserPoolClient.ClientId')
# テストユーザーの作成
echo "テストユーザーを作成中..."
aws cognito-idp admin-create-user \
--user-pool-id $POOL_ID \
--username "testuser" \
--temporary-password "TempPass123!" \
--region $REGION \
--message-action SUPPRESS > /dev/null
# 恒久パスワードの設定
aws cognito-idp admin-set-user-password \
--user-pool-id $POOL_ID \
--username "testuser" \
--password "Testpass123!" \
--region $REGION \
--permanent > /dev/null
# 設定値の出力
echo "===== Cognito設定完了 ====="
echo "Pool ID: $POOL_ID"
echo "Discovery URL: https://cognito-idp.us-west-2.amazonaws.com/$POOL_ID/.well-known/openid-configuration"
echo "Client ID: $CLIENT_ID"
echo "Username: testuser"
echo "Password: Testpass123!"
実行すると、必要な情報がすべて表示されるので、これを.env
ファイルに転記しておきます!
IAMロールの作成
必要な権限について
公式ドキュメントにIAMロールの基本的な権限は載っているのですが、実はOutbound Authを使う場合、追加の権限が必要になります。
Secrets Managerへのアクセス権限や、token-vaultへの直接アクセス権限が必要になるので、加味した権限を付与しておきます。こちらは下記公式ドキュメントに記載があるので、必要に応じてご参照ください。
信頼ポリシー
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "AssumeRolePolicy",
"Effect": "Allow",
"Principal": {
"Service": "bedrock-agentcore.amazonaws.com"
},
"Action": "sts:AssumeRole",
"Condition": {
"StringEquals": {
"aws:SourceAccount": "123456789012"
},
"ArnLike": {
"aws:SourceArn": "arn:aws:bedrock-agentcore:us-west-2:123456789012:*"
}
}
}
]
}
実行ポリシー
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "ECRImageAccess",
"Effect": "Allow",
"Action": [
"ecr:BatchGetImage",
"ecr:GetDownloadUrlForLayer"
],
"Resource": [
"arn:aws:ecr:us-west-2:123456789012:repository/*"
]
},
{
"Sid": "ECRTokenAccess",
"Effect": "Allow",
"Action": [
"ecr:GetAuthorizationToken"
],
"Resource": "*"
},
{
"Sid": "LogsAccess",
"Effect": "Allow",
"Action": [
"logs:DescribeLogStreams",
"logs:CreateLogGroup",
"logs:DescribeLogGroups",
"logs:CreateLogStream",
"logs:PutLogEvents"
],
"Resource": [
"arn:aws:logs:us-west-2:123456789012:log-group:/aws/bedrock-agentcore/runtimes/*",
"arn:aws:logs:us-west-2:123456789012:log-group:/aws/bedrock-agentcore/runtimes/*:log-stream:*",
"arn:aws:logs:us-west-2:123456789012:log-group:*"
]
},
{
"Sid": "XRayAccess",
"Effect": "Allow",
"Action": [
"xray:PutTraceSegments",
"xray:PutTelemetryRecords",
"xray:GetSamplingRules",
"xray:GetSamplingTargets"
],
"Resource": ["*"]
},
{
"Sid": "CloudWatchMetrics",
"Effect": "Allow",
"Resource": "*",
"Action": "cloudwatch:PutMetricData",
"Condition": {
"StringEquals": {
"cloudwatch:namespace": "bedrock-agentcore"
}
}
},
{
"Sid": "GetAgentAccessToken",
"Effect": "Allow",
"Action": [
"bedrock-agentcore:GetWorkloadAccessToken",
"bedrock-agentcore:GetWorkloadAccessTokenForJWT",
"bedrock-agentcore:GetWorkloadAccessTokenForUserId"
],
"Resource": [
"arn:aws:bedrock-agentcore:us-west-2:123456789012:workload-identity-directory/default",
"arn:aws:bedrock-agentcore:us-west-2:123456789012:workload-identity-directory/default/*"
]
},
{
"Sid": "BedrockModelInvocation",
"Effect": "Allow",
"Action": [
"bedrock:InvokeModel",
"bedrock:InvokeModelWithResponseStream"
],
"Resource": [
"arn:aws:bedrock:*::foundation-model/*",
"arn:aws:bedrock:us-west-2:123456789012:*"
]
},
{
"Sid": "CredentialProviderAccess",
"Effect": "Allow",
"Action": [
"bedrock-agentcore:GetApiKeyCredentialProvider",
"bedrock-agentcore:GetOauth2CredentialProvider",
"bedrock-agentcore:CreateApiKeyCredentialProvider",
"bedrock-agentcore:CreateOauth2CredentialProvider",
"bedrock-agentcore:GetResourceApiKey"
],
"Resource": [
"arn:aws:bedrock-agentcore:us-west-2:123456789012:workload-identity-directory/*",
"arn:aws:bedrock-agentcore:us-west-2:123456789012:token-vault/*"
]
},
{
"Sid": "SecretsManagerAccess",
"Effect": "Allow",
"Action": [
"secretsmanager:GetSecretValue"
],
"Resource": "*"
}
]
}
Secrets Managerの権限が必要な理由は、AgentCore Identityが内部的にAPIキーをSecrets Managerで管理しているためです。これに気づくまで少し時間がかかりました...
IAMロール作成スクリプト
実際にはこんなシェルスクリプトを作って実行しました。アカウントIDを自動で取得してJSONファイルのプレースホルダーを置き換える作りにしています!
#!/bin/bash
# アカウントIDとリージョンを取得
ACCOUNT_ID=$(aws sts get-caller-identity --query Account --output text)
REGION="us-west-2"
AGENT_NAME="${AGENT_NAME:-strands_full_auth_agent}"
# JSONファイルのプレースホルダーを置換
sed -i.bak "s/123456789012/$ACCOUNT_ID/g" trust-policy.json
sed -i.bak "s/123456789012/$ACCOUNT_ID/g" execution-policy.json
# IAMロールの作成
ROLE_NAME="AgentCoreExecutionRole-$(date +%s)"
aws iam create-role \
--role-name $ROLE_NAME \
--assume-role-policy-document file://trust-policy.json
# ポリシーの作成とアタッチ
aws iam put-role-policy \
--role-name $ROLE_NAME \
--policy-name AgentCoreExecutionPolicy \
--policy-document file://execution-policy.json
# ロールARNを取得
ROLE_ARN=$(aws iam get-role --role-name $ROLE_NAME --query 'Role.Arn' --output text)
echo "✅ IAM Role created: $ROLE_ARN"
export ROLE_ARN
# 環境変数をファイルに保存
echo "export ROLE_ARN=\"$ROLE_ARN\"" > role_vars.sh
echo "IAM Role ARN has been saved to role_vars.sh"
このシェルを実行すると、最後にロールARNをrole_vars.sh
に保存してくれるので、.env
ファイルにコピペしておきましょう。
Azure OpenAI APIキーの登録
API Key方式での登録手順
今回はAPI Key方式で進めます。Azure OpenAI のAPIキーをAgentCore Identityのtoken-vaultに登録します。これはAWSコンソールから行います。
- Bedrock AgentCore コンソールの「Identity」セクションに移動
- 「Add OAuth Client / API key」をクリック
- Provider typeで「API Key」を選択
- Nameに「azure-openai-key」と入力し、API Key欄にAzure OpenAIのAPIキーを貼り付け
作成後、表示されるProvider ARNを控えて.env
に転記しておきましょう!
保存したAPI KeyはAWS Secrets Managerに保存されるため、リソースが自動的に作成されていました。
bedrock-agentcore-identity!default/apikey/name
といった形式で保存されるんですね。
エージェントの実装
いよいよメインのエージェント実装です!今回はシンプルなエージェントにしています。
- 天気情報を提供:シンプルなツールを組み込んだチャットボット
- 今回はダミーのツールを作成しています。
requires_api_key
デコレータ- Outbound Authの特徴かと思います。
- デコレータの引数に、事前に作成した
name
を引数に設定すれば、鍵を自動的に取得してくれます。
- デコレータの引数に、事前に作成した
- Outbound Authの特徴かと思います。
import os
from bedrock_agentcore.identity.auth import requires_api_key
from strands import Agent, tool
from strands.models.litellm import LiteLLMModel
from bedrock_agentcore.runtime import BedrockAgentCoreApp
# グローバル変数でAPIキーを管理
AZURE_API_KEY_FROM_CREDS_PROVIDER = ""
# Outbound Auth: APIキー取得用のデコレーター付き関数
# このデコレーターが、token-vaultからAPIキーを自動で取得してくれる!
@requires_api_key(
provider_name="azure-openai-key" # Step 4で作成したプロバイダー名
)
async def need_api_key(*, api_key: str):
global AZURE_API_KEY_FROM_CREDS_PROVIDER
print(f'✅ Credential ProviderからAPIキー取得: {api_key[:10]}...')
AZURE_API_KEY_FROM_CREDS_PROVIDER = api_key
app = BedrockAgentCoreApp()
# Azure OpenAI設定(環境変数から読み込み)
os.environ["AZURE_OPENAI_ENDPOINT"] = os.getenv("AZURE_OPENAI_ENDPOINT", "")
os.environ["AZURE_OPENAI_API_VERSION"] = os.getenv("AZURE_OPENAI_API_VERSION", "2025-01-01-preview")
# カスタムツールの定義(天気情報を返す簡単なツール)
@tool
def weather():
"""現在の天気を取得します"""
return "現在の天気は晴れです。気持ちの良い天気です"
# エージェントをグローバル変数として管理(初期化は一度だけ)
agent = None
@app.entrypoint
async def full_auth_agent(payload):
"""
Inbound Auth(Cognito認証)とOutbound Auth(Azure OpenAI)を
両方使用するエージェントのエントリーポイント
このメソッドが呼ばれる時点で、すでにCognito認証は通過している!
"""
global AZURE_API_KEY_FROM_CREDS_PROVIDER, agent
print("✅ Cognito認証済みリクエストを受信")
print(f"受信したペイロード: {payload}")
# Outbound Auth: 初回のみAPIキーを取得
# 2回目以降は取得済みのキーを使い回す
if not AZURE_API_KEY_FROM_CREDS_PROVIDER:
print("Outbound Auth: Credential ProviderからAzure APIキーを取得中...")
try:
await need_api_key(api_key="") # デコレーターが自動でキーを注入
os.environ["AZURE_OPENAI_API_KEY"] = AZURE_API_KEY_FROM_CREDS_PROVIDER
print("✅ Azure APIキーの設定完了!")
except Exception as e:
print(f"❌ APIキー取得エラー: {e}")
raise
# エージェントの初期化(初回のみ)
# 毎回初期化すると遅いので、一度だけ初期化して使い回す
if agent is None:
print("Azure OpenAIモデルでエージェントを初期化中...")
deployment_name = os.environ.get("AZURE_DEPLOYMENT_NAME", "gpt-4o-mini")
model = f"azure/{deployment_name}" # LiteLLMの形式に合わせる
print(f"使用するモデル: {model}")
litellm_model = LiteLLMModel(
model_id=model,
params={"max_tokens": 4096, "temperature": 0.7}
)
agent = Agent(
model=litellm_model,
tools=[calculator, weather], # 計算と天気のツールを追加
system_prompt="あなたは親切なアシスタントです。計算と天気の情報を提供できます。"
)
print("✅ エージェント初期化完了!")
# ユーザー入力を処理
user_input = payload.get("prompt", "こんにちは")
print(f"ユーザー入力: {user_input}")
try:
# Azure OpenAIを使って応答を生成
response = agent(user_input)
result = response.message['content'][0]['text']
print(f"エージェント応答: {result}")
return result
except Exception as e:
print(f"❌ エージェント処理エラー: {e}")
return f"エラーが発生しました: {str(e)}"
if __name__ == "__main__":
app.run()
デプロイ
デプロイ用のスクリプトを作成しました!python deploy_agent.py
を実行するだけで、以下が実行されます。
.env
ファイルの自動読み込み- Azure OpenAI設定の環境変数注入
- エージェントのビルド・デプロイ
from bedrock_agentcore_starter_toolkit import Runtime
import os
from urllib.parse import urlencode
from dotenv import load_dotenv
def prepare_environment_variables():
"""Prepare all environment variables for the agent"""
print("⚙️ 環境変数を準備中...")
# Prepare environment variables for the agent container
env_vars = {
# Azure OpenAI settings
"AZURE_API_BASE": os.environ.get('AZURE_API_BASE', ''),
"AZURE_API_VERSION": os.environ.get('AZURE_API_VERSION', '2025-01-01-preview'),
"AZURE_DEPLOYMENT_NAME": os.environ.get('AZURE_DEPLOYMENT_NAME', 'gpt-4.1-mini'),
}
# Filter out empty values
env_vars = {k: v for k, v in env_vars.items() if v}
print(f"✅ 環境変数準備完了: {list(env_vars.keys())}")
return env_vars
def deploy_agent():
"""Deploy agent with integrated environment variable management"""
print("🚀 統合デプロイスクリプトを開始...")
# Load .env file using python-dotenv
print("📋 .envファイルを読み込み中...")
if not load_dotenv():
print("❌ .envファイルが見つかりません")
return
# Get required environment variables
try:
discovery_url = os.environ['DISCOVERY_URL']
client_id = os.environ['CLIENT_ID']
role_arn = os.environ['ROLE_ARN']
except KeyError as e:
print(f"❌ 必要な環境変数が設定されていません: {e}")
return
# Prepare environment variables for agent container
env_vars = prepare_environment_variables()
print("🔧 AgentCore Runtimeの設定中...")
# AgentCore Runtimeの設定
agentcore_runtime = Runtime()
response = agentcore_runtime.configure(
entrypoint="strands_full_auth_agent.py",
execution_role=role_arn,
auto_create_ecr=True, # ECRリポジトリを自動作成
requirements_file="requirements.txt",
region="us-west-2",
# エージェント名にハイフンは使えない!アンダースコアを使う
agent_name=os.environ.get('AGENT_NAME', 'strands_full_auth_agent'),
# Inbound Auth: Cognito認証の設定
authorizer_configuration={
"customJWTAuthorizer": {
"discoveryUrl": discovery_url,
"allowedClients": [client_id]
}
}
)
print("✅ 設定完了!デプロイ中...")
# デプロイ実行(環境変数を注入)
launch_result = agentcore_runtime.launch(env_vars=env_vars)
print(f"✅ デプロイ完了!")
print(f" Agent ARN: {launch_result.agent_arn}")
return agentcore_runtime
if __name__ == "__main__":
deploy_agent()
統合デプロイの実行
deploy_agent.py
を実行してデプロイしましょう!
python deploy_agent.py
実行すると以下のように進行します。
🚀 統合デプロイスクリプトを開始...
📋 .envファイルを読み込み中...
⚙️ 環境変数を準備中...
🔧 AgentCore Runtimeの設定中...
✅ 設定完了!デプロイ中...
✅ デプロイ完了!
Agent ARN: arn:aws:bedrock-agentcore:us-west-2:123456789012:agent/...
実行するとコンテナイメージ作成用のDockerfile
やエージェントの設定ファイルなどが自動的に作成されます。
デプロイが完了するとコンソールからもエージェントの状態を確認できます。
注入した環境変数も確認可能です。
エージェントURL(エンドポイント)の組み立て方
curlコマンドで今回エージェントを実行する想定ですが、ARNからエージェントのURLを組み立てる必要があります。少し複雑ですが、以下の手順で作成できます!
ARNのエンコードが必要です。
- ARNに含まれる
:
(コロン)は%3A
に /
(スラッシュ)は%2F
にエンコードする必要があります
例えば、以下のようなARNの場合
arn:aws:bedrock-agentcore:us-west-2:XXXXXXXXXXXX:runtime/strands_full_auth_agent-abc123
エンコード後のURLは下記のように組み立てます。
https://bedrock-agentcore.us-west-2.amazonaws.com/runtimes/arn%3Aaws%3Abedrock-agentcore%3Aus-west-2%3AXXXXXXXXXXXX%3Aruntime%2Fstrands_full_auth_agent-abc123/invocations?qualifier=DEFAULT
動作確認
トークンの取得
トークン取得用のスクリプトget_token.py
を作成します。
コード全文
#!/usr/bin/env python3
"""
Cognito Bearer Token取得スクリプト(Python版)
使用方法:
python get_token.py && source .token_env
"""
import os
import boto3
import sys
from dotenv import load_dotenv
def get_cognito_bearer_token():
"""Get Cognito Bearer Token using boto3"""
try:
print("🔐 Cognito Bearer Token取得中...")
# 環境変数から設定を取得(USER_POOL_IDは不要!)
required_vars = ['CLIENT_ID', 'USERNAME', 'PASSWORD']
missing_vars = [var for var in required_vars if var not in os.environ]
if missing_vars:
print(f"❌ 必要な環境変数が設定されていません: {', '.join(missing_vars)}")
print(" .envファイルに以下の設定が必要です:")
for var in missing_vars:
print(f" {var}=your_value_here")
return None
client_id = os.environ['CLIENT_ID']
username = os.environ['USERNAME']
password = os.environ['PASSWORD']
region = os.environ.get('REGION', 'us-west-2')
# Cognito Identity Providerクライアントを初期化
cognito_client = boto3.client('cognito-idp', region_name=region)
# ユーザー認証(AWS CLIコマンドと同等)
response = cognito_client.initiate_auth(
ClientId=client_id,
AuthFlow='USER_PASSWORD_AUTH',
AuthParameters={
'USERNAME': username,
'PASSWORD': password
}
)
# アクセストークン取得
access_token = response['AuthenticationResult']['AccessToken']
print("✅ Cognito Bearer Token取得成功!")
return access_token
except Exception as e:
print(f"❌ Cognito認証エラー: {e}")
print(" 以下を確認してください:")
print(" - .envファイルの設定値が正しいか")
print(" - AWS認証情報が正しく設定されているか")
print(" - ネットワーク接続が正常か")
return None
def save_token_to_file(token):
"""Save token to .token_env file for sourcing"""
try:
with open('.token_env', 'w') as f:
f.write(f'export BEARER_TOKEN="{token}"\n')
print("💾 トークンを.token_envファイルに保存しました")
print(" 次のコマンドで環境変数に設定してください:")
print(" source .token_env")
return True
except Exception as e:
print(f"❌ ファイル保存エラー: {e}")
return False
def main():
"""Main function"""
print("🚀 Cognito Bearer Token取得スクリプト(Python版)")
print()
# Load .env file using python-dotenv
print("📋 .envファイルを読み込み中...")
if not load_dotenv():
print("❌ .envファイルが見つかりません")
print(" Cognito認証に必要な設定が.envファイルに記載されていることを確認してください")
sys.exit(1)
# Get Cognito token
token = get_cognito_bearer_token()
if not token:
sys.exit(1)
# Save token to file
if not save_token_to_file(token):
sys.exit(1)
print()
print("✅ 完了!以下のコマンドで環境変数を設定してください:")
print(" source .token_env")
print()
print("または、ワンライナーで実行:")
print(" python get_token.py && source .token_env")
if __name__ == "__main__":
main()
.token_env
にトークンが出力されるので1ライナーでアクセストークンを環境変数に設定しておきます。
python get_token.py && source .token_env
curlコマンドでの動作確認
エージェント呼び出し
トークン取得後、curlでエージェントを呼び出します。
URLは取得したARNを使用して組み立てます。
# トークン取得
python get_token.py && source .token_env
# エージェント呼び出し(URLのARN部分を適切にエンコード)
curl -X POST "https://bedrock-agentcore.us-west-2.amazonaws.com/runtimes/arn%3Aaws%3Abedrock-agentcore%3Aus-west-2%3AXXXXXXXXXXXX%3Aruntime%2Fstrands_full_auth_agent-{your-id}/invocations?qualifier=DEFAULT" \
-H "Authorization: Bearer ${BEARER_TOKEN}" \
-H "Content-Type: application/json" \
-d '{"prompt": "あなたはどんなAIですか?"}'
# 応答
"私は親切なアシスタントAIです。質問に答えたり、情報を提供したり、さまざまなサポートを行うことができます。天気の情報も提供できますので、何か知りたいことがあれば教えてくださいね。"
ちゃんとAzure OpenAIを使って応答が返ってきました!!!
トークンなしでアクセスした場合
試しにトークンなしでアクセスしてみると...
curl -X POST "https://bedrock-agentcore.us-west-2.amazonaws.com/runtimes/..." \
-H "Content-Type: application/json" \
-d '{"prompt": "こんにちは"}'
# エラー応答
{"message":"Missing Authentication Token"}
期待通り、Cognito認証がないとアクセスできないことが確認できました!
まとめ
Amazon Bedrock AgentCore Identityを使って、Cognito認証とAzure OpenAI連携を同時に実現するエージェントを作ることができました!
実装してみて感じたのは、特にIAM権限周りでは、実際に動かしてログを見ながら調整していたところ、結局は公式ドキュメントに記載されていた内容だった・・・!ということを繰り返しました。
Inbound AuthとOutbound Authを組み合わせることで、マネージドサービスと連携しながら認証や鍵管理を自前実装することなく、オフロードできるのはすごい魅力だなと思いました。
Inbound Auth/Outbound Authどちらも今回はシンプルな実装だったので色々なパターンを試してブログで発信できたらなと思っております!
本記事が少しでも参考になりましたら幸いです!最後までご覧いただきありがとうございました!