「2026 Japan AWS Jr. Champions 真夏のQiitaリレー」
の18日目の投稿です!
過去の投稿は以下の(リンク集)からご覧ください!
https://qiita.com/ys-yoshida/private/6f7c7f85155a993e2c86
17日目の投稿
https://qiita.com/ryu-ki/items/abbf520bd8cd628e4f55
⚠️ この記事はAI(Claude)と一緒に作成しました。
結論
AgentCore Temporal Policyの累積制限のような
過去の行動が必要な制限はセッションを2つに分けるとすり抜けます。
今回検証した累積制限はセッション単位で評価されます。
Temporal Policyってなに?
AI Agentは実行時に自律的に次のアクションを決定します。
例えば、顧客情報を取得してからその情報をもとに別のツールを呼び出すAgentを考えます。
従来の認可では、それぞれのリクエストを個別に評価することが多いと思います。
しかし、AI Agentでは個々のアクションだけを見ても安全性を判断できないケースがあります。
例えば、
- 顧客情報を取得
- Agentが別の口座番号を生成
- その口座番号で送金
という動きを考えます。
これは単体で①や③を見れば許可された動きかもしれませんが、
「③で使われた値が、①で取得した値と一致しているか?」
という過去のAgentの行動を踏まえた判断ができないと問題になります。
Amazon Bedrock AgentCore PolicyにTemporal Policyは以上のような課題を解決できます。
一言でいうと、
「Agentがこれまで何をしたかを考慮して認可するPolicy」
というわけですね。
実行構成
PolicyはGatewayの外側で以下の条件で評価を行います。
principal + session ID
で、Agentのtrajectoryが識別され、
そのセッション内の過去のアクション、入力、出力などがPolicy評価に利用されていました。
ということはセッション分けた場合、以下のような動作が可能なのでは…?
各セッションでは100円の上限に超えないように累積での制限を行いますが、
セッション分けたらすり抜けるのか?何か対策がしてあるのか?
が気になったので調査しました。
調べてみる
以下の構成で調べてみます。
架空の銀行送金を行うツールを作成して、1度呼び出します。それをセッションを分けて呼び出します。
1.一度ツール呼び出しを行う
まずトークンを取得し、それを分岐するAとBで使いまわします。
トークンが違うことで別ユーザーだと認識されると面倒だなと思ったためです。
ACCESS_TOKEN=$(curl --http1.1 -s -X POST "$TOKEN_ENDPOINT" \
-H "Content-Type: application/x-www-form-urlencoded" \
-d "grant_type=client_credentials&client_id=${CLIENT_ID}&client_secret=${CLIENT_SECRET}" \
| jq -r '.access_token')
一度ツール呼び出しを行います。
status=$(curl -s -o "$body_file" -w "%{http_code}" -X POST "$GATEWAY_URL" \
-H "Authorization: Bearer ${ACCESS_TOKEN}" \
-H "Content-Type: application/json" \
-H "x-amzn-bedrock-agentcore-policy-session-id: ${session_id}" \
-d "{\"jsonrpc\":\"2.0\",\"id\":\"call-${session_id}-${call_no}\",\"method\":\"tools/call\",\"params\":{\"name\":\"${TOOL_NAME}\",\"arguments\":{\"amount\":${amount}}}}")
2.セッション内で制限を超えないように操作
session_Aとsession_Bでそれぞれ上限を超えないように操作を実施し、合計金額を確認します。
run_session() {
local label="$1"
local session_id="verify-${label}-$(uuidgen)"
local total=0
log ""
log "=== セッション${label} (session_id=${session_id}) を開始 ==="
for i in $(seq 1 "$CALLS_PER_SESSION"); do
local status
status=$(call_transfer "$session_id" "$AMOUNT" "$i")
if [ "$status" = "200" ]; then
total=$((total + AMOUNT))
fi
done
log "=== セッション${label} 終了: 許可された合計 = ${total} ==="
echo "$total"
}
3.結果
結果、セッション内では累積制限を課すことはできましたが、
セッションを分けると、制限をすり抜けました。
実施条件
AMOUNT=6000
CALLS_PER_SESSION=3
THRESHOLD=20000
結果
セッションAの許可合計: 18000
セッションBの許可合計: 18000
実質合計(同一principal): 36000
セッション単位の閾値: 20000
まとめ
Amazon Bedrock AgentCoreのTemporal Policyが「セッション単位」で
Agentの行動履歴を評価している点から実際にセッションを分けることで累積制限を
すり抜けられるかを検証しました。
結果として、単一セッション内では累積金額の上限を正しく守れて、
セッションを2つに分けて呼び出すと、制限をすり抜けてしまうことが確認できました。
Temporal Policyは「同一セッション内での逐次的な逸脱」は防げますが
「セッションをまたいだ累積」は単体では防げないという前提があるため、
「履歴の範囲がどこまでか」を正しく理解して設計する必要があります。
session IDの発行・管理をAgent側の実装に委ねず、
信頼できるバックエンド(DynamoDB)で一元管理する等の対策が必要ですね。




