View a markdown version of this page

制定临时策略 - 亚马逊基岩 AgentCore

本文属于机器翻译版本。若本译文内容与英语原文存在差异,则一律以英文原文为准。

制定临时策略

您可以使用 Dogwood 策略语言编写临时策略并将其添加到策略引擎中,就像在中 AgentCore为策略创建任何其他策略一样。临时策略是将会话感知条件置于temporal区块中的permit或forbid规则;该规则适用的主体、操作和资源使用标准(principal, action, resource)范围编写,与任何其他策略相同。以下各节介绍如何创建临时策略并逐步介绍您可以表达的常见模式。

创建临时策略

您可以使用该create-policy操作创建临时策略,与用于其他策略的操作相同,然后将其附加到策略引擎。临时政策的声明属于定义范围policy,而不是cedar像无国籍的雪松政策那样低下。

以下 AWS CLI 示例在策略引擎上创建临时策略:

aws bedrock-agentcore-control create-policy \ --policy-engine-id my-policy-engine-id \ --name TransferToLookedUpAccount \ --validation-mode FAIL_ON_ANY_FINDINGS \ --definition '{ "policy": { "statement": "permit (principal, action == AgentCore::Action::\"FundsTarget___transfer_funds\", resource == AgentCore::Gateway::\"arn:aws:bedrock-agentcore:us-west-2:123456789012:gateway/my-gateway\") when temporal { formerly within 1h AgentCore::Action::\"FundsTarget___get_account_balance\"::response{ eventResource: resource, output.accountId: context.input.toAccount } };" } }'

你也可以通过用自然语言描述来创建临时策略,而不是自己写Dogwood声明。

事件架构:您可以引用的字段

temporal { }区块内的条件使用时间事件谓词来匹配迄今为止在会话中记录的特定事件(包括当前授权的操作)。谓词命名匹配事件的时间窗口、动作和事件种类以及一组字段约束条件。上一节中的create-policy示例使用了一个谓词formerly within 1h AgentCore::Action::"FundsTarget___get_account_balance"::response{ eventResource: resource, output.accountId: context.input.toAccount },该谓词匹配最近一小时内get_account_balanceresponse记录的output.accountId等于当前请求的toAccount记录。

要编写谓词,你需要知道一个操作会产生哪些事件以及每个事件带有哪些字段,因为这些是谓词可以限制和关联的字段。本节描述了该事件架构。

每个操作最多会产生三种事件,以谓词 (, ::request::response,::error) 中的事件种类命名:

  • request— 记录每项授权请求。携带操作的输入字段。

  • response— 在工具成功返回时记录。携带操作的输入和输出字段。

  • error— 在请求被拒绝或工具返回错误时记录。携带操作的输入字段。此事件仅限历史记录。

时态事件架构为每个操作定义这些事件A。…​inputs(A)并…​outputs(A)扩展到操作的声明输入和输出字段:

// Recorded for each authorized request. decision event <A>::request { ...inputs(A), eventPrincipal: principalType(A), eventResource: resourceType(A), requestId: String, pin sessionId: String = context.sessionId, } // Recorded when the tool returns successfully; carries inputs and outputs. event <A>::response { ...inputs(A), ...outputs(A), eventPrincipal: principalType(A), eventResource: resourceType(A), requestId: String, pin sessionId: String = context.sessionId, } // Recorded when the request is denied or the tool returns an error; history-only. event <A>::error { ...inputs(A), eventPrincipal: principalType(A), eventResource: resourceType(A), requestId: String, pin sessionId: String = context.sessionId, }

在谓词正文中,您可以引用匹配事件的以下字段:

字段 说明

input.<name>

操作的输入字段。在requestresponse、和error活动上可用。

output.<name>

操作的输出字段。仅适用于response活动。

eventPrincipal

提出记录请求的校长。

eventResource

请务必将其设置为resource(aseventResource: resource),使其引用策略范围内的资源,即permit或forbid头resource中的资源。这会将匹配范围限定为当前请求的资源,并且每个时间谓词都必须包含该资源。

要将记录的事件与当前请求相关联,请将其中一个字段与当前请求的值进行比较,例如context.input.<name>。

使用案例

以下是临时策略的几个示例。

可用的工具

本节中的示例使用名为的网关目标FundsTarget,该目标公开了三个工具。在策略中,每个工具都通过其操作名称以及此处列出的输入和输出字段来引用。FundsTarget___<tool-name>

FundsTarget___get_account_balance

检索客户的当前账户余额。

  • 输入:customerId(字符串,必填)。

  • 输出:status(字符串)、customerId(字符串)、accountId(字符串)、balance(整数)。

