Amazon Bedrock AgentCore、AI エージェント保護に時間的ポリシー
本文の状態
日本語全文を表示中
詳細モードで約18分の本文を読めます。
同じ出来事の情報源
この情報源を基点に整理
AWS Machine Learning Blog
Amazon は AI エージェントのセッション履歴を考慮した権限管理機能「Temporal Policies」を Amazon Bedrock AgentCore に導入し、エージェントが外部から迂回できない状態でリスク制御を実現する。
Continue in AI NEW LAB
このニュースを、実務の判断につなげる
AI NEW LABで、試したことや先に確認したい条件を共有できます。まずはログインなしで読めます。
AI NEW LABで論点を見るAI深層分析を開く2026年8月7日 04:31
AI深層分析
キーポイント
状態依存型ポリシーの実装
従来のステートレスな権限管理では対応できず、エージェントの過去の呼び出し履歴(トラジェクトリ)を文脈として評価することで、一見安全でも連続実行時に危険となる行動を検知する。
ゲートウェイ層での強制執行
ポリシー判定ロジックがエージェントのコード外にある AgentCore Gateway の境界で実行されるため、エージェント自身がこれを傍受したり改ざんしたりすることを防止する。
具体的なリスク制御ユースケース
ワークフローの順序強制、ツール呼び出し間のデータ捏造防止、セッションごとの累積金融リスクのカップリング、高価値アクションにおける人間承認の要求が可能となる。
時系列ポリシーによるトラジェクトリ監視
個々のツール呼び出しのステートレスなチェックを超え、セッション内の順序立った行動(トラジェクトリ)を評価することで一貫性を確保する。ゲートウェイで実行されるため、エージェントのコードやプロンプト、バグの影響を受けずに強制力を持つ。
具体的な適用ユースケース
連鎖するツール間の出力整合性維持、標準手順(SOP)遵守のための呼び出し順序強制、機密操作前の人間による承認要件、および古くなった情報に基づく判断を防ぐデータ鮮度の保証が可能である。
重要な引用
One tool call might be deemed safe when considered in isolation, but harmful in the context of the preceding call
Because these policies run at the AgentCore Gateway perimeter, outside the agent's own code, the agent cannot intercept or manipulate them.
An agent calls a lookup_customer tool, hallucinates a different account number than what was returned, and passes it to a transfer_funds tool that then moves money to the wrong customer's account.
Temporal policies extend Policy in AgentCore with this trajectory-aware enforcement layer.
編集コメントを表示
編集コメント
AI エージェントの自律性が高まる中で、従来の静的な権限管理では対応しきれない動的なリスクへの対策が急務となっている。AWS はエージェントの外部から強制的に制御をかけるアーキテクチャを採用することで、セキュリティと柔軟性の両立を図っている点が高く評価される。
Source Article
元記事を日本語で読む
本文に関係しない購読案内、埋め込み通知、サイト内プロモーションは除いています。
AI エージェントが登場する以前は、アクセス制御において各アクションを独立したイベントとして扱うことで十分でした。従来のアプリケーションでは、決定論的なビジネスロジックによって、アクションが正しい順序で実行されたか、データが最新の状態にあるかを強制していました。
しかし、AI エージェントの振る舞いは従来のアプリケーションとは根本的に異なります。エージェントはランタイム時に、どのツールを呼び出すか、どのような引数を使用するか、そしてその順序を自ら決定します。この柔軟性と、ますます賢くなるモデルの組み合わせにより、エージェントは強力な能力を持つ一方で、制御が極めて困難なものとなっています。
単独で考えれば安全と見なされるツールの呼び出しも、直前の呼び出しとの文脈によっては有害となる可能性があります。例えば、信頼できないデータソースから読み込んだ後の処理などが該当します。そこで重要になるのは、エージェントが回避できない形で、セッション履歴を考慮した認可ルールをどのように適用するかという課題です。
Amazon Bedrock AgentCore の Temporal policies を利用すれば、エージェントの軌跡における過去のイベントを文脈として評価し、現在のリクエストに基づいて AgentCore Gateway のターゲットへのアクセス権限を決定する状態管理型のルールを定義できます。これらのポリシーはエージェント自身のコードの外側、つまり AgentCore ゲートウェイの境界部で実行されるため、エージェントがこれを傍受したり改ざんしたりすることはできません。
本記事では、時間制ポリシー(Temporal Policies)とは何か、その仕組み、そして具体的な実装例について解説します。時間制ポリシーを用いて、ワークフローの順序を強制したり、ツール呼び出し間のデータ改ざんを防いだり、セッションごとの累積的な財務リスクに上限を設定したり、高額なアクションには人間の承認を必須としたりする方法を紹介します。また、エージェントが人間からの関与なしに動作している場合に自動的に権限を強化する仕組みも解説します。
まずは、状態保持型ポリシー(Stateful Policies)が必要となる背景とユースケースについて詳しく見ていきましょう。
エージェントに状態保持型のポリシー強制が必要な理由
現在の AgentCore Policy が提供するアクセス制御は、個々のリクエストに対して「誰が」「どのツールを」「どのような条件下で」呼び出せるかという、状態レス(Stateless)かつ決定論的なルールのみを適用します。このアプローチは必要不可欠ですが、エージェントの運用においては不十分なケースが多々あります。
既存の状態レス制御では検知できない重大な問題が発生する具体例として、以下のようなシナリオが挙げられます。
- エージェントが
lookup_customerツールを呼び出した際、返されたアカウント番号とは異なる架空の番号を生成(ハルシネーション)し、それをtransfer_fundsツールに渡してしまい、結果として誤った顧客の口座へ資金が送金されてしまうケース。 - 累積的なリスク許容度を超過していることを追跡する仕組みがないため、エージェントが制御不能となり、何十回もの取引をループ実行してしまうケース。
- エージェントが数秒のうちに同じ保険請求案件に対して「承認」と「却下」の両方の判断を下してしまうケース。
これらのシナリオにおいて、個々のツール呼び出しはステートレスなポリシーチェックを通過します。しかし、問題が顕在化するのは、セッション内の順序立てられた一連の行動であるエージェントの軌跡(トラジェクトリ)全体を見たときです。
AgentCore の「Temporal policies」は、この軌跡を意識した実行レイヤーとして Policy を拡張するものです。Temporal policies はゲートウェイで動作し、エージェントコードの外側に位置するため、エージェントが何を行おうとも、プロンプトがどうあれ、あるいはエージェントコードにどのようなバグが存在しようとも、これを迂回することはできません。
よくある Temporal policies のユースケースは以下の通りです。
- 連鎖するツール間での出力整合性の確保
現在のツール呼び出しに渡される引数が、直前のツール呼び出しの出力と完全に一致することを要求します。これにより、エージェントがステップ間で値を捏造したり置き換えたりするのを防ぎます。
- ツールの呼び出し順序の強制
特定の標準作業手順(SOP)が遵守されているか確認するため、あるツールを別のツールの前に呼び出すことを要求します。
- 特権的なアクション実行前の人間による承認の必須化
破壊的または機微なツール呼び出しは、軌跡に明示的な人間の承認イベントが記録されるまでブロックされます。
データの鮮度を維持する。依存するアクションを許可する前に、データ参照が所定の時間枠内で完了していることを要求し、古い情報に基づく判断を防ぎます。
タイムポリシーは、「AgentCore Gateway で観測された直近の経路を踏まえて、この特定の要求は承認されるべきか?」という問いに答える認可制御です。現在の要求だけでなく、直近の経路(つまりセッション内のイベント)も評価対象とし、Gateway を経由したリクエストが許可されるべきかどうかを判断します。ただし、タイムポリシー自体はリクエストを変換したり、ツールを呼び出したり、分析を行ったり、エージェントを直接オーケストレーションするものではありません。
タイムポリシーは、AgentCore Gateway を流れるトラフィックを対象に動作します。Gateway はエージェントの Model Context Protocol (MCP) ツール呼び出し、エージェント間呼び出し、モデル推論呼び出しをすべて単一のエンドポイント経由でルーティングするため、エージェントがこれらの呼び出しを Gateway 経由で行う場合、タイムポリシーはそれらすべての呼び出しを一貫して管理できます。これにより、エージェントがどのような種類の呼び出しを行っているかに関わらず、時間軸に沿ったエージェントの振る舞いを一箇所で把握・検討することが可能になります。
タイムポリシーの仕組み
Temporal policies(時間的ポリシー)は、すでにステートレスなアクセス制御に使用されている既存のポリシーエンジンの上に構築されています。これにより、特定のプリンシパルとセッション ID によって識別される、範囲が限定された一連のアクションである「エージェント・トラジェクトリ」の概念が導入されました。
エージェントはポリシーロジックを直接見ることはなく、状態ストアにアクセスすることも、制御を変更することもできません。既存の AgentCore Policy 機能と同様に、Temporal policies はデフォルトで拒否(deny)し、許可よりも禁止(forbid)を優先します。
ゲートウェイがツール呼び出しを受け取ると、ポリシーエンジンは以下の処理を行います:
- ポリシー評価に関連するアクション、入力、出力についてトラジェクトリの状態を検索します。
- 現在の要求に対して、各時間的ポリシーをその歴史的範囲(つまり、顧客が定義したトラジェクトリ内の過去のイベント)の文脈で評価します。
- 決定論的な ALLOW または DENY の判断を返すとともに、その判断に至った完全なコンテキストをログに記録します。
時間制約ポリシー(temporal policy)が評価するすべてのリクエストには、x-amzn-bedrock-agentcore-policy-session-id ヘッダーを含める必要があります。このヘッダーは、リクエストが属するセッションを特定するために使用されます。
セッションの開始と終了をどのように定義するかは、アプリケーション側で決定します。その境界線は、単一のユーザー対話、多段階タスク、あるいは長時間実行されるワークフローなど、アプリケーションにとって意味のある作業単位に合わせて設定できます。
1 つのセッション内で並行して実行できる認証リクエストは最大 1 つに限られるため、セッションのスコープは可能な限り狭く保つことを推奨します。ヘッダーを指定しない場合、システムが自動的に ID を生成しますが、新しいセッション ID が付与されると、ポリシーエンジンはその履歴を持たない新規の空の軌跡(trajectory)に対して評価を行う点に注意が必要です。
セッションは ID だけで定義されるものではありません。AgentCore は、セッション ID とエンドユーザーの身元を組み合わせることで一意のセッションを作成します。つまり、異なる 2 つのユーザーが同じセッション ID を提示しても、完全に別のセッションとして扱われます。ポリシーはそれぞれの軌道(トラジェクトリ)に対して独立して適用されます。これは、基盤となるユーザーの身元が異なるためです。
アクティブなセッション内では、エージェントの軌道には最大 24 時間の過去スパン(ルックバックウィンドウ)が設定されています。それより古いイベントは自動的に削除されます。セッションとポリシーの関係性を規律するルールがもう一つあります。ポリシーエンジン内のポリシーに変更を加えた場合、既存のすべてのセッションが無効化されます。これにより、各セッションが最新のポリシーセットに基づいて評価され、関連する軌道イベントが期待されるスキーマで記録されることを保証しています。
プライベートバンキングポートフォリオエージェントへの時間的ポリシー適用
これらの概念を具体的に理解するために、時間的ポリシーが仮想的なプライベートバンキングエージェントをどのように守るのかを見ていきましょう。このエージェントは、金融サービス企業の資産運用担当者がクライアントのポートフォリオを管理するのを支援します。具体的には、クライアントのプロフィールを取得し、保有銘柄を読み込み、リアルタイムの市場価格を取得し、分析を実行し、担当者の代わりに取引を実行します。
このシナリオでは、以下の MCP ツールが AgentCore Gateway を介して公開されています:
| ツール | 説明 |
|---|---|
| get_client_profile | クライアントのリスク許容度、投資方針、口座制限、および関連するポートフォリオ ID を取得します |
| load_portfolio | クライアントのポートフォリオ保有状況と現在のポジションを取得します |
| get_market_price | 有価証券の現在の市場価格を取得します |
| execute_trade | ポートフォリオに対して買いまたは売りの注文を実行します |
| rebalance_portfolio | 保有資産全体にわたるポートフォリオの配分を調整します |
アドバイザーには3つの役割があります。取引権限が制限されたジュニア・アドバイザー、完全な取引権限を持つシニア・アドバイザー、そして読み取り専用で監視を行うコンプライアンス・オフィサーです。
本例では、ID 管理に Amazon Cognito を使用し、AgentCore Gateway へのインバウンド認証に JWT を渡します。この Gateway はエージェントのツールをホストする場所です。AgentCore Gateway の概要や、Gateway との連携による認証設定については、AgentCore Gateway ドキュメントをご覧ください。
Temporal ポリシーには、エージェントとそのツール向けに設計された新しいオープンソースガバナンス言語である Dogwood が使用されます。Dogwood は既存の Cedar ポリシー の評価をサポートし、時間条件(temporal conditions)への対応も可能にします。Dogwood は既存の Cedar ポリシーと互換性があるため、顧客は移行の手間なく現在の Cedar ポリシーを引き続き利用できます。
Dogwood やその意味論の詳細については、言語ドキュメント または こちらのブログ記事 をご覧ください。
コンプライアンスチームでは、エージェントが本番環境に到達する前に以下の時間制御(temporal controls)の実施を要求しています:
- 取引を実行する前に、まずクライアントのプロフィールを取得し、その後ポートフォリオを読み込むこと。
取引で使用する portfolio_id は、get_client_profile から取得した出力と完全に一致している必要があります。
市場価格は、取引実行から 1 分以内に取得する必要があります。
単一のセッションでの取引総額は $60,000 を超えてはいけません。
個別の取引額が $25,000 を超える場合は、アドバイザーの承認が必要です。承認は取引ごとに 1 つずつ必要です。
エージェントは、損失が出る同一の証券を同じトジェクトリ内で購入した後に売却することはできません。
アドバイザーとのやり取りが 15 分続かない場合、エージェントは書き込み操作へのアクセス権を失います。
ゲートウェイとポリシーを介したリクエストフロー

