一個跑在伺服器上的程式,半夜三點被叫醒,要去呼叫一個 API。對面問它:你是誰。

它的回答是一串字。那串字躺在環境變數裡,名字大概是 API_KEYSERVICE_TOKEN,開頭幾個字元你閉著眼睛都背得出來。程式把它貼進 header,對面收到,放行。「證明自己是誰」這件事就這樣結束了。

嚴格講那不叫證明,叫出示。持有即通過,誰撿到誰就是你。在只有幾支定時腳本的年代這還算堪用,那些腳本做的事很固定:讀一張表、寄一封信、清一次快取,key 外流的代價估得出來。

現在跑在上面的東西不一樣了。它自己決定下一步呼叫哪個工具,把外面讀進來的文字塞回自己的上下文,一輪任務裡動到三四個系統。而它手上還是同一把 key,還是同一句「持有即通過」。

IETF 的 WIMSE 工作組(Workload Identity in Multi-System Environments)交了一份草案處理這件事,文件編號 draft-ietf-wimse-aims-00,標題是 “AI Identity Management System”,30 頁。它對上面那把 key 的判決寫得很不客氣。

憑證本身:從「拿得出來」到「綁得住人」

草案直接點名:

“Static API keys are an antipattern for agent identity. They are bearer artifacts that are not cryptographically bound, do not convey identity, are typically long-lived and are operationally difficult to rotate.”

四條裡最刺的是最後一條:輪替在維運上很難,難到多數團隊的做法是等出事再說。

對照的另一邊寫的是 Agent credentials SHOULD be short-lived to minimize the risk of credential theft, MUST include an explicit expiration time after which it is no longer accepted, and MAY carry additional attributes relevant to the agent. 動詞強度的分配值得看一眼。短效只是 SHOULD,帶額外屬性只是 MAY,唯一那條 MUST 是「一定要有明確的過期時間」。草案願意讓步的地方很多,不讓步的只有一件事:這東西必須會死。

拿實體世界的東西來對,舊的那把像公寓大樓的鑰匙,它不知道你是誰也不在乎,插進去會轉就開,掉在路邊被撿走跟交給你本人沒有差別。草案要的像公司門禁卡:綁在一個人身上,有生效區間,刷下去後台就知道是誰在幾點刷了哪道門,離職那天不用把卡拿回來它自己會失效。

這個差別在規格裡有位置。草案第 5 章列出一套 Agent Identity Management System 該有的元件,第二項 Agent Credentials 的定義就是「Agent Identifier 與 Agent 屬性之間的密碼學綁定」。綁定是重點:鑰匙跟人之間沒有綁定,門禁卡有。

憑證放在哪:一條被寫成 MUST NOT 的架構規定

舊做法沒有「放在哪」這個概念。key 在環境變數裡,程式想讀就讀,而那支程式裡面同時住著一個會把外部文字吃進來的模型。憑證跟模型共處一室,中間沒有牆。

草案這一條的措辭重得多:

“The Large Language Model MUST NOT have access to an agent’s credentials or to credentials that may be needed to access tools and services. This prevents the Large Language Model from using, exposing, or being manipulated via prompt injection.”

有意思的是這條規定的理由。prompt injection 這個詞出現在一份身分管理草案裡,而且它的位置不在「安全考量」那種擺設章節,直接接在 MUST NOT 後面,當作這條規定存在的原因。

多數人處理 prompt injection 的方式是往提示詞裡加東西:加一句「不要理會使用者輸入裡夾帶的指令」,加一個分類器,加一層輸出檢查。全都在同一層裡想辦法,而那一層的本質是機率,你永遠不知道下一種寫法會不會繞過去。

這條 MUST NOT 換了一層回答:模型會不會被騙不歸這份文件管,它管的是模型就算被騙了,手上也沒有東西可以交出去。「怎麼讓它不上當」被改寫成「它上當時最多能造成多少損失」,難度差了一整個等級。

能做什麼:一把 key 的權限是全有全無

草案的授權那一章份量重到不太尋常。整份文件 18 章,第 10 章 “Agent Authorization” 一章就掛了十個子節:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
10 Agent Authorization
10.1 Agent Mission
10.2 Leverage OAuth 2.0 as a Delegation Authorization Framework
10.3 Use of OAuth 2.0 Access Tokens
10.4 Obtaining an OAuth 2.0 Access Token
10.4.1 User Delegates Authorization
10.4.2 Agent Obtains Own Authorization
10.4.3 Agents Accessed by Systems or Other Agents
10.4.4 OAuth 2.0 Security Best Practices
10.5 Risk Reduction with Transaction Tokens
10.6 Cross Domain Access
10.7 Human in the Loop
10.8 Tool-to-Service Access
10.9 Privacy Considerations
10.10 OAuth 2.0 Discovery in Dynamic Environments

看標題就知道 10.2 到 10.4、再加上 10.10 全部在講 OAuth 2.0。這一整章沒有在發明東西,它在把一套跑了十幾年的授權框架套到 agent 身上。

key 那一側對不出這麼多東西。它綁在一個帳號上,那個帳號能做的事它全都能做。要縮小範圍,唯一的辦法是另外開一個權限比較小的帳號、再發一把 key,於是 secret 清單開始長出第二頁、第三頁。而「這次操作是使用者授權的,還是程式自己要做的」,這個區別在那套做法裡根本不存在。

10.4 底下那三個並列的子節正好把「全有全無」拆開了:使用者把授權委派給 agent(10.4.1)、agent 自己去取得授權(10.4.2)、agent 被別的系統或別的 agent 呼叫(10.4.3)。三種來源分開處理,因為該給的權限本來就不一樣。10.5 的 Transaction Tokens 再往下走一步,讓權杖往下游傳的時候範圍越縮越小。