FundsTarget___transfer_funds

在账户之间转移资金。

  • 输入:fromAccount(字符串,必填)、toAccount(字符串,必填)、amount(整数,必填)。

  • 输出:status(字符串)、fromAccount(字符串)、toAccount(字符串)、amount(整数)。

FundsTarget___get_transaction_history

检索账户的交易历史记录。

  • 输入:accountId(字符串,必填)、startDate(字符串,可选)、endDate(字符串,可选)。

  • 输出:status(字符串),accountId(字符串)。

示例:输出到输入的完整性

此示例允许代理仅将资金转入其在同一会话中先前查找的账户,从而防止其转入其伪造的账户。该政策transfer_funds仅在会话早些时候的get_account_balance响应返回相同的账户时才允许:

permit ( principal, action == AgentCore::Action::"FundsTarget___transfer_funds", resource == AgentCore::Gateway::"arn:aws:bedrock-agentcore:us-west-2:123456789012:gateway/my-gateway" ) when temporal { formerly within 1h AgentCore::Action::"FundsTarget___get_account_balance"::response{ eventResource: resource, output.accountId: context.input.toAccount } };

::response谓词与先验get_account_balance记录的响应相匹配。output.accountId是工具返回的字段,context.input.toAccount也是当前transfer_funds请求的目标账户;要求它们相等会将转移与先前的查询绑定。

由于策略引擎在默认情况下会拒绝,并且由于response只有在允许的情况下才会将操作记录为,因此您还会授予一个普通的 permit for,get_account_balance以便允许该查询并将其记录为会话中的响应:

permit ( principal, action == AgentCore::Action::"FundsTarget___get_account_balance", resource == AgentCore::Gateway::"arn:aws:bedrock-agentcore:us-west-2:123456789012:gateway/my-gateway" );

这两项政策均已到位后,会话中的请求按以下方式决定:

会话中的请求顺序 决策

transfer_funds无需事先查询

DENY

get_account_balance先换一个账户,然后transfer_funds转到同一个账户

允许

get_account_balance一个账户,然后transfer_funds转到另一个账户

DENY

示例:刀具排序

此示例仅允许在先前在同一会话中运行先决条件操作后执行操作。以下政策get_account_balance仅允许在过去五分钟内transfer_funds提出请求:

permit ( principal, action == AgentCore::Action::"FundsTarget___get_account_balance", resource == AgentCore::Gateway::"arn:aws:bedrock-agentcore:us-west-2:123456789012:gateway/my-gateway" ) when temporal { formerly within 5m AgentCore::Action::"FundsTarget___transfer_funds"::request{ eventResource: resource } };

::request谓词与会话中先前的transfer_funds请求相匹配。将其与 permit for 配对,transfer_funds这样就可以允许并记录操作。这两个策略均transfer_funds已部署后,get_account_balance在会话中运行之前会被拒绝:

会话中的请求顺序 决策

get_account_balance在任何人之前 transfer_funds

DENY

transfer_funds,然后 get_account_balance

允许

示例:数据新鲜度

此示例仅允许在紧张的窗口内成功完成先决条件时执行操作,因此过时的结果会使权限过期。get_account_balance只有在最近五分钟内transfer_funds完成,它才允许:

permit ( principal, action == AgentCore::Action::"FundsTarget___get_account_balance", resource == AgentCore::Gateway::"arn:aws:bedrock-agentcore:us-west-2:123456789012:gateway/my-gateway" ) when temporal { formerly within 5m AgentCore::Action::"FundsTarget___transfer_funds"::response{ eventResource: resource } };

开启::response而不是::request匹配与工具排序的区别:只有在操作成功完成时才记录response事件,因此此策略要求最近成功完成,而不仅仅是事先的请求。窗口长度设置了完成时必须保持的新鲜度;窗口通过后,权限将失效,直到先决条件再次运行。

会话中的请求顺序 决策

get_account_balance在任何完成之前 transfer_funds

DENY

transfer_funds完成,然后get_account_balance在窗口中

允许

get_account_balance窗户过去之后

DENY

示例:基于会话的速率限制

此示例将工具限制在会话中的固定呼叫次数。以下政策禁止transfer_funds在会话的五分钟内被调用三次以上:

forbid ( principal, action == AgentCore::Action::"FundsTarget___transfer_funds", resource == AgentCore::Gateway::"arn:aws:bedrock-agentcore:us-west-2:123456789012:gateway/my-gateway" ) when temporal { exists (n: Long). (count for (t: Timepoint). where (formerly within 5m (AgentCore::Action::"FundsTarget___transfer_funds"::request{ eventResource: resource } && tp(t)))) == n && n > 3 };