図 1: AgentCore Gateway とポリシーを介したリクエストフロー
この図は、Gateway へのリクエストが AgentCore の Policy によってどのようにインターセプトされ評価されるかを示しています。ポートフォリオエージェントがツール呼び出しを開始すると、以下の手順が発生します。
- リクエストは AgentCore Gateway に到達します。アドバイザーはすでに AgentCore Identity を通じて認証済みです。リクエストには現在のセッションのトジェクトリ ID が含まれています。
- ポリシーエンジンが、そのトジェクトリの累積状態を取得します。
- 各時間制約ポリシー(temporal policy)が、履歴に対して現在のリクエストを評価します。
すべてのポリシーが許可した場合、リクエストは MCP ツールへ進みます。いずれかのポリシーで禁止されている場合、リクエストは拒否され、その拒否記録が残されます。
実行に成功すると、そのアクションと結果は、将来の評価のためにトラジェクトリ状態に追加されます。
時間ベースのポリシーの実装
ENFORCE モードで既存のポリシーエンジンを持っている場合は、その強制モードを LOG_ONLY に更新するか、個別のポリシーの強制モードを変更できます。ただし、本番環境のワークロードでは、既存のポリシーやポリシーエンジンを LOG_ONLY モードに切り替えることは推奨されません。なぜなら、それによりセキュリティルールの強制が停止してしまうからです。
前提条件
このソリューションを実装する前に、以下の前提条件を満たしていることを確認してください:
Amazon Bedrock AgentCore で AI エージェントを保護するための時間的ポリシー
- Amazon Bedrock AgentCore が有効化されたアクティブな AWS アカウント。
- 少なくとも 1 つの MCP ターゲットが設定された AgentCore Gateway。
- その Gateway に紐付けられたポリシーエンジン。
- ポリシーリソースの作成と管理に必要な適切な IAM 権限(詳細はドキュメントを参照)。
ポリシー 1: ワークフローの順序制御(マルチホップチェーン)
コンプライアンスチームでは、エージェントが get_client_profile、次に load_portfolio、そして最後に rebalance_portfolio という順で実行されることを要求しています。クライアントのプロファイル情報がなければ、エージェントはどのポートフォリオがこのクライアントに属するのか、リスク許容度がどうなっているのか、あるいはどのような口座制限が適用されているのかなど、システムから検証された文脈情報を得ることができません。
permit (principal, action == AgentCore::Action::"FinTarget___load_portfolio", resource == AgentCore::Gateway::)
when temporal {
formerly within 5m (AgentCore::Action::"FinTarget___get_client_profile"::response{eventResource: resource})
};
permit (principal, action == AgentCore::Action::"FinTarget___rebalance_portfolio", resource == AgentCore::Gateway::)
when temporal {
formerly within 5m (AgentCore::Action::"FinTarget___load_portfolio"::response{eventResource: resource})
};このポリシーは、rebalance_portfolio を禁止しています。ただし、get_client_profile と load_portfolio の両方がこの軌道内で正しい順序で完了している場合に限ります。ロードプロファイルのステップをスキップしてリバランスに直接飛ぶエージェントは、どのような指示を受けたかに関わらず拒否されます。
| 軌道状態 | 試行されたアクション | 期待される結果 |
|---|---|---|
| 空 | rebalance_portfolio (portfolio_id: " 8821", amount: 15000) | DENY |
| get_client_profile の完了 | rebalance_portfolio (portfolio_id: " 8821", amount: 15000) | DENY |
| get_client_profile の後、load_portfolio の完了 | rebalance_portfolio(portfolio_id: " 8821", amount: 15000) | ALLOW |
ポリシー 2:出力から入力への整合性
execute_trade に渡される portfolio_id は、get_client_profile が返すポートフォリオ ID のいずれかと完全に一致している必要があります。エージェントが偽の ID を作成したり、別の ID に置き換えたりすることはできません。
permit (
principal,
action == AgentCore::Action::"execute_trade",
resource
)
when temporal {
formerly within 24h (
AgentCore::Action::"get_client_profile"::response{
input.profile_id: context.input.profile_id,
eventResource: resource
}
)
};このポリシーにより、攻撃者がプロンプトインジェクションを利用してエージェントを操作し、異なるクライアントのポートフォリオに対して取引を行わせることを防ぎます。攻撃者は LLM に対して偽造された ID を使用させることに成功する可能性がありますが、ポリシーが CRM システムから実際に返された値と照合することで、その試みを阻止します。
| get_client_profile が返した結果 | execute_trade portfolio_id | 期待される結果 |
|---|---|---|
| port-8821 | port-8821 | ALLOW |
| port-8821 | port-3347 | DENY |
ポリシー 3: データの鮮度
execute_trade を実行する前に、get_market_price の呼び出しが完了してから 30 秒以内である必要があります。エージェントは古い相場情報に基づいて行動することはできません。
permit (
principal,
action == AgentCore::Action::"execute_trade",
resource
)
when temporal {
formerly within 30s (
AgentCore::Action::"get_market_price"::response{eventResource: resource}
)
};市場が変動している状況では、60 秒前のデータでも価格の大きなズレを招く可能性があります。このポリシーにより、エージェントは取引ごとに市場データを最新のものに更新し、判断材料として現在値を使用することが強制されます。
| get_market_price 実行から経過した時間 | アクション | 期待される結果 |
|---|---|---|
| 4 秒前 | BUY Stock A | ALLOW |
| 2 分前 | BUY Stock A | DENY |
| 未呼び出し | BUY Stock A | DENY |
ポリシー 4:軌道ごとの累積予算上限
単一のポリシーセッション(または軌道)における総取引額は、60,000 ドルを超えてはなりません。これは、暴走するエージェントや成功した攻撃による被害範囲を制限するための措置です。
permit (
principal,
action == AgentCore::Action::"execute_trade",
resource
)
when temporal {
exists (total: Long). ((sum amount for (amount: Long), (t: Timepoint). where (formerly within 24h (
AgentCore::Action::"get_market_price"::request{input.cost: amount, eventResource: resource} && tp(t)))) == total && total < 60000
)
};一見問題のない小口取引を数十回実行するだけで、侵害されたエージェントが累積的に破滅的なリスクに晒される可能性があります。60,000 ドルを超えると、新しい軌道が始まるまですべての取引は拒否されます。
Prior cumu
原文を表示
Before AI agents, it was generally sufficient for access controls to treat each action as an independent event. Applications relied on deterministic business logic to enforce whether actions happened in the right order or whether the data was up-to-date. AI agents behave in fundamentally different ways than traditional applications. They decide at runtime which tools to call, with which arguments, and in what order. That flexibility, combined with increasingly intelligent models, makes agents equal measures capable and challenging to control. One tool call might be deemed safe when considered in isolation, but harmful in the context of the preceding call, such as after reading from an untrusted data source. The question then becomes, how do you enforce authorization rules that account for an agent’s session history, in a way the agent cannot circumvent?
Temporal policies in Amazon Bedrock AgentCore let you define stateful rules that determine authorization to AgentCore Gateway targets by evaluating the current request in the context of prior events in an agent’s trajectory. Because these policies run at the AgentCore Gateway perimeter, outside the agent’s own code, the agent cannot intercept or manipulate them.
In this post, you will learn what temporal policies are, how they work, and walk through an example to demonstrate. We will show you how to use temporal policies to enforce workflow sequencing, prevent data fabrication between tool calls, cap cumulative financial exposure per session, and require human approval for high-value actions. You will also see how to automatically tighten permissions when an agent operates without human engagement. First, however, we will explore the needs and use cases for stateful policies in more detail.
Why agents need stateful policy enforcement
Existing access controls in AgentCore Policy enforce stateless, deterministic rules on each individual request: who can call which tool, under what conditions. Stateless controls are necessary but often insufficient for agents. Consider the following scenarios where existing stateless controls fail to catch critical issues:
- An agent calls a lookup_customer tool, hallucinates a different account number than what was returned, and passes it to a transfer_funds tool that then moves money to the wrong customer’s account.
- A runaway agent executes dozens of trades in a loop because nothing tracks that cumulative exposure has already exceeded the risk limit.
- An agent both approves and denies the same insurance claim within seconds.
Each individual tool call in these scenarios would pass a stateless policy check. The problem only becomes apparent when you look at the agent’s trajectory, the ordered sequence of actions in a session. Temporal policies extend Policy in AgentCore with this trajectory-aware enforcement layer. Temporal policies run at the gateway, outside the agent’s code, so they cannot be bypassed regardless of what the agent does, how it is prompted, or what bugs exist in the agent code. Some common temporal policy use cases include:
- Enforcing output integrity across chained tools. Require that an argument passed to the current tool call exactly matches the output of a prior tool call, preventing the agent from hallucinating or substituting values between steps.
- Enforcing tool-call ordering. Require that one tool is called before another tool to verify standard operating procedure (SOP) adherence.
- Requiring human approval before privileged actions. Block destructive or sensitive tool calls until an explicit human approval event is recorded in the trajectory.
- Enforcing data freshness. Require that a data lookup completed within a given timeframe before a dependent action is authorized, preventing decisions based on stale information.Temporal policies are authorization controls that answer the question “given the recent trajectory observed at the AgentCore Gateway, is this specific request authorized?”. They evaluate whether a gateway-routed request should be permitted based on the current request and recent trajectory (that is, events within a session). They do not transform requests, call tools, perform analysis, or directly orchestrate the agent.
Temporal policies operate on the traffic that flows through AgentCore Gateway. Because Gateway routes an agent’s Model Context Protocol (MCP) tool calls, agent-to-agent calls, and model inference calls through a single endpoint, a temporal policy can govern all three whenever your agent issues those calls through the gateway. This gives you one consistent place to reason about an agent’s behavior over time, regardless of which kind of call the agent is making.
How temporal policies work
Temporal policies build on the existing policy engine that’s already used for stateless access control. They introduce the concept of agent trajectories, which are bounded sequences of actions identified by a principal and session ID. Agents never see the policy logic, never touch the state store, and cannot alter the controls. As with the existing AgentCore Policy features, temporal policies deny by default and forbid wins over permit.
When the gateway receives a tool call, the policy engine:
- Queries the trajectory state for actions, inputs, and outputs relevant to the policies being evaluated.
- Evaluates each temporal policy against the current request in the context of its historical scope (that is, prior events within the customer-defined trajectory).
- Returns a deterministic ALLOW or DENY decision and logs the full context of the decision.
Every request that a temporal policy evaluates must carry an x-amzn-bedrock-agentcore-policy-session-id header, which identifies the session the request belongs to. You decide what constitutes the beginning and end of a session. The boundary can reflect whatever unit of work makes sense for your application, whether that is a single user conversation, a multi-step task, or a longer-running workflow. Because there can be no more than one concurrent authorization request per session, we recommend keeping the scope of a session as narrow as possible. If no header is passed, one will be generated on your behalf. However, note that a new session ID means that the policy engine will evaluate against a new, empty trajectory with no history.
A session is never defined by its ID alone. AgentCore combines the session ID with the end user’s identity to produce a unique session, which means two different identities can present the same session ID and still be treated as having entirely separate sessions. Policies apply independently to each trajectory, because the underlying identity differs. Within an active session, agent trajectories carry a maximum look-back window of 24 hours. Any trajectory events older than that are automatically deleted. One additional rule governs the relationship between sessions and the policies themselves. Whenever a change is made to the policies in a policy engine, existing sessions are invalidated. This makes sure that each session is evaluated against the current set of policies and each relevant trajectory event is recorded with the expected schema.
Applying temporal policies to a private banking portfolio agent
To make these concepts concrete, we’ll walk through how temporal policies can secure a hypothetical private banking agent. The agent helps wealth advisors at a financial services firm manage client portfolios. It retrieves client profiles, loads portfolio holdings, fetches real-time market prices, performs analysis, and executes trades on the advisor’s behalf.
In this scenario, the following MCP tools are exposed through the AgentCore Gateway:
| Tool | Description |
|---|---|
| get_client_profile | Retrieves client’s risk tolerance, investment policy, account restrictions, and associated portfolio IDs |
| load_portfolio | Retrieves a client’s portfolio holdings and current positions |
| get_market_price | Fetches current market price for a security |
| execute_trade | Executes a buy or sell order against a portfolio |
| rebalance_portfolio | Adjusts portfolio allocations across holdings |
There are three different advisor roles: junior advisors (limited trade authority), senior advisors (full trade authority), and compliance officers (read-only monitoring access). In this example, we will use Amazon Cognito for identity and pass JWTs for inbound auth to the AgentCore Gateway, which hosts our agent’s tools. To learn about AgentCore Gateway and how to set up auth with Gateway, read the AgentCore Gateway Documentation. Temporal policies use Dogwood, a new open-source governance language designed for agents and their tools. Dogwood supports evaluating existing Cedar policies and enables support for temporal conditions. Because Dogwood is compatible with existing Cedar policies, customers can continue to use their current Cedar policies without needing to migrate. For additional detail on Dogwood and its semantics, you can read the language documentation or this blog post.
The compliance team requires the following temporal controls before the agent reaches production:
- The agent must pull the client profile, then load the portfolio, before any trade executes.
- The portfolio_id used in a trade must exactly match the output from get_client_profile.
- Market prices must be retrieved within 1 minute of a trade execution.
- No single session can exceed $60,000 in total trade value.
- Any individual trade over $25,000 requires advisor approval, one approval per trade.
- The agent cannot buy and then sell the same security within the same trajectory if it sells for a loss.
- After 15 minutes without advisor interaction, the agent loses access to write operations.
Request flow through gateway and policy

