本文属于机器翻译版本。若本译文内容与英语原文存在差异,则一律以英文原文为准。
临时策略示例
本节中的策略是根据同一会话中早些时候发生的事情决定的。它们允许你在付款之前要求获得批准,使已经过时的许可过期,限制运行总数,或者在失败后阻止操作。没有一个请求包含足够的信息来决定其中任何一个。
每个示例都授权示例资源配置中描述的参考网关。有关临时事件架构、运算符、会话 ID、配额和区域可用性,请参阅临时策略和创作临时策略。
在使用这些示例之前
有四个因素决定临时政策的行为是否符合您的预期。
- 会话 ID 是必需的
-
时态历史的范围仅限于您命名的会话。从第一个请求开始,在每个请求的
x-amzn-bedrock-agentcore-policy-session-id标题中发送会话 ID。网关不会为您生成一个临时策略,如果引擎持有临时策略,则没有会话 ID 的请求将无法通过验证。 - 只有允许的操作才会变成
response事件 -
只有在策略允许并且
response事件已完成的情况下,操作才会记录该事件。被拒绝的操作error会改为记录一个事件。因此,以下每个示例都需要一个普通permit的先决条件操作——否则先决条件将被拒绝,永远不会记录为 aresponse,并且时间条件永远无法匹配。每个示例都说明了允许将其与之配对。 -
eventResource: resource是强制性的 -
每个谓词都必须包含
eventResource: resource,它将匹配的事件与策略范围内的资源相关联。省略它会被拒绝。temporal predicates do not constrain the matched event to the current request’s resource您无需编写sessionId— 事件架构已经将每个谓词的范围限定为当前会话。 - 有序比较需要整数;相等性不需要
-
在一个
temporal { }区块内,这两种比较接受不同的类型。-
订购 —
<⇐、>、、>=— 要求两integer边都有。使用创建策略时string,Adecimal或 a 会被拒绝comparison requires numeric operands on both sides。 -
相@@ 等
!=—==和 — 适用于任何类型,只要两边的类型相同。这就是关联的用法:input.claimId匹配context.input.claimId比较两个字符串,这是支持的。
因此,将临时策略必须达到总值或阈值的任何值建模为
integer。这就是为什么参考网关在这些示例汇总的工具上以整数次要单位陈述金钱的原因。求和有同样的要求和它自己的信息:sum需要一个integer总结。有关更多信息,请参阅条件中的参数类型。 -
要求对同一索赔事先获得批准
意图:仅允许为会话早些时候批准的索赔支付款项,这样代理就无法使用其发明的索赔编号进行付款。
::response谓词与已完成approve_claim的匹配。将其output.claimId与当前请求相关联context.input.claimId是将付款与该特定批准联系起来的原因——如果没有相关性,会议中的任何批准都将授权对任何索赔进行赔偿。
permit ( principal, action == AgentCore::Action::"InsuranceAPI___disburse_payment", resource == AgentCore::Gateway::"arn:aws:bedrock-agentcore:us-west-2:123456789012:gateway/insurance-gw-a1b2c3d4e5" ) when temporal { formerly within 1h AgentCore::Action::"InsuranceAPI___approve_claim"::response{ eventResource: resource, output.claimId: context.input.claimId } };
重要
output.*只有当目标为工具声明输出架构时,该response事件才会存在字段。许多目标不这样做,例如,Lambda 目标通常只声明输入,然后事件只带有eventPrincipal、、eventResourceinput.*requestId、和。sessionId
如果您命名了事件未声明的字段,则服务会拒绝该策略,并且错误会列出可用的内容:
predicate `AgentCore::Action::"MyTarget___verify_purchase"::response` mentions field `output.orderId`, which is not declared on that event (declared fields: eventPrincipal, eventResource, input.orderId, requestId, sessionId)
使用该列表来查看您可以关联的内容。如果不存在输出字段,则在共享的输入字段上进行关联——将两个调用input.claimId: context.input.claimId绑定到同一个声明,而无需先前的工具返回任何内容。
两者并不相同,因此请谨慎选择。输入关联与先前调用请求的内容相匹配;输出关联与其返回的内容相匹配。如果您的规则依赖于先前工具生成的值(批准 ID、计算的金额),则只有输出关联才能强制执行,这需要目标声明输出架构。
将其与普通许可证配对,以便允许批准并记录在案:
permit ( principal, action == AgentCore::Action::"InsuranceAPI___approve_claim", resource == AgentCore::Gateway::"arn:aws:bedrock-agentcore:us-west-2:123456789012:gateway/insurance-gw-a1b2c3d4e5" );
| 会话中的请求序列 | 决策 |
|---|---|
|
|
DENY |
|
|
允许 |
|
|
DENY |
需要先决条件操作
意图:只有有人在会话中查看索赔的状态后,才允许批准索赔。
匹配::request意味着只需要尝试先决条件,而不能成功。与许可证配对get_claim_status.
permit ( principal, action == AgentCore::Action::"InsuranceAPI___approve_claim", resource == AgentCore::Gateway::"arn:aws:bedrock-agentcore:us-west-2:123456789012:gateway/insurance-gw-a1b2c3d4e5" ) when temporal { formerly within 5m AgentCore::Action::"InsuranceAPI___get_claim_status"::request{ eventResource: resource } };
需要一个 成功的 先决条件,最近
意图:仅当状态查询在过去五分钟内完成时才允许批准,因此过时的查询会停止授予权限。
与前面的示例相比,唯一的::response变化是取代了::request,这是 “已尝试” 和 “成功” 之间的区别。窗口长度决定了成功必须有多新鲜;一旦通过,权限就会失效,直到先决条件再次运行。
permit ( principal, action == AgentCore::Action::"InsuranceAPI___approve_claim", resource == AgentCore::Gateway::"arn:aws:bedrock-agentcore:us-west-2:123456789012:gateway/insurance-gw-a1b2c3d4e5" ) when temporal { formerly within 5m AgentCore::Action::"InsuranceAPI___get_claim_status"::response{ eventResource: resource } };
| 会话中的请求序列 | 决策 |
|---|---|
|
|
DENY |
|
查找完成,然后 |
允许 |
|
|
DENY |
上限一个动作运行的次数
意图:每节课的任意五分钟内最多允许三笔付款。
count计算窗口中的匹配事件,包括正在授权的请求,因此窗口中的第四个调用是第一个被拒绝的调用。exists (n: Long)活页夹会捕获计数,以便n > 3过滤器可以对其进行测试;聚合物需要在左侧加上括号。==与许可证配对,disburse_payment因此允许在上限内拨打电话。
forbid ( principal, action == AgentCore::Action::"InsuranceAPI___disburse_payment", resource == AgentCore::Gateway::"arn:aws:bedrock-agentcore:us-west-2:123456789012:gateway/insurance-gw-a1b2c3d4e5" ) when temporal { exists (n: Long). (count for (t: Timepoint). where (formerly within 5m (AgentCore::Action::"InsuranceAPI___disburse_payment"::request{ eventResource: resource } && tp(t)))) == n && n > 3 };
重要
这不是安全控制。呼叫者提供会话 ID,因此他们可以通过启动新会话来重置计数。使用它来塑造合作会话内部的行为(例如停止循环代理),而不是对控制自己的会话 ID 的呼叫者施加限制。有关更多信息,请参阅安全注意事项。
上限跑步总数
意图:允许在五分钟内支付总额为 3,000.00,然后停止。
sum在匹配的事件(包括当前请求)中添加命名的输入字段,因此超过阈值的请求将被拒绝。上限为30万美分,支出为10万美分,允许前两笔支付,第三笔被拒绝。
forbid ( principal, action == AgentCore::Action::"InsuranceAPI___disburse_payment", resource == AgentCore::Gateway::"arn:aws:bedrock-agentcore:us-west-2:123456789012:gateway/insurance-gw-a1b2c3d4e5" ) when temporal { exists (total: Long). (sum amt for (amt: Long), (t: Timepoint). where (formerly within 5m (AgentCore::Action::"InsuranceAPI___disburse_payment"::request{ eventResource: resource, input.amountCents: amt } && tp(t)))) == total && total >= 300000 };
双变量域是必需的:amt是对值进行求和并t区分时间点,因此两笔相同金额的付款被计算两次,而不是将重复数据删除为一个。for (amt: Long), (t: Timepoint)
注意
amountCents是工具integer内架构,这就是使该策略起作用的原因。sum聚合需要一个整数求和,而排序比较total需要两边都有一个整数,所以你的架构声明为的字段number无法产生这样的上限。有关这些示例所依赖的类型规则,请参阅使用这些示例之前。
使每份批准仅用于一次用途
意图:允许每次批准一次付款。付款后,需要重新批准。
当右边的锚点出现在窗户内时,since操作员会按住,此后左边的状况一直保持不变。这里的内容是:批准已在最后一小时内完成,此后没有完成任何付款。批准后的第一笔款项消耗了它。
permit ( principal, action == AgentCore::Action::"InsuranceAPI___disburse_payment", resource == AgentCore::Gateway::"arn:aws:bedrock-agentcore:us-west-2:123456789012:gateway/insurance-gw-a1b2c3d4e5" ) when temporal { !AgentCore::Action::"InsuranceAPI___disburse_payment"::response{ eventResource: resource } since within 1h AgentCore::Action::"InsuranceAPI___approve_claim"::response{ eventResource: resource } };
否定::response侧的匹配至关重要。被授权的请求尚未产生回应,因此它不会自行屏蔽——在::request那里匹配会使每笔付款都被拒绝。
| 会话中的请求序列 | 决策 |
|---|---|
|
|
允许 |
|
一秒钟 |
DENY |
|
那么 |
允许 |
注意
通话结束后不久就会录制一个response事件。在发放付款之前,请等待批准返回,而不是将款项背靠背发送。有关更多信息,请参阅对依赖于先前响应的操作进行排序。
强制冷却
意图:防止相同的操作在完成后的一分钟内重复。
此条件指的是它授权的相同操作。 ::response这才是安全的:当前请求还没有响应,因此它本身不匹配。使用书写::request,当前请求将与自己的事件相匹配,并且该操作将被永久禁止。有关更多信息,请参阅Self-referential 条件包括当前请求。
forbid ( principal, action == AgentCore::Action::"InsuranceAPI___disburse_payment", resource == AgentCore::Gateway::"arn:aws:bedrock-agentcore:us-west-2:123456789012:gateway/insurance-gw-a1b2c3d4e5" ) when temporal { formerly within 1m AgentCore::Action::"InsuranceAPI___disburse_payment"::response{ eventResource: resource } };
需要一个尚未失效的先决条件
意图:在批准有效期间允许付款,如果之后重新开放申请以进行状态审查,则撤回许可。
这与一次性使用批准的形式相同,但被否定的操作与正在授权的操作不同,后者将 “消耗批准” 变为 “使批准失效”。同时为approve_claim和授予许可证get_claim_status。
permit ( principal, action == AgentCore::Action::"InsuranceAPI___disburse_payment", resource == AgentCore::Gateway::"arn:aws:bedrock-agentcore:us-west-2:123456789012:gateway/insurance-gw-a1b2c3d4e5" ) when temporal { !AgentCore::Action::"InsuranceAPI___get_claim_status"::response{ eventResource: resource } since within 5m AgentCore::Action::"InsuranceAPI___approve_claim"::response{ eventResource: resource } };
| 会话中的请求序列 | 决策 |
|---|---|
|
|
DENY |
|
|
允许 |
|
|
DENY |
|
那么 |
允许 |
需要按顺序执行一系列操作
意图:要求查询序列状态,然后是批准,然后是付款。
每个环节都有一个策略,链条从它们的组成中脱颖而出。为第一个动作授予普通许可,这样链条就可以开始了。在先决条件完成之前,尝试失序的步骤会被拒绝。
// Link 1: approve only after a completed status lookup permit ( principal, action == AgentCore::Action::"InsuranceAPI___approve_claim", resource == AgentCore::Gateway::"arn:aws:bedrock-agentcore:us-west-2:123456789012:gateway/insurance-gw-a1b2c3d4e5" ) when temporal { formerly within 5m AgentCore::Action::"InsuranceAPI___get_claim_status"::response{ eventResource: resource } }; // Link 2: disburse only after a completed approval permit ( principal, action == AgentCore::Action::"InsuranceAPI___disburse_payment", resource == AgentCore::Gateway::"arn:aws:bedrock-agentcore:us-west-2:123456789012:gateway/insurance-gw-a1b2c3d4e5" ) when temporal { formerly within 5m AgentCore::Action::"InsuranceAPI___approve_claim"::response{ eventResource: resource } };
需要按任意顺序排列两个先决条件
意图:只有在状态查询和批准都完成后,才允许按任一顺序付款。
与之连接的两个formerly条件都&&需要两个条件,并且两个条件都不限制顺序。它使用单个策略可能包含的三个临时运算符中的两个。
permit ( principal, action == AgentCore::Action::"InsuranceAPI___disburse_payment", resource == AgentCore::Gateway::"arn:aws:bedrock-agentcore:us-west-2:123456789012:gateway/insurance-gw-a1b2c3d4e5" ) when temporal { formerly within 1h AgentCore::Action::"InsuranceAPI___get_claim_status"::response{ eventResource: resource } && formerly within 1h AgentCore::Action::"InsuranceAPI___approve_claim"::response{ eventResource: resource } };
使两个动作相互排斥
意图:在两分钟内,允许付款或删除索赔,但不能同时允许两者兼而有之。
排除需要两个对称策略,每个方向一个;一个forbid只能阻止一个订单。匹配::request意味着只需尝试一个动作即可阻挡另一个动作,而不必等待它完成。
// Forbid deletion if a disbursement was requested within 2m forbid ( principal, action == AgentCore::Action::"InsuranceAPI___delete_claim", resource == AgentCore::Gateway::"arn:aws:bedrock-agentcore:us-west-2:123456789012:gateway/insurance-gw-a1b2c3d4e5" ) when temporal { formerly within 2m AgentCore::Action::"InsuranceAPI___disburse_payment"::request{ eventResource: resource } }; // Forbid disbursement if a deletion was requested within 2m forbid ( principal, action == AgentCore::Action::"InsuranceAPI___disburse_payment", resource == AgentCore::Gateway::"arn:aws:bedrock-agentcore:us-west-2:123456789012:gateway/insurance-gw-a1b2c3d4e5" ) when temporal { formerly within 2m AgentCore::Action::"InsuranceAPI___delete_claim"::request{ eventResource: resource } };
需要事件数量的阈值
意图:只有在完成至少两笔针对某项索赔的付款后,才允许将其删除。
input.claimId与当前请求的索赔相关联将计数限定为该索赔,而不是计算会话中的每笔付款。
permit ( principal, action == AgentCore::Action::"InsuranceAPI___delete_claim", resource == AgentCore::Gateway::"arn:aws:bedrock-agentcore:us-west-2:123456789012:gateway/insurance-gw-a1b2c3d4e5" ) when temporal { exists (n: Long). (count for (t: Timepoint). where (formerly within 5m (AgentCore::Action::"InsuranceAPI___disburse_payment"::response{ eventResource: resource, input.claimId: context.input.claimId } && tp(t)))) == n && n >= 2 };
注意
count计算事件,而不是不同的呼叫者。它不能表达 “得到两个不同的人的认可”,因为没有什么能阻止一位校长制作所有匹配的事件。要获得多方批准,请在政策之外关联eventPrincipal或强制执行区别。
在之前的拒绝后屏蔽某项操作
意图:在会话中的任何批准尝试被拒绝后,停止该会话付款。
error事件记录了被拒绝或失败的请求,策略对先前失败的反应::error也是如此。将其与普通许可证配对disburse_payment,因此在正常条件下是允许的。
forbid ( principal, action == AgentCore::Action::"InsuranceAPI___disburse_payment", resource == AgentCore::Gateway::"arn:aws:bedrock-agentcore:us-west-2:123456789012:gateway/insurance-gw-a1b2c3d4e5" ) when temporal { formerly within 3m AgentCore::Action::"InsuranceAPI___approve_claim"::error{ eventResource: resource } };
这是一种有用的遏制模式:探测自己没有的权限的代理会被切断与敏感操作的联系,而不是被允许继续尝试。
结合临时条件、护栏条件和请求条件
意图:允许来电者提出索赔,前提是该会话在过去 24 小时内的申报少于三份,索赔描述中没有银行详细信息,并且来电者不是受限角色。
所有三种条件类型都构成一个策略,每个条款都必须成立,permit才能适用。方temporal块强制执行上限,方when块筛选内容,方unless块排除角色。每项都是独立评估的。
permit ( principal is AgentCore::OAuthUser, action == AgentCore::Action::"InsuranceAPI___file_claim", resource == AgentCore::Gateway::"arn:aws:bedrock-agentcore:us-west-2:123456789012:gateway/insurance-gw-a1b2c3d4e5" ) when temporal { exists (n: Long). (count for (t: Timepoint). where (formerly within 24h (AgentCore::Action::"InsuranceAPI___file_claim"::request{ eventResource: resource } && tp(t)))) == n && n <= 3 } when { BedrockGuardrails::SensitiveInformation(["US_BANK_ACCOUNT_NUMBER"], [context.input.description]).count() == 0 } unless { principal.hasTag("role") && principal.getTag("role") == "restricted" };
护栏屏幕description,这是唯一需要的自由文本参数。file_claim将敏感信息护栏指向一个可能合理携带你正在筛选的数据的字段。如果你把它指向标识符或数字,它就没有什么可检测的,子句就会静默通过。 description是可选的,因此省略它的请求不会给护栏提供任何文本,该子句成立。
编辑临时策略时会发生什么变化
在引擎上添加或更新临时策略会使该引擎的打开临时会话失效,因为记录的历史记录不再与应用于该引擎的规则相匹配。下一个重用失效会话的请求失败,HTTP 409。ConflictException启动新会话并重试;新会话以空白的历史记录开始,并根据更新的策略进行评估。
重要
在推出临时政策变更时,请为此做好计划。客户需要将 a 视409为 “开始新会话”。任何正在运行的多步骤工作流程都会重新启动而不是恢复。