该count表达式计算最近五分钟内在会话中记录的transfer_funds请求,包括当前请求;当该计数超过三时,禁令适用。将其与 permit for 配对transfer_funds,这样就允许最大限度地拨打电话。两种政策均已实施后,允许在任何五分钟的时间段内进行前三次transfer_funds呼叫,而该时段内的第四次(或更晚的)呼叫将被拒绝。

重要

此限制仅适用于单个会话,因此它不是针对确定的呼叫者的安全控制。由于呼叫者提供会话 ID,因此他们可以通过启动新会话来重置计数。使用这种模式来塑造合作会话中的行为,而不是对控制自己的会话 ID 的呼叫者强制实行硬限制。有关更多信息,请参阅安全注意事项。

示例:一次性使用批准

此示例使每项批准都适用于一次性使用。transfer_funds仅当自会话中最近get_account_balance(批准)transfer_funds以来没有完成任何操作时,才允许 A。转移完成后,它会消耗批准时间,在新的批准发生之前,下一次转移将被拒绝:

permit ( principal, action == AgentCore::Action::"FundsTarget___transfer_funds", resource == AgentCore::Gateway::"arn:aws:bedrock-agentcore:us-west-2:123456789012:gateway/my-gateway" ) when temporal { !AgentCore::Action::"FundsTarget___transfer_funds"::response{ eventResource: resource } since within 1h AgentCore::Action::"FundsTarget___get_account_balance"::response{ eventResource: resource } };

当在最后一小时内完成get_account_balance(批准)且自该批准以来没有完成transfer_funds时,此since条件成立。匹配::response是必不可少的:传输只有在成功后才算作已完成,因此获得授权的请求不会自行阻止。将其与 permit for 配对get_account_balance,这样就可以记录批准了。

会议中的请求按以下方式决定:

会话中的请求顺序 决策

get_account_balance(批准),然后 transfer_funds

允许

transfer_funds一秒没有新的批准

DENY

那么get_account_balance,一个新的 transfer_funds

允许

注意

调用完成后不久就会记录工具response的事件。等待get_account_balance(批准)申请完成response并记录在案,然后再发出下一份申请transfer_funds,而不是背靠背发出。有关更多信息,请参阅依赖于先前响应的排序操作。

示例:累积预算

此示例限制了窗口内某项操作的总值。如果过去五分钟内会话传输的amount输入总和达到 3000,则以下政策将禁止transfer_funds:

forbid ( principal, action == AgentCore::Action::"FundsTarget___transfer_funds", resource == AgentCore::Gateway::"arn:aws:bedrock-agentcore:us-west-2:123456789012:gateway/my-gateway" ) when temporal { exists (total: Long). (sum amt for (amt: Long), (t: Timepoint). where (formerly within 5m (AgentCore::Action::"FundsTarget___transfer_funds"::request{ eventResource: resource, input.amount: amt } && tp(t)))) == total && total >= 3000 };

该sum表达式将窗口中匹配transfer_funds请求的amount输入字段相加,包括当前请求;当总数达到阈值时,禁令适用。求和字段是操作的输入字段。将策略与 permit for 配对transfer_funds。例如,如果阈值为 3000,传输值为 1000,则允许前两次传输,第三次达到 3000,则被拒绝。

与速率限制一样,总和仅限于当前会话,不会跨会话汇总。

示例:冷却

此示例强制执行冷却时间:操作在上次完成后的固定时间内不能重复。transfer_funds如果在最后一分钟内transfer_funds完成,则禁止:

forbid ( principal, action == AgentCore::Action::"FundsTarget___transfer_funds", resource == AgentCore::Gateway::"arn:aws:bedrock-agentcore:us-west-2:123456789012:gateway/my-gateway" ) when temporal { formerly within 1m AgentCore::Action::"FundsTarget___transfer_funds"::response{ eventResource: resource } };

此条件具有自我参照性:它与授权的相同操作相匹配。匹配::response是它起作用的原因,因为获得授权的请求尚未产生响应,因此它本身并不匹配。::request在此处进行匹配将使当前请求与其自身的事件匹配,并且该操作将被永久禁止。在窗口过去且没有新的完成后,再次允许该操作。

会话中的请求顺序 决策

第一 transfer_funds

允许

1 分钟transfer_funds内再来一次

DENY

transfer_funds1 分钟过去后

允许

示例:连续前提条件

