哪些條件應觸發 Human Approval,且 approval 如何與即將執行的 Action 綁定?
Agent 要刪除 300 筆客戶資料。PDP 判定 risk 高,回傳 approval_required。若 UI 只顯示「Agent 想要清理資料」,Alice 可能核准模糊意圖;之後模型把 resource set 換成 30,000 筆,系統仍沿用 approval。Human-in-the-loop 只有在核准的是明確、未被偷換的 Action 時才有意義。
這不是把每一步都丟給人。Agent 的價值在於處理低風險、可逆工作;人應介入 policy 明確指定的高 impact、跨邊界、不可逆或 context 不足的步驟。
PDP 依 delete tool 產生 approval request,尚未執行時 Agent 修改了 resource IDs;或 approval 過期後 retry,PEP 只看到同一 task。這是典型 approve-one-execute-another 與 TOCTOU:核准時的 facts 和執行時的 facts 不一致。
觸發條件可包含 risk tier、resource sensitivity、批次數量、外部 destination、不可逆性、policy uncertainty 與超出 Task grant。Approval request 至少呈現 subject、actor、Task/purpose、operation、canonical resource set、參數摘要、資料分類、預期 side effect、expiry 與 policy reason。
授權服務對 canonical Action 序列化並計算 digest(例如 SHA-256)。核准證據包含 approval_id、approver、digest、policy version、issued_at、expires_at、constraints。PEP 執行前重新 canonicalize;digest、audience、expiry 任一不符即重新申請。人核准的是具體 Action,不是模型人格或整個 session。
用 chat 中的「好」當 approval;核准 tool name 或 Task 一次後,允許 Agent 任意改參數與重試。
PDP 回傳 approval_required obligation。Approval Service 產生人可讀摘要與 machine-verifiable digest;人核准限定 resource/constraints。PEP 在 side effect 前驗證 approval、digest、approver authority、expiry 與 resource state;拒絕、逾期、修改都 fail closed。
Agent 不能簽核自己提出的 Action。Approval UI、Approval Service、PDP、PEP 與 resource version 是分離邊界;通知內容不等於 approval evidence。
保留 subject=alice、actor=agent://ops/instance/20、approver=manager@corp。Approver 的 authority 由獨立 identity provider 驗證,不能只信任 chat username;approval audience 綁定 PEP/Tool。
PDP 先決定 allow/deny/approval_required;Approval Service 不重新放寬 policy,只能在指定範圍內簽發證據。PEP 是最後 enforcement point。

import hashlib, json, time
def digest(action):
raw = json.dumps(action, sort_keys=True, separators=(",", ":")).encode()
return hashlib.sha256(raw).hexdigest()
action = {"op": "bulk_delete", "resources": ["c1", "c2"], "task": "T-20"}
d = digest(action)
approval = {"digest": d, "expires": time.time() + 60, "approver": "manager"}
def execute(candidate, evidence):
return (digest(candidate) == evidence["digest"]
and time.time() < evidence["expires"])
assert execute(action, approval) is True
changed = {**action, "resources": ["c1", "c2", "c3"]}
assert execute(changed, approval) is False
expired = {**approval, "expires": time.time() - 1}
assert execute(action, expired) is False
print("bound-approval=allow parameter-change=deny expiry=deny")
Day 21 從 approval 的 expiry 接續到一般 authority lifecycle:Agent 的權限能否只存在五分鐘,以及多步 Task 如何安全續期。