iT邦幫忙

2026 iThome 鐵人賽

DAY 27
0
AI Security

AI Agent 憑什麼動手?30 天拆解 Agent Identity、Delegation 與 Authorization系列 第 27 篇

Day 27|怎麼證明某個 Action 真的是 Agent 在當時被允許執行?

  • 分享至 

  • xImage
  •  

Core Question

如何證明特定 identity 在特定 delegation 與 policy version 下,獲准執行未被竄改的 Action?

今天的問題

Agent 要替 Alice 退一筆款。PDP 回傳 allow,數秒後 PEP 卻送出另一個帳號與更大的金額。普通 audit log 兩邊都留下 200 OK,卻無法證明批准的內容和實際執行的內容相同。

為什麼這不是傳統 IAM 問題

Agent 的 Action 在規劃、approval、retry 和 execution 間可能被重新生成;同一個長任務還可能跨 policy 版本與 delegation expiry。Authentication 證明 caller 是誰,audit log 記錄發生過什麼,但企業還需要一份綁定「誰、代表誰、哪個 Action、哪版 policy、到何時」的 decision evidence。這個 binding 是 Agent-specific 的,因為 Action 並非固定 UI 流程,而是模型動態提出。

Threat / Failure Scenario

Naive 設計以 decision_id=allow-1 作為旗標,PEP 收到同一旗標就執行 request body。攻擊者或 buggy retry handler 修改 amount、recipient 或 resource,仍能重用 allow。另一種錯誤是只簽整個 token,卻沒有把具體 Action canonicalize,造成「批次退款」和「單筆退款」使用同一權限。

核心概念

Decision Receipt

PDP 應產生短效 decision receipt:subject、actor、delegation id、audience、canonical Action digest、resource、constraints、policy id/version、issued_at、expires_at、nonce 與 decision。簽章提供完整性與來源驗證;PEP 在執行前重新 canonicalize 實際 request,比對 digest、audience、expiry 和 constraints。簽章不會替 PDP 決定 policy,也不會證明 Resource 一定已改變;outcome 仍需另記。

可用 JWT/JWS 或其他標準簽章格式承載,但不要把格式當成架構。OAuth Token Exchange 的 actor/subject 語意可描述代行鏈;RFC 8693 不是完整 Agent authorization receipt 規格。JWS 定義簽署與驗證表示法;RFC 7515 也不替應用定義 Action 欄位。

Architecture Pattern

Naive / Unsafe Design

PDP -- allow-1 --> PEP -- decision_id only --> Tool
                         (body may change)

Recommended Design

https://ithelp.ithome.com.tw/upload/images/20260925/20120151HpmvYJRnOh.png

Trust boundary 在 PDP/PEP 之間與 PEP/Tool 之間:Agent 不能自己簽 receipt;PEP 不能只信 Agent header;Tool 只接受 Gateway 的受限呼叫或再驗證 receipt。Authorization Decision Point 是 PDP,真正 enforcement 是 PEP。Identity flow 為 User subject + Agent actor + delegation → canonical Action → signed receipt → PEP 驗證 → Tool。

小型 PoC

import base64, hashlib, hmac, json, time

key = b"local-demo-key"
def canon(action):
    return json.dumps(action, sort_keys=True, separators=(",", ":")).encode()
def digest(action): return hashlib.sha256(canon(action)).hexdigest()
def sign(body):
    raw = json.dumps(body, sort_keys=True, separators=(",", ":")).encode()
    mac = hmac.new(key, raw, hashlib.sha256).hexdigest()
    return base64.urlsafe_b64encode(raw).decode() + "." + mac
def verify(receipt, action, now):
    encoded, mac = receipt.split(".", 1)
    raw = base64.urlsafe_b64decode(encoded.encode())
    if not hmac.compare_digest(mac, hmac.new(key, raw, hashlib.sha256).hexdigest()): return False
    body = json.loads(raw)
    return body["action_digest"] == digest(action) and now < body["exp"] and body["aud"] == "tool:refund"

action = {"op": "refund", "account": "A-7", "amount": 10}
receipt = sign({"sub": "alice", "actor": "agent:i-1", "aud": "tool:refund",
                "action_digest": digest(action), "exp": 200})
assert verify(receipt, action, 100)                 # allow
assert not verify(receipt, {**action, "amount": 1000}, 100)  # tamper reject
assert not verify(receipt, action, 201)              # expiry reject
print("allow, tamper-reject, expiry-reject")

這是完整性示範,故使用 HMAC;正式跨信任域應使用受管理的非對稱金鑰、key id、rotation、replay protection 與安全時間來源。PoC 沒有宣稱法律上的不可否認性,也沒有替 Resource outcome 做證明。

今天得到什麼

  • Allow log 不能取代綁定 Action 的 decision receipt。
  • PEP 必須在執行前比對 canonical Action digest、audience、expiry 與 constraints。
  • 簽章提供完整性與來源,不會自動證明 policy 正確或 side effect 成功。
  • Token Exchange、JWT/JWS 是可用 building blocks,不是完整 Agent evidence profile。

下一篇

即使 receipt 有效,Task 也可能在多步執行中被撤銷。下一篇處理 grant revocation 與已經 in-flight 的 Agent task。

參考資料


上一篇
Day 26|Agent 做錯事後,Audit Log 應該記 Prompt 還是 Action?
系列文
AI Agent 憑什麼動手?30 天拆解 Agent Identity、Delegation 與 Authorization 共 27 篇
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言