此示例仅允许在前提条件成熟时执行操作:最近出现了肯定确认,此后没有任何内容使其失效。它transfer_funds仅允许get_account_balance(确认)在过去五分钟内完成,并且从那以后没有完成get_transaction_history(失效):

permit ( principal, action == AgentCore::Action::"FundsTarget___transfer_funds", resource == AgentCore::Gateway::"arn:aws:bedrock-agentcore:us-west-2:123456789012:gateway/my-gateway" ) when temporal { !AgentCore::Action::"FundsTarget___get_transaction_history"::response{ eventResource: resource } since within 5m AgentCore::Action::"FundsTarget___get_account_balance"::response{ eventResource: resource } };

当某项任务在过去五分钟get_account_balance内完成且此后没有完成时,此since条件get_transaction_history成立。完成的get_account_balance确认了先决条件,并要求此后get_transaction_history没有发生任何事可以确保之后没有任何东西使它失效。为两者发放许可证get_transaction_history,get_account_balance然后将其记录在案。

会话中的请求顺序 决策

transfer_funds在任何之前 get_account_balance

DENY

get_account_balance,那么 transfer_funds

允许

get_transaction_history发生,然后 transfer_funds

DENY

那么get_account_balance,一个新的 transfer_funds

允许

示例:多跳链

您可以编写多个排序策略以要求一系列操作,每个策略都只有在前一个操作完成后才允许。此示例要求链 get_account_balance get_transaction_history → transfer_funds 使用两个策略(每个链接一个):

// Link 1: permit get_transaction_history only after get_account_balance completed permit ( principal, action == AgentCore::Action::"FundsTarget___get_transaction_history", resource == AgentCore::Gateway::"arn:aws:bedrock-agentcore:us-west-2:123456789012:gateway/my-gateway" ) when temporal { formerly within 5m AgentCore::Action::"FundsTarget___get_account_balance"::response{ eventResource: resource } }; // Link 2: permit transfer_funds only after get_transaction_history completed permit ( principal, action == AgentCore::Action::"FundsTarget___transfer_funds", resource == AgentCore::Gateway::"arn:aws:bedrock-agentcore:us-west-2:123456789012:gateway/my-gateway" ) when temporal { formerly within 5m AgentCore::Action::"FundsTarget___get_transaction_history"::response{ eventResource: resource } };

每项政策都强制执行一个环节,链条从其组成中脱颖而出:transfer_funds需要get_transaction_history,也就是要求。get_account_balancepermit为链中的第一个操作授予 a,这样它就可以开始了。在先决条件完成之前,尝试的失序步骤将被拒绝。

会话中的请求顺序 决策

transfer_funds或者get_transaction_history之前 get_account_balance

DENY

get_account_balance,然后get_transaction_history,然后 transfer_funds

每一步都允许

示例:相互排斥

此示例使窗口中的两个操作相互排斥:先运行的操作会阻塞另一个。它使用两种对称的禁止政策,因此排除是双向的。在这里transfer_funds,get_transaction_history不能在两分钟内同时发生:

// Forbid get_transaction_history if a transfer_funds was requested within 2m forbid ( principal, action == AgentCore::Action::"FundsTarget___get_transaction_history", resource == AgentCore::Gateway::"arn:aws:bedrock-agentcore:us-west-2:123456789012:gateway/my-gateway" ) when temporal { formerly within 2m AgentCore::Action::"FundsTarget___transfer_funds"::request{ eventResource: resource } }; // Forbid transfer_funds if a get_transaction_history was requested within 2m forbid ( principal, action == AgentCore::Action::"FundsTarget___transfer_funds", resource == AgentCore::Gateway::"arn:aws:bedrock-agentcore:us-west-2:123456789012:gateway/my-gateway" ) when temporal { formerly within 2m AgentCore::Action::"FundsTarget___get_transaction_history"::request{ eventResource: resource } };

因为每个策略都匹配::request,即使请求一个操作也会阻止另一项操作,因此封禁不会等待第一个操作完成。您需要两个对称forbid策略,每个方向一个:一个在请求get_transaction_history后禁止,另一个在transfer_funds请求transfer_funds后禁止。get_transaction_history一次禁令只能阻止一个订单。将两者与这两项行动的许可证配对。

会话中的请求顺序 决策

transfer_funds,那么 get_transaction_history

允许转移,历史记录拒绝

get_transaction_history,那么 transfer_funds

历史记录允许,传输拒绝

示例:组合时间条件、护栏条件和雪松条件

单一保单可以将临时条件与护栏和标准雪松条件相结合;必须满足所有这些条件才能适用该政策。此示例transfer_funds仅在累积转账金额保持在上限(临时)、请求不包含敏感信息(护栏)且呼叫者不在封锁组(Cedar)中时才允许:

