一句自然語言同意如何轉成對收件者、內容、次數與期限都有邊界的可執行 authority?
send_emailAlice 對 Support Agent 說:「把這次退款摘要寄給財務。」Agent 需要知道「這次」是哪個 task、財務是哪個已註冊收件群組、摘要允許哪些欄位,以及只能寄一次。若 consent 只換成 send_email scope,Agent 就能改寄外部地址、附上原始客戶資料,或在稍後重放同一 grant。
傳統 OAuth scope 多半描述一類 API 能力;Agent 的 Action 參數卻由模型在執行時生成,且可能受前一步查詢結果影響。自然語言 intent、使用者確認、formal grant 與真正送出的 message 不是同一份資料,必須透過 canonicalization 和 digest 連起來。
錯誤流程是:UI 顯示「允許寄信」,使用者按下同意後,Agent 取得 broad scope;模型將收件者改成 external@evil.test,把「摘要」擴成完整明細,Gateway 仍因 scope 有效而 allow。即使人曾同意,也沒有證據顯示人同意的是這個收件者與內容。
jti、使用次數、expiry 與 idempotency key 必須在 PEP 消耗並記錄。UI 將「幫我寄信」換成永久 send_email scope;Agent 直接把任意 message POST 到 mail API,沒有結構化 constraints,也沒有將核准內容與執行內容比對。
Intent service 產出待確認 grant。使用者確認後,Authorization service 簽發一次性、短效、audience-bound grant。PEP 對 Action 做 canonical JSON、計算 digest,只有 digest、recipient、content class、task 都吻合才呼叫 Tool。
User UI、Agent runtime、grant issuer、PEP/PDP、Mail Tool 各自分界。模型可提出 draft,但不能簽發 grant;Mail Tool 也不應接受 Agent 自帶的未驗證 recipient header。

grant = {
"sub": "alice", "task": "refund-12", "recipient": "finance@example.test",
"content_class": "refund-summary", "max_count": 1, "jti": "g-1"
}
PDP 的 allow 條件是:sub 與 actor context 正確、task 尚未完成、recipient 與 class 完全符合、grant 未過期且 jti 未消耗。建議採用 RFC 9396 Rich Authorization Requests 的結構化請求思路;RFC 9449 DPoP 可在需要時綁定 sender,但不能取代 message 參數 policy。
import hashlib, json
def digest(action):
raw = json.dumps(action, sort_keys=True, separators=(",", ":"))
return hashlib.sha256(raw.encode()).hexdigest()
action = {"recipient":"finance@example.test", "content_class":"refund-summary"}
grant = {"digest": digest(action), "uses": 0, "max_count": 1}
def execute(candidate):
if grant["uses"] >= grant["max_count"]: return "deny: replay"
if digest(candidate) != grant["digest"]: return "deny: parameters changed"
grant["uses"] += 1
return "allow: send"
assert execute(action) == "allow: send"
assert execute(action) == "deny: replay"
assert execute({"recipient":"external@evil.test", "content_class":"refund-summary"}) == "deny: replay"
print("binding and replay checks: PASS")
第三個案例特意在 replay 後執行;正式實作應對每次 candidate 先做 digest mismatch 檢查,並以原子操作消耗 jti。這個 PoC 證明「同意的 Action」必須是可比對的資料結構。
Day 13 會問更棘手的問題:即使 Alice 本人能讀全部資料,Agent 是否仍應只讀必要欄位與筆數?
未驗證事項:PoC 未實作時鐘、簽章與分散式原子 replay store;這些是 production 必須補上的 enforcement 細節。