iT邦幫忙

2026 iThome 鐵人賽

DAY 6
0

Core Question

Tool 收到請求時,要驗證 User、Agent workload、Agent instance,還是三者的組合?

今天的問題:一個有效 Token 仍然不夠

假設財務 Agent 替 Alice 查詢逾期帳款,最後把摘要交給內部郵件 Tool。Tool 只看見一個 sub=alice 的 token,會以為 Alice 親自發出請求;只看見 sub=finance-agent,又無法知道這次是否真的獲得 Alice 的委派。若 Agent 把 X-User: alice 放在 HTTP header,任何能呼叫 Tool 的程式都能偽造它。

這不是在問「JWT 怎麼驗簽」,而是在問一次 Action 的責任鏈:誰是直接執行者、它代表誰、請求要送給哪個資源,以及哪個元件作出 allow。

為什麼這不是傳統 IAM 問題

固定後端服務通常只需辨認服務本身。Agent 會在同一個 runtime 連續提出多個、由模型決定參數的 Tool Call,且可在不同 Task 代表不同使用者。因此 authentication 的 subject 與 authorization 的 effective principal 必須分開。

若只傳 User token,會遺失 workload attribution;若只傳 Agent token,會把 Agent 自身權限誤當成 User delegation。Agent 的請求至少要有 subject(代表誰)、actor(哪個 instance 執行)、aud(給哪個 Tool)與 task_id(哪個任務)。

Threat / Failure Scenario

Naive 設計是 Agent 直接呼叫 Tool,Tool 信任 X-Agent-IdX-User-Id,或只驗證一個共用 bearer token。攻擊者若能重放 token,便能冒充 Agent;若能改 header,便能把自己的查詢記成 Alice 的委派操作。更隱蔽的錯誤是 token audience 是整個 API 平台,郵件 Tool 可拿同一 token 去呼叫 CRM。

核心概念

  • Authentication:驗證 issuer、簽章、expaud,並確認 credential 是給本 Tool 的。
  • Direct caller:實際建立連線的 Agent workload/instance,記為 actor
  • Delegated subject:被代表的 User,記為 sub;它不是直接連線者。
  • Authoritysubactor 的關係仍需由 delegation policy 驗證,不能由 caller 自行拼接。
  • Authorization:對具體 operation、resource、參數與 task 再作一次決策。

RFC 8693 的 act claim 正是用來表達 delegation 後的 acting party;RFC 8707 則說明以 resource indicator 限定 token 的目標資源。兩者都不是「自動允許寄信」的規則,PDP 仍要檢查 Action。

Architecture Pattern

Naive / Unsafe Design

Agent --共用 token + 可偽造 headers--> Tool

Tool 無法可靠區分 caller、代表人與 audience,且 Agent 能繞過 policy。

Recommended Design

由受信任的 issuer 簽發含 subactaudexptask_id 的 token;Tool Gateway 驗證 token,再把 canonical request 交給 PDP。Agent 只能提出 Action,不能自行變更 sub 或 scope。

Trust Boundary、Identity Flow、Authorization Decision Point

https://ithelp.ithome.com.tw/upload/images/20260911/201201518uoriSWYXI.png

User/issuer、Agent runtime、Gateway/PDP、Tool 是不同 trust boundary。Gateway 是 identity enforcement point;PDP 是 authorization decision point;Tool 仍應拒絕沒有 Gateway 可驗證 caller context 的直接呼叫。Tool audit 要同時記 sub=Aliceactor=agent://finance/v3/i-7

小型 PoC

以下只用 Python 標準庫,模擬簽章已由受信任 issuer 驗證後的 claims。它刻意拒絕只有 User、錯誤 audience、缺 actor 的請求。

import base64, json

def token(**claims):
    return base64.urlsafe_b64encode(json.dumps(claims).encode()).decode()

def authenticate(raw, expected_aud="tool://mail"):
    c = json.loads(base64.urlsafe_b64decode(raw + "=" * (-len(raw) % 4)))
    required = {"iss", "sub", "act", "aud", "exp"}
    if not required <= c.keys() or c["iss"] != "issuer://corp":
        return False, "missing-or-untrusted-claims"
    if c["aud"] != expected_aud or c["exp"] <= 100:
        return False, "wrong-audience-or-expired"
    return True, c

cases = {
    "delegated": token(iss="issuer://corp", sub="alice", act={"sub":"agent://mail/i-7"}, aud="tool://mail", exp=200),
    "user_only": token(iss="issuer://corp", sub="alice", aud="tool://mail", exp=200),
    "wrong_audience": token(iss="issuer://corp", sub="alice", act={"sub":"agent://mail/i-7"}, aud="tool://crm", exp=200),
}
for name, raw in cases.items():
    print(name, authenticate(raw)[0])
assert authenticate(cases["delegated"])[0]
assert not authenticate(cases["user_only"])[0]
assert not authenticate(cases["wrong_audience"])[0]

預期輸出為 delegated True、其餘 False。實際系統還必須驗證 JWT 簽章、issuer key rotation、nonce/重放、delegation scope 與 resource authorization;本例只證明 claims 的最小邊界。

今天得到什麼

  1. Tool 要同時辨認直接 caller 與 delegated subject。
  2. actaudiss 和 expiry 是可驗證輸入,不是 Agent 自報 header。
  3. Authentication 成功後,仍要對每次具體 Action 重新授權。
  4. audit 必須保存 User、Agent instance、Task 與 decision 的關聯。

下一篇

下一篇進一步問:如果 Agent 只有一把靜態 API Key,這把 key 能否證明上述四件事?

參考資料


上一篇
Day 05|替一個會呼叫 Tool 的 Agent 畫 Threat Model
系列文
AI Agent 憑什麼動手?30 天拆解 Agent Identity、Delegation 與 Authorization6
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言