聯絡 EN 中文

身分平台

以自架 Supabase 打造職工與志工共用的三層身分平台

概念驗證 獨力完成

沒有公開連結,本頁說明問題、決策與成果。

一眼看懂

問題
慈濟基金會的職工與志工要登入許多各自獨立的業務系統,每個系統都有自己的帳號。
我做了什麼
一個內部 POC:三層身分平台。
成果
19 天做出可運作的內部 POC,含 38 支 SQL migration 與 191 個 TypeScript 測試檔;尚未上線。
我的角色
獨力完成
期間
2026-10-01 → 2026-10-19

展現的能力

每一項都連到能力頁上對應的能力與等級。

問題

慈濟基金會的職工與志工要登入許多各自獨立的業務系統,每個系統都有自己的帳號。「這個人是誰、今天具備哪些身分」沒有統一的答案,授權、撤銷和稽核都無法在同一個地方完成。

我做了什麼

一個內部 POC:三層身分平台。第一層負責登入與簽發 token;第二層是人員與組織身分的權威來源;第三層是各業務系統,依一份書面的接入契約串接,自己的資料與授權自己管。第一、二層刻意放在同一個自架 Supabase 專案。登入與授權同意頁、管理後台、示範用的業務系統,以及前面的 gateway,也都是我做的。

運作方式

  1. 業務系統以 OAuth 2.1 authorization code + PKCE 把使用者導向平台。
  2. 職工與志工按同一個 Google 按鈕。是否為職工,看的是 Google 在 ID token 裡簽出的 hd,不看 email 字串。
  3. 建立新帳號前,資料庫內的 hook 會擋下「看起來像職工、卻沒有 Google 簽章 hd」的登入。
  4. 簽發 token 時,另一個 hook 讀取治理資料,寫入 person_id、is_staff,以及這個業務系統獲准看到的身分與基本資料,其餘一律裁掉。
  5. 業務系統以 JWKS 在本地驗證 ES256 token,全程不必回頭呼叫平台。

關鍵決策

  • 選 Supabase Auth,不選 Zitadel。 比較過幾套開源 IdP 後決定:驗證碼登入是硬需求,而 Zitadel 只把它當第二因子。
  • 改走 OIDC,放棄 SAML。 POC 發現 GoTrue 不會拿 SAML assertion 裡的 email 去比對 provider 的網域,於是職工判定改看 Google 簽章的 hd,避開「用 email 字串授權」這一類漏洞。
  • 平台自發 person_id。 OIDC 只保證 issuer + subject 的組合穩定;業務系統存平台的識別碼,日後換 IdP 也不受影響。
  • hook 在資料庫裡執行。 兩個 hook 都是走索引的 SQL 函式,登入熱路徑零外部呼叫。

成果

目前是內部 POC/MVP,尚未上線。從開工到可運作的 POC 只花了 19 天,目前有 38 支 SQL migration、191 個 TypeScript 測試檔。接入契約(草案)把「不即時」的地方寫清楚:帳號停用或撤銷 session 後,已發出的 access token 最多還有 15 分鐘有效(另加業務系統自己的時鐘容許)。開發方式是用 Claude Code 跑「規格 → 計畫 → 實作 → 審查」循環;計畫經過設計、可執行性、資安三路審查,規格也交給 Codex 審過。