7.38 外部身分與本地紀錄:兩條生命週期在哪裡分岔
本章接在 7.31 認證方式選型 判定走委派之後,處理那一章列為依賴而沒有展開的三件事:對方停用帳號時這邊怎麼知道、使用者離開之後資料歸誰、以及同一個人帶著第二個來源出現時怎麼對應。
這三者出自同一個原因,只是在不同的時點浮現。
本章涵蓋與不涵蓋
本章聚焦委派身分成立之後,本地那筆紀錄要怎麼跟著外部身分走。要不要委派、委派與自建的取捨在 7.31。內部身分的權限分級與會話收斂在 7.2 身分與授權邊界;供應商那一端出事之後自己這邊的收斂責任在該章的供應商身分鏈傳導一節。機器對機器的跨組織信任與 token 範圍走 7.10 Workload Identity 與聯邦信任邊界,主體是機器而非人。B2B 每租戶各帶自己的身分提供者這項可設定能力在 7.40 B2B 多租戶的身分接入,它是本章的上一層——本章假設對應關係已經接上,那一章問的是這個接法要做成幾組設定、誰來填、填的內容憑什麼可信。
判讀軸:委派之後這邊還剩下一筆紀錄
委派——把登入整個交給外部的身分提供者,使用者拿著對方的憑證過來——給人的直覺是「帳號交給對方管了」。實際留下來的狀態要看清楚:這邊仍然有一筆本地紀錄,它至少存了一個對應到外部身分的識別值,通常還存了權限、偏好設定,以及使用者在這個服務裡產生的全部資料。
於是這裡有兩個生命週期——外部身分的(由對方的目錄決定:建立、停用、刪除)與本地紀錄的(由這邊決定)。委派預設同步的是「登入」這一個時點,其餘的時點各走各的——除非另接一條反向通道,做法見「對方停用之後這邊怎麼知道」。本章的三個問題都是這兩條線在某個時點分岔的結果。
| 分岔的時點 | 產生的問題 |
|---|---|
| 外部身分被停用 | 本地紀錄不知道,會話與 fallback 都還開著 |
| 外部身分永久消失 | 本地紀錄承載的資料歸誰 |
| 同一個人帶第二個來源來 | 對應從一對一變成多對一,而判斷依據不可靠 |
判讀的起點因此是一個問句:**這筆本地紀錄的哪些狀態變化,會有事件通知我。**多數系統的答案是「只有登入」,而那正是三個問題的共同成因。
對方停用之後這邊怎麼知道
委派的資料流方向是單向的,而且由使用者發動——他拿著對方的憑證過來。對方的目錄裡發生的事情,這邊沒有任何機制會知道。要拿到帳號狀態的事件,需要另接一條反向通道,而它的落點在對接契約而非自己這邊的程式碼。
既成的標準有三個,管的粒度不同。
SCIM(跨網域身分管理系統)管帳號本身:對方的目錄建立、更新或停用帳號時推送到這邊的端點,這邊照著建立或停用本地紀錄。它的獨有能力是推送完整的帳號紀錄與屬性、驅動這邊建立與更新,也就是接手整個開通流程;另外兩種只送事件、不帶紀錄狀態。
OIDC 的 back-channel logout 管會話:使用者在對方那裡登出時通知這邊撤銷對應的會話,通知可以指定單一會話、也可以指涉該使用者在這邊的全部會話。粒度落在會話層,涵蓋不到「帳號被停用而使用者沒有登出」這個最常見的形態。
Shared Signals 管安全事件:帳號停用、帳號刪除、會話撤銷、憑證變更這類事件的推送框架,設計目標正是跨組織的狀態同步。停用與刪除這兩件事它與 SCIM 都送得出來,差別在它送的是事件而非紀錄——這邊要自己決定收到之後做什麼。
選哪一種由對方支援什麼決定,所以這是導入當下要問的問題。三個都沒有時,剩下的做法都在自己這一側縮短窗口。成本最低的是換發時回打對方——長效憑證換成短效憑證的那一刻順便確認帳號還在,OIDC 的標準流程就含這一步,而且使用者無感。做不到換發的系統退而縮短本地會話的有效期、強制使用者定期重新走一次對方的登入,把「不知道對方停用了」的窗口從無限長縮到一個會話的長度,代價是登入頻率上升。兩者都是替代方案而非最佳做法,選了要在導入時記下來。
停用同步還有一個位置容易漏掉:當初為「沒有那個來源帳號的使用者」留的 fallback。那條路徑不看外部身分的狀態,於是對方停用帳號之後它對這個人照樣開著。處置是把停用落到本地紀錄本身,而不只是撤銷會話——本地紀錄停用之後,所有進得來的路徑一併關上。撤銷會話與停用紀錄的差別與 7.37 密碼外洩之後 的那一組是同一件事。
使用者離開之後資料歸誰
這是產品與契約的決定。工程這一端要做的是讓幾種可能的處置都執行得出來,而選哪一種在導入當下就要定。
導入時要定案的是三個問題。保留多久:外部身分消失之後,本地紀錄與資料是立刻刪除、保留一段固定期間,還是無限期留著。歸誰:使用者在這個服務裡產生的內容,離開之後屬於他個人還是屬於那個組織。匯出給誰:要不要提供匯出、匯出給離開的個人還是給組織的管理者。
第二個問題在某些形態上會直接衝突,值得單獨看一眼。B2B 的預設答案多半是組織——工作產出屬於雇主;消費端的預設答案多半是個人。而「用公司帳號登入的個人向服務」剛好落在兩個預設的交界上,兩邊都主張得出理由。落在這個交界上的服務要把答案明寫進契約,因為預設值在這裡不存在。
寫進契約的理由是這個決定在事發當下會被兩邊的立場拉扯,而這邊夾在中間沒有依據。導入當下決定的成本是一次討論;事發當時決定的成本是一次爭議,而且爭議期間資料還在這邊。
工程這一端的最小交付是刪除與匯出各自做得到,而做得到的前提是歸屬關係在資料模型裡表達得出來:哪些資料掛在使用者身上、哪些掛在組織身上、哪些兩者共有。刪除那一半與 7.11 資料駐留、刪除與證據鏈 共用同一套基礎,匯出那一半的治理走 7.4 資料保護與遮罩治理。
同一個人帶著第二個來源出現
問題的形狀是對應關係從一對一變成多對一,而判斷「這兩個外部身分是同一個人」的依據不可靠。
最常被拿來當依據的是電子郵件地址,它在兩個方向上都不成立。相同的信箱不保證是同一個人——企業信箱在離職之後會被重新指派,個人信箱也可能易主。不同的信箱也不代表不是同一個人——同一個人在不同來源用不同信箱是常態。
所以預設做法是不自動合併,改成讓使用者在已登入的狀態下主動綁定第二個來源。這一步的可靠性來自他證明得出自己同時控制兩邊,而不是來自任何欄位的比對。
不自動合併的代價是帳號分裂:同一個人有兩筆本地紀錄、兩份資料、兩套設定。這個代價要跟另一邊對照著看,而兩者的性質差很多。自動合併判斷錯誤的後果是把一個人的資料交給另一個人。 而它發生時不產生任何訊號——雙方都覺得登入正常。分裂造成的困擾使用者會主動來反映,錯誤合併造成的外洩不會。兩種錯誤的可發現性不對等,這是預設值選在不合併那一邊的理由。
補救分裂的路徑要事先設計:使用者發現自己有兩個帳號時,要有一條把它們併起來的流程,而那個動作要求兩邊都證明控制權。這條路徑本身是高風險端點——它把兩份資料合到一起——授權設計走 7.2 代理操作的授權邊界。
判讀流程
- 列出本地紀錄有哪些狀態,逐一問「這個狀態變化有沒有事件來源」。答案只有登入時,其餘的狀態變化目前靠人工,而人工的觸發條件要寫下來。
- 對接當下問對方支援哪一種反向通道,把答案寫進契約。三者都沒有時用會話有效期把窗口縮短,並記下這是替代方案而非最終狀態。
- 確認停用同步的落點是本地紀錄本身,而不只是會話。落在會話上時 fallback 路徑仍然開著。
- 在導入當下定資料歸屬三問(保留多久、歸誰、匯出給誰),寫進契約。落在 B2B 與消費端交界的服務要明寫,那個交界上沒有預設值。
- 帳號對應預設不自動合併,並準備一條要求雙邊證明控制權的合併路徑。
- 排一個定期對帳:把本地紀錄與對方目錄的現況比一次,列出兩邊不一致的。這一步是前面所有機制的兜底——推送會漏、事件會丟,而遺失本身不產生訊號。
這個決定失敗時長什麼樣
他離職幾週之後,公司的管理者來要那些資料;差不多同時,那個人來要匯出自己的內容。
這是一個 B2B 服務,他用公司的身分提供者登入,累積了數年份的文件、設定與往來紀錄,離職時公司在目錄裡停用了帳號。而這邊沒有任何依據可以決定資料給誰。契約裡沒有這一條——導入當時談的是資料保護、可用性與價格,帳號生命週期被歸類成對方的事。工程上更麻煩的是那些資料在模型裡沒有明確的歸屬:它掛在一個使用者識別值上,而那個識別值同時屬於那個人與那個租戶,兩邊的主張都對得上資料庫裡的欄位。
這種缺口在事件發生前不產生任何徵兆,而它在導入時被跳過的方式很具體:委派把「帳號」這個概念交了出去,於是「帳號消失之後」這個時點沒有人負責想。
這件事沒有技術解,只有先談好或後爭議兩種。
常見風險邊界
- 本地紀錄的狀態變化只有登入這一個事件來源時,其餘時點全部靠人工,而人工的觸發條件多半沒有寫下來——生命週期因此只設計了一半,且缺的那一半不產生錯誤訊息。
- 反向通道談成了而沒有排定期對帳時,推送遺失是靜默的——推送機制的失敗不會在這邊留下任何紀錄。
- 停用只撤銷會話而沒有停用本地紀錄時,當初留的 fallback 路徑對已離職的人仍然開著。
- 資料歸屬沒有寫進契約時,這個決定會在爭議發生時做,而那時兩邊都已經有立場。
- 用信箱自動合併帳號時,判斷錯誤的後果是資料交給錯的人,且不產生訊號。
- 本地紀錄與外部身分在資料模型裡寫死成一對一時,第二個來源出現時表達不了,補救要改資料模型而非改流程。
下一步路由
- 要不要委派、委派與自建的取捨:7.31 認證方式選型
- 每個客戶各帶身分提供者時的設定與網域驗證:7.40 B2B 多租戶的身分接入
- 撤銷會話與停用紀錄的差別、以及範圍怎麼分層:7.37 密碼外洩之後
- 刪除能力的基礎:7.11 資料駐留、刪除與證據鏈
- 匯出治理:7.4 資料保護與遮罩治理
- 合併帳號這條高風險路徑的授權設計:7.2 代理操作的授權邊界
- 供應商那一端出事後自己這邊的收斂責任:7.2 供應商身分鏈傳導
- 機器對機器的跨組織信任與 token 範圍:7.10 Workload Identity 與聯邦信任邊界
- 稽核欄位要記什麼、保存多久才夠回查:7.7 稽核追蹤與責任邊界