Zitadel 這個名字在自架 IdP 的討論裡出現頻率一直偏低。中文社群提 SSO 幾乎只講 Keycloak 跟 Authentik,Zitadel 頂多在英文技術部落格的比較文章裡被順帶提到,很少人真的認真拆過它跟另外兩者在架構層次的差別。這個情況在 v4 於 2025 年 8 月 GA 之後開始有點微妙——當團隊拿了 B2B SaaS 專案準備做多租戶身份管理,Keycloak 跟 Authentik 的模型會在某個時間點撞牆,而 Zitadel 從第一版就是為這件事設計的。
Instance / Organization / Project 四層直接刻進資料模型
Keycloak 的 realm 是最接近租戶概念的抽象,但 realm 之間幾乎完全獨立——共用一組 master admin,其餘資料互不相通。B2B SaaS 常見需求是「一個平臺、多個租戶、每個租戶自己有 admin,但整個平臺還是同一批工程師管」,realm 這種扁平結構要撐這件事得靠應用層寫 policy 去補。
Authentik 的做法接近,但它的 tenant 概念本質是「同一個服務不同 branding」——UI 樣式、登入頁、寄件網域可以分開,權限跟資料還是共用的。想真的做租戶隔離得靠 group 加上 policy engine 疊出來,Authentik 官方也明講 tenant 不是核心功能。
Zitadel 的資料模型從第一版就是 Instance → Organization → Project → Application 四層。Instance 是整個 Zitadel 部署,Organization 對應到租戶,Project 是租戶下的應用集合,Application 是實際的 client。每一層都有自己的 policy scope、branding、admin 帳號、IdP 設定。想做到「租戶 A 用 Google 登入、租戶 B 綁自家 SAML」這種需求,Zitadel 只是切換 Organization 的 IdP 設定,不用寫任何額外邏輯。
代價是心智模型比 Authentik 重。Zitadel 的 admin console 得學會分辨自己站在哪一層——很多設定在 Instance 跟 Organization 都能改,設在哪裡決定會不會被下層覆寫。第一次上手的體感確實比 Authentik 那種扁平介面陡。
事件溯源不是為了炫,是為了審計
Zitadel 底層跑的是完整的 Event Sourcing 加 CQRS。每一次帳號建立、密碼變更、MFA 綁定、Role 分派都以不可變事件寫進 eventstore,讀取路徑另外從事件投影出讀取模型。這個設計聽起來像技術炫技,實際上是拿來解一個很現實的問題——SaaS 廠商賣給企業客戶時,SOC 2、ISO 27001 這些認證都要求完整的身份操作稽核紀錄,而且事後不能被修改。
傳統 IdP 靠應用日誌或事件表補這件事,資料完整性完全看寫日誌那段程式碼有沒有漏掉某條路徑。Zitadel 直接反過來——讀取模型從事件投影而來,改變狀態沒有其他路徑,稽核紀錄跟業務資料是同一份。想匯出所有 admin 操作走 API 就能拉,不用另外接 log pipeline。
代價是資料庫寫入模式很不 PostgreSQL——高頻寫入單一 eventstore table,讀取幾乎全靠投影出來的讀取模型。這個特性也是 v3 為什麼要把 CockroachDB 換掉的關鍵原因。
v3 把 CockroachDB 拿掉,回到單顆 PostgreSQL
Zitadel 最早選 CockroachDB 是看上分散式 SQL 天然的多區域高可用——想像中的部署形態是全球多節點跨區同步。實務上跑起來完全不是這回事。官方 2024 年那篇搬遷文寫得很直白:CockroachDB 每個區域要 3 節點乘上 8 CPU + 32GB RAM 才撐得起來,利用率停在 40 到 50%,成本大約是同等 PostgreSQL 配置的三倍。分散式共識帶來的延遲讓 API 回應時間比預期高,而事件溯源的高頻寫入模式又特別吃這種延遲。
換成 PostgreSQL 之後 Cloud SQL 4 CPU + 16GB RAM 就能達到接近的 per-region 效能,垂直擴充到 128 CPU 加 1TB RAM 也還有空間。v3 於 2025 年 3 月釋出時正式移除 CockroachDB 支援,v2 分支延續到 2025 年 9 月 EOL。自架者要注意這條時間線——還停在 v2 的部署要升到 v4 得先過 v3 這道資料庫遷移關卡。
v4 的 Actions v2 把 Deno runtime 抽掉換成 webhook
v3 之前 Zitadel 的 Actions 系統是把 Deno runtime 嵌進 IdP,允許使用者上傳 JavaScript 在 request / response 生命週期跑客製邏輯。這條路走了三年之後 v4 決定砍掉重來。Actions v2 只保留三個概念:Target 是外部 HTTP endpoint、Execution 是綁定條件、Function 是可執行點。所有客製邏輯搬到 Zitadel 外部的 webhook 服務,Zitadel 本身不跑任何使用者程式碼。
這個轉變的意義超過看起來的規模。Deno 嵌在 IdP 裡的架構讓 Zitadel 得替使用者程式碼負責安全隔離、CPU 限制、依賴管理——這些每一項都是 IdP 團隊不想扛的責任。改成 webhook 之後這些問題全數推給接收端,可以是 Cloudflare Worker、AWS Lambda、自架的 Node 服務都行,Zitadel 團隊只需要保證事件可靠送達。
代價是延遲多一次網路 roundtrip,而且 webhook endpoint 掛掉會直接影響 IdP 流程。實務上多數場景其實不需要在 request path 跑客製邏輯,post-provisioning 這類非同步 webhook 就足以應付。真的要在登入 path 塞邏輯的少數場景才會被這個改變影響到。
AGPL 3.0 對自架者其實沒差
Zitadel v3 起把授權從 Apache 2.0 改成 AGPL 3.0,這件事在英文技術圈引起過小規模反彈。實務上對絕大多數自架部署完全沒差——AGPL 的觸發條件是「修改過的原始碼提供給網路上其他人使用時要開源自己的修改」。內部工具、公司 SSO、B2B SaaS 只要沒動 Zitadel 原始碼都不受影響。真的要修改核心且對外提供 SaaS 服務的少數場景才需要買商業授權。
比較實在的變化是 v3 之後釋出節奏改成主版本 3 個月一次、次版本 2 週一次。過去 Zitadel 的釋出節奏偏隨機,企業採用者對升級週期很難排。改成固定節奏之後 rolling upgrade 政策才有辦法寫進運維 SOP。
什麼時候該選 Zitadel
需求如果只是「幾個內部服務要 SSO、每個服務手動塞使用者名單」,Pocket ID 或 Authentik 才是對的答案,Zitadel 的多租戶概念反而會變成心智負擔。
真正該考慮 Zitadel 的情境是——正在做 B2B SaaS 產品需要租戶隔離、想一次滿足 SOC 2 / ISO 27001 的身份操作稽核、預期未來會有大客戶要求綁自家 SAML / LDAP、或團隊有 Go 背景想能真的讀懂 IdP 原始碼並且改造它。
自架 Zitadel v4 的最低配置是 4 vCPU、8GB RAM 加一顆 PostgreSQL 16 以上的實例,NVMe SSD 是硬需求——eventstore 的寫入延遲直接決定 IdP 整體的 API 效能。Docker Compose 版本官方持續維護,Kubernetes 用 Helm chart 也有官方版,v4 開始 Helm chart 品質才真的到 production ready 的水準。
想在臺灣自架 Zitadel 或其他身份基礎設施的團隊,NCSE Network 提供 Intel Gold CPU 加 NVMe SSD 的 VPS 主機,是方電訊機房的位置讓 IdP 的登入延遲維持在跟同機房服務接近的等級。細節可以到 ncse.tw 查看。