企業如何決定哪些 Agent、Tool、Action 或 trust domain 不得再接受或延伸 delegation?
在 Day 14 的流程中,Agent A 把 read-only 子任務交給 B。B 又想請 Data Export Agent C 整理結果。若沒有明確停止條件,Alice 的權力會沿著 Agent graph 無限傳遞;每一跳都說「前一個 Agent 已經允許」,最後卻沒有人能說明誰批准了外部 export。
固定應用呼叫通常只有一層 caller-to-resource 關係。Agent delegation 的 hop 數、trust domain、Action risk 與 downstream audience 會在 runtime 才出現;chain 甚至可能跨不同管理邊界。停止不是流程圖上的箭頭,而是每一個 PEP 必須重新驗證的安全條件。
Policy 只設定 scope,不設定 depth。A→B→C 的每一跳都保留 read_customer,C 卻把資料送到未註冊的 Export Tool;Tool 只看 scope 和有效期,因此 allow。另一種失敗是 high-risk delete 被標成可委派,第三個 Agent 在無人核准下執行不可逆 Action。
can_delegate=false,甚至直接禁止 Agent 代行。每個 Agent 只驗自己的 issuer、scope 與 expiry;沒有 maximum depth、terminal audience 或 domain allowlist。Delegation 被當成「只要 token 有效就可再轉交」。
Issuer 在 grant 中寫入 max_depth、remaining_hops、terminal_audience、non_delegable_actions、allowed_domains 與 expires_at。每個 delegation service 與 Tool Gateway 都要在 enforcement point 消耗 hop、驗證 audience,並在跨 domain 時停止自動轉委派。
中央 grant issuer、各 Agent runtime、delegation service、terminal Tool 與外部 trust domain 分離。中央服務設定上限,但最後 Tool 仍需 defense-in-depth 驗證;Agent 不能以「我是 chain 最後一跳」自我宣告 terminal。

PEP/PDP 應逐項判斷:remaining_hops > 0、callee 是否允許的 delegate、最終 audience 是否匹配、Action 是否在 non-delegable set、domain 是否相同,以及 chain expiry 是否仍有效。若 grant 設定 terminal read-tool,B 不得把它交換成 export-tool;若需要跨 domain,應產生新的 local grant 並留下原 chain reference,而不是默默信任外部 issuer。
RFC 8693 的交換模型可作為實作基礎,RFC 8707 的 resource indicator 可協助限制 audience;Zero Trust 的 NIST SP 800-207 則提醒,網路位置或既有連線不應被視為持續信任。停止條件仍應由企業 policy 明確定義。
def delegate(g, callee, action, domain="corp"):
if g["remaining_hops"] <= 0: return "deny: hop limit"
if callee != g["terminal"]: return "deny: audience"
if action in g["non_delegable"]: return "deny: non-delegable"
if domain not in g["domains"]: return "deny: trust domain"
return {**g, "remaining_hops": g["remaining_hops"] - 1}
g = {"remaining_hops":2, "terminal":"read-tool", "non_delegable":{"delete"},
"domains":{"corp"}}
g = delegate(g, "read-tool", "read")
assert isinstance(g, dict)
g = delegate(g, "read-tool", "read")
assert isinstance(g, dict) and g["remaining_hops"] == 0
assert delegate(g, "read-tool", "read").startswith("deny")
assert delegate(g, "read-tool", "delete").startswith("deny")
assert delegate(g, "export-tool", "read").startswith("deny")
print("stop-condition checks: PASS")
PoC 驗證兩 hop 後第三 hop、high-risk Action 與錯誤 terminal audience 都拒絕;正式系統需把 counter 與 revoke state 放在具一致性的授權服務,避免平行請求重複消耗失敗。
Part 3 到此回答「Agent 代表誰、權力在哪裡停止」。Day 16 轉進 Part 4:即使 Agent 看得到一個 Tool,也不代表它有權執行其中每個 Action。