AuthN、AuthZ、Audit:後端最難的不是 CRUD,是把權限講清楚
後端工程有個很不浪漫的事實:真正的大魔王通常不是效能,也不是資料庫,而是 3A:
- AuthN(認證):你是誰
- AuthZ(授權):你能做什麼
- Auditing(審計):你做了什麼、何時做的、能不能追溯
只要這三個沒搞清楚,你的服務很容易就變成在網路上裸奔。
## 為什麼「只靠 API Key」很常翻車
很多 API 為了方便,直接用一組 API key 當門票。
它的問題不是不好用,而是它的安全語義太弱:
- 它通常代表的是「某個程式/某個 client」
你知道是某個 app 在呼叫,但你不知道背後是誰在操作。
- 它是靜態憑證
外流一次就很麻煩:
- 很難追到是誰拿走的
- 很難做到細粒度撤銷
- 也很難做行為歸因
- 把權限切到每個使用者的 key 管理成本爆炸
你可以給每個人發 key,但你會得到:
- 旋轉與撤銷的地獄
- 權限變更的地獄
- 稽核與責任歸屬的地獄
## Google 的思路:把「應用程式識別」與「使用者身分」拆開
一個很直覺的比喻是:
- API Key = 車牌:辨識是哪個 App 來的,用於配額、計費、流量控管
- EUC(End-User Context)= 駕照:承載「當前操作者」的身分與權限,並加密/簽章保護
這其實就是把兩個問題拆開治理:
- 你要不要允許這個 App 進來?(車牌)
- 你要不要允許這個使用者做這件事?(駕照)
這種設計的好處是:即便 API key 外流,攻擊者如果拿不到合法的 EUC,也難以存取使用者的私有資料。
## 回到 3A:EUC 不是銀彈,但它讓你的安全語言變清楚
很多後端安全事故,都是因為系統缺少這些能力:
- 你無法清楚回答「誰在做」
- 你無法清楚回答「他被允許做什麼」
- 出事時你無法清楚回答「他到底做了什麼」
EUC 這類設計不是要把系統變得複雜,而是要讓你能用更一致、更可稽核的方式回答這三個問題。
## 工程上怎麼落地(最小可行)
如果你不想一口氣上到最重的架構,最小可行可以先做到:
- 把 API key 當成 app-level credential:只做配額、計費、粗粒度 allowlist。
- user-level identity 用可撤銷 token:例如 OAuth/OIDC 的 access token,短效期+可刷新。
- 每個 request 帶上 user context:後端做權限檢查,不要靠前端保證。
- 審計日誌要可查:至少包含 who/what/when/where,並能對照 request id。
先把語義做對,再來談優化。
## 結尾
後端的安全設計,本質是把兩個句子講清楚:
- 這是誰在用(AuthN)
- 他被允許做什麼(AuthZ)
最後再加上一句:出事了你能不能回放(Audit)。
只靠一串 API key,通常只能回答「從哪裡來」。
但真正的安全架構,必須能回答「誰在用」。
#Backend #Security #AuthN #AuthZ #Auditing #API