Figure 1: Request flow through AgentCore Gateway and Policy
This diagram demonstrates how requests to your gateway are intercepted and evaluated by Policy in AgentCore. When the portfolio agent initiates a tool call, the following steps occur:
- The request arrives at the AgentCore Gateway. The advisor is already authenticated through AgentCore Identity. The request carries the trajectory ID for the current session.
- The policy engine retrieves the trajectory’s accumulated state.
- Each temporal policy evaluates the current request against that history.
- If all policies permit, the request proceeds to the MCP tool. If any policy forbids, the request is denied and the denial is logged.
- On successful execution, the action and its result are appended to the trajectory state for future evaluations.
Implementing temporal policies
If you have an existing policy engine in ENFORCE mode, you can either update its enforcement mode to LOG_ONLY, or you can change the enforcement mode of the individual policies. Switching existing policies or policy engines to LOG_ONLY mode is not recommended for production workloads since policies will no longer enforce those security rules.
Prerequisites
Before implementing this solution, verify that you have met the following prerequisites:
- An active AWS account with Amazon Bedrock AgentCore enabled.
- An AgentCore Gateway with at least one MCP target configured.
- A policy engine attached to the gateway.
- Appropriate Identity and Access Management (IAM) permissions to create and manage policy resources (see documentation).
Policy 1: Workflow sequencing (multi-hop chain)
The compliance team requires that the agent follow get_client_profile, then load_portfolio, then rebalance_portfolio in sequence. Without the client profile, the agent has no system-verified context about which portfolios belong to this client, what the client’s risk tolerance is, or what account restrictions apply.
permit (principal, action == AgentCore::Action::"FinTarget___load_portfolio", resource == AgentCore::Gateway::)
when temporal {
formerly within 5m (AgentCore::Action::"FinTarget___get_client_profile"::response{eventResource: resource})
};
permit (principal, action == AgentCore::Action::"FinTarget___rebalance_portfolio", resource == AgentCore::Gateway::)
when temporal {
formerly within 5m (AgentCore::Action::"FinTarget___load_portfolio"::response{eventResource: resource})
};This policy forbids rebalance_portfolio unless get_client_profile and load_portfolio have both completed in the correct order within this trajectory. An agent that skips the load profile step and jumps directly to rebalancing is denied regardless of what instructions it received.
| Trajectory state | Action attempted | Expected result |
|---|---|---|
| Empty | rebalance_portfolio (portfolio_id: ” 8821”, amount: 15000) | DENY |
| get_client_profile completed | rebalance_portfolio (portfolio_id: ” 8821”, amount: 15000) | DENY |
| get_client_profile then load_portfolio completed | rebalance_portfolio(portfolio_id: ” 8821”, amount: 15000) | ALLOW |
Policy 2: Output-to-input integrity
The portfolio_id passed to execute_trade must exactly match one of the portfolio IDs returned by get_client_profile. The agent cannot fabricate or substitute a different portfolio ID.
permit (
principal,
action == AgentCore::Action::"execute_trade",
resource
)
when temporal {
formerly within 24h (
AgentCore::Action::"get_client_profile"::response{
input.profile_id: context.input.profile_id,
eventResource: resource
}
)
};This policy prevents an attacker from using prompt injection to steer the agent to trade against a different client’s portfolio. The attacker can convince the LLM to use a fabricated ID, but the policy verifies the value against what the CRM system actually returned.
| get_client_profile returned | execute_trade portfolio_id | Expected result |
|---|---|---|
| port-8821 | port-8821 | ALLOW |
| port-8821 | port-3347 | DENY |
Policy 3: Data freshness
A get_market_price call must have completed within the last 30 seconds before execute_trade is authorized. The agent cannot act on stale quotes.
permit (
principal,
action == AgentCore::Action::"execute_trade",
resource
)
when temporal {
formerly within 30s (
AgentCore::Action::"get_market_price"::response{eventResource: resource}
)
};In volatile markets, even a 60-second-old quote can represent significant price drift. This policy forces the agent to refresh its market data before every trade, ensuring that decisions are based on current information.
| Time since get_market_price | Action | Expected result |
|---|---|---|
| 4 seconds ago | BUY Stock A | ALLOW |
| 2 minutes ago | BUY Stock A | DENY |
| Never called | BUY Stock A | DENY |
Policy 4: Cumulative budget cap per trajectory
Total trade value in a single policy session (or trajectory) cannot exceed $60,000. This contains blast radius from runaway agents or successful attacks.
permit (
principal,
action == AgentCore::Action::"execute_trade",
resource
)
when temporal {
exists (total: Long). ((sum amount for (amount: Long), (t: Timepoint). where (formerly within 24h (
AgentCore::Action::"get_market_price"::request{input.cost: amount, eventResource: resource} && tp(t)))) == total && total < 60000
)
};A compromised agent executing dozens of small trades that individually look fine can still accumulate catastrophic exposure. After $60,000, all trades are denied until a new trajectory begins.
Prior cumu
関連記事
今日のまとめ
AIデイリーブリーフで今日の重要ニュースをまとめ読み