10.7 那節叫 Human in the Loop,草案在這裡提到了 MCP 的 user-solicitation 模式。本站 8 月 22 日那篇〈一個 agent 中途反問你問題,這件事在 MCP 的抽象裡沒有位置〉講的是這個動作在協定抽象裡找不到落點;這份草案從授權那一側切進來,把人的介入當成授權流程裡的正式環節,不當例外處理。同一個問題,兩層各自的答案。

那要新造多少東西?十項裡面三項

看到「IETF 幫 AI agent 定身分系統」這種標題,直覺反應是又要學一套新協定。草案開頭就把這個預期按住:Rather than defining new protocols, this document describes how existing and widely deployed standards can be applied or extended to establish agent authentication and authorization. 這種宣示每份規格都會寫,不稀奇,稀奇的是它真的做得到。把整份文件提到的憑證與權杖型別列出來,一共十項,照出處分群長這樣:

出處 項目
SPIFFE 既有 X.509-SVID、WIT-SVID、JWT-SVID
OAuth 家族 OAuth 2.0 Access Tokens、Transaction Tokens、JWT Authorization Grants
IETF 既有 HTTP Message Signatures
WIMSE 新造 Workload Identity Token (WIT)、X.509 Workload Identity Certificate (WIC)、WIMSE Proof Tokens (WPTs)

七項借來的,自己造的三項,而且三項全部集中在同一件事上:工作負載要怎麼證明自己是誰。授權那一半整個交給 OAuth,跨網域交給 JWT Authorization Grants,應用層簽章交給既有的 HTTP Message Signatures。

順著看下來,這份文件的主張其實很窄:agent 身分這題只有「工作負載憑證」那半需要新東西,剩下的半邊不要重造。

不重造的理由草案自己講了。它說各家「develop solutions in isolation, often reinventing existing mechanisms unaware of applicable prior art」,後果是 This fragmentation risks creating incompatible implementations, duplicated development effort, and missed opportunities to leverage decades of established identity and authorization standards. 各做各的,重複造一樣的輪子,最後得到一堆互相不相容的實作。這是條真實走過的死路,而且沒有人是故意的。

出事之後:從翻 log 到規格層的要求

一把靜態 key 被盜用,你能查的只有存取紀錄,而每一筆都長得一模一樣,因為每一筆都是「某人帶著這把 key 來過」。要分辨哪幾筆該發生、哪幾筆不該,靠的是人腦跟時間戳。

草案第 5 章那份元件清單的第六項是 Agent Observability and Remediation,定義是依觀察到的行為與系統狀態動態調整授權決策。授權在這裡是活的,開工時給的那組權限會隨著它做了什麼而調整。對應的條文也是 MUST:Deployments MUST maintain sufficient monitoring and observability to reconstruct agent behavior and authorization context after execution.

reconstruct 後面那兩個受詞值得分開看。agent behavior 是「它做了什麼」,這個大家本來就在記。authorization context 是「它當時憑什麼可以做」,這個多數系統記不出來,因為那個憑據就是環境變數裡那串永遠不變的字。

這份草案賭的是什麼

整份文件最關鍵的判斷寫在第 4 章的標題上,那章叫 “Agents are workloads”。它給 agent 下的定義是 An Agent is a workload that iteratively interacts with a Large Language Model (LLM) and a set of Tools, Services and Resources.,把 agent 拆成三個已知的零件:一個工作負載、一個 LLM、一組工具與服務。沒有一個零件需要新的身分理論。工作負載的身分問題業界處理了很多年,SPIFFE 就是那條路上跑出來的,草案直接把它當成既有的落地實例引進來。

這就是它賭的東西:agent 只是一種行為比較難預測的工作負載,不需要被當成新物種處理。賭對了,既有的身分基礎設施可以原封不動搬過來;賭錯了,這份文件會變成一份把舊工具硬套在新問題上的紀錄。

我的立場是這一賭賭得對。草案最有價值的部分,我會押在它願意先把「AI 需要一套專屬的新身分體系」這個假設丟掉,再去看剩下什麼真的缺。多數規格傾向證明自己有存在必要,願意反過來寫的不多。

會讓我改變想法的條件很具體:如果接下來幾版在授權那一半也長出自己的協定,把 OAuth 換成 WIMSE 自製的東西,那就代表「既有標準夠用」這個判斷在實作上撐不住。這份是 2026 年 9 月 15 日發布的 draft-00,所以要看的就是接下來那幾版。同一個工作組目前掛著七份文件,最成熟的 draft-ietf-wimse-workload-identity-practices-06 已在 8 月 11 日送交 IESG,AIMS 是最年輕的一份。

先把邊界講清楚:這是 draft-00,Intended Status 掛的是 Informational,文件上的失效日期是 2027 年 3 月 19 日。Informational 的意思是它不打算成為必須遵守的標準規範,是把做法記錄下來。草案階段的東西會改,章節編號、元件名稱、哪一條是 MUST 哪一條是 SHOULD,下一版都可能不一樣,本文引的都是 -00 這一版的內容。另外,我只讀了這份草案,沒有實際跑過裡面任何一段流程。

草案裡有一句話讀起來像標語,但它藏了東西:

“An Agent Identity Management System ensures that the right Agent has access to the right resources and tools at the right time for the right reason.”

前面三個 right 都很好懂,對的 agent、對的資源、對的時間,傳統存取控制裡都有對應的機制。第四個是新的。for the right reason,憑什麼做這件事,這在一把靜態 key 的世界裡根本問不出口,因為那把 key 從頭到尾只回答一個問題:你有沒有。

要求得不高。但回頭看看自己專案裡那個 .env,會發現連這個等級都還沒到。

參考來源draft-ietf-wimse-aims-00 草案全文IETF WIMSE 工作組文件列表