permit ( principal, action == AgentCore::Action::"FundsTarget___transfer_funds", resource == AgentCore::Gateway::"arn:aws:bedrock-agentcore:us-west-2:123456789012:gateway/my-gateway" ) when temporal { exists (total: Long). (sum amt for (amt: Long), (t: Timepoint). where (formerly within 24h (AgentCore::Action::"FundsTarget___transfer_funds"::request{ eventResource: resource, input.amount: amt } && tp(t)))) == total && total < 60000 } when { BedrockGuardrails::SensitiveInformation(["ACCOUNT_NUMBER"], [context.input.body]).count() == 0 } unless { principal in Group::"blocked_users" };

时间封锁强制执行累积上限,护栏区块阻止包含列出的敏感信息的请求,Cedar unless 区块不包括被封锁的主体。每种条件类型都经过独立评估,许可证仅在所有条件都有效时才适用。有关护栏条件语法,请参阅策略中的护栏;临时区块的行为如前面的示例中所述。

示例:并行先决条件

此示例要求先按任意顺序完成两个先决条件,然后才允许执行某项操作。它get_account_balance仅允许两者兼transfer_funds而有之且在最后一小时内get_transaction_history完成,将两个formerly条件与&&以下条件相结合:

permit ( principal, action == AgentCore::Action::"FundsTarget___get_account_balance", resource == AgentCore::Gateway::"arn:aws:bedrock-agentcore:us-west-2:123456789012:gateway/my-gateway" ) when temporal { formerly within 1h AgentCore::Action::"FundsTarget___transfer_funds"::response{ eventResource: resource } && formerly within 1h AgentCore::Action::"FundsTarget___get_transaction_history"::response{ eventResource: resource } };

两个先决条件都必须在窗口内完成 (::response),顺序无关紧要。为这两项必备操作授予许可,以便将其记录在案。只完成一个操作会被拒绝,直到另一个也完成为止。

会话中的请求顺序 决策

get_account_balance在两个先决条件之前

DENY

只完成了一个先决条件,那么 get_account_balance

DENY

两个先决条件都已完成,然后 get_account_balance

允许

示例:批准阈值

此示例仅允许在符合条件的赛事达到阈值数量之后采取行动。它仅允许get_account_balance客户在账户中transfer_funds完成至少两笔转账,并将转账toAccount与余额申请相关联:customerId

permit ( principal, action == AgentCore::Action::"FundsTarget___get_account_balance", resource == AgentCore::Gateway::"arn:aws:bedrock-agentcore:us-west-2:123456789012:gateway/my-gateway" ) when temporal { exists (n: Long). (count for (t: Timepoint). where (formerly within 5m (AgentCore::Action::"FundsTarget___transfer_funds"::response{ eventResource: resource, input.toAccount: context.input.customerId } && tp(t)))) == n && n >= 2 };

该count表达式对窗口中匹配的已完成事件进行计数,一旦计数达到阈值,便允许该操作。

注意

count计算匹配的事件,而不是不同的主体。它无法强制要求事件来自不同的调用方,因此它表示了 “N 个事件” 的阈值,而不是由 N 个不同方批准的多方批准。

将已完成的转账与账户进行匹配 get_account_balance

小于 2

DENY

2 或更多

允许

示例:在之前遭到拒绝后阻止某项操作

当同一会话中的先前工具调用被拒绝时,此示例会阻止敏感操作。被拒绝的请求被记录为error事件,并且::error谓词与此类事件相匹配。如果会话get_account_balance中的某项在最近三分钟内被拒绝,则以下策略将禁止transfer_funds:

forbid ( principal, action == AgentCore::Action::"FundsTarget___transfer_funds", resource == AgentCore::Gateway::"arn:aws:bedrock-agentcore:us-west-2:123456789012:gateway/my-gateway" ) when temporal { formerly within 3m AgentCore::Action::"FundsTarget___get_account_balance"::error{ eventResource: resource } };

forbid规则优先于任何规则permit,因此将其与正常条件transfer_funds下允许permit的规则配对:

permit ( principal, action == AgentCore::Action::"FundsTarget___transfer_funds", resource == AgentCore::Gateway::"arn:aws:bedrock-agentcore:us-west-2:123456789012:gateway/my-gateway" );

这两项政策均已到位后,会话中的请求按以下方式决定:

会话中的请求顺序 决策

transfer_funds事先没有否认

允许

get_account_balance被拒绝,那么 transfer_funds

DENY