ZITADEL 开源身份基础设施:Docker Compose 自托管部署、冷启动架构与 V2 API 集成指南
【免费下载链接】zitadelZITADEL - Identity infrastructure, simplified for you.项目地址: https://gitcode.com/GitHub_Trending/zi/zitadel
ZITADEL 是一个开源的身份与访问管理(IAM)平台,为 SaaS 产品、B2B 平台和自托管生产环境提供 SSO、MFA、Passkeys、OIDC、SAML、SCIM 以及多租户能力。本文基于仓库根目录的 README.md 展开,结合 deploy/compose/docker-compose.yml 部署编排、cmd/start/start_from_init.go 冷启动命令实现与 go.mod 依赖清单等源码证据,讲解如何在 3 分钟内用 Docker Compose 跑起一套完整的 ZITADEL,理解其 API 路由与事件驱动架构,并学会通过 V2 REST API 管理用户资源。
ZITADEL 是什么
按照 README.md 的定义,ZITADEL 是一个面向"需要基础认证以上能力"的团队的开源 IAM 平台,开箱即用的核心能力包括:
- 单点登录(SSO)、用户名/密码、Passkeys(FIDO2 / WebAuthn)
- 多因素认证(MFA):OTP、U2F、OTP Email、OTP SMS
- 协议支持:OpenID Connect(官方认证过 OP 认证)、SAML 2.0、SCIM 2.0 Server、设备授权(Device Authorization)、机器对机器认证(JWT Profile、PAT、Client Credentials)
- 身份源集成:LDAP、企业 IdP 与社交登录
- 多租户:身份代理(Identity Brokering)、可自定义的 B2B 自助注册、委托角色管理、域名发现
- 扩展机制:Actions(webhook、自定义代码、token enrichment)、RBAC、审计日志对接 SOC/SIEM
- 管理与自助:自助注册(邮箱/手机验证)、Admin Console、按组织的自定义品牌
仓库的技术栈可以从 go.mod 中得到印证:项目基于 Go 1.25(toolchain go1.25.11),核心依赖中能看到connectrpc.com/connect(connectRPC 传输)、jackc/pgx/v5(PostgreSQL 驱动)、go-webauthn/webauthn(Passkey/WebAuthn)、crewjam/saml(SAML)、go-ldap/ldap/v3(LDAP)以及grpc-ecosystem/grpc-gateway/v2(REST/gRPC 网关)——这些与 README 宣称的协议与 API 能力一一对应。
为什么选择 ZITADEL:README 中的横向对比
README.md 给出了一张与其他主流身份平台的对比表(这是官方文档的陈述,选型时请结合最新版本自行验证):
| 维度 | ZITADEL | FusionAuth | Keycloak | Auth0/Okta |
|---|---|---|---|---|
| 开源 | 是 | 否 | 是 | 否 |
| 可自托管 | 是 | 是 | 是 | 否 |
| 基础设施级租户 | 是,Instances(高扩展) | 是,Tenants | 部分,Realms(有扩展限制) | 否(多租户 = 多账号) |
| B2B 组织 | 原生且无限制 | 部分,经 Entity Management | 是(近年新增) | 部分,依赖套餐/账号 |
| 完整审计轨迹 | 是,全面的事件流 | 部分,审计日志 | 部分,审计日志 | 部分,审计日志 |
| Passkeys(FIDO2) | 是 | 是 | 是 | 是 |
| Actions / webhooks | 是 | 是 | 部分,经 SPI | 是 |
| API-first(gRPC + REST) | 是 | 部分,仅 REST | 部分,仅 REST | 部分,仅 REST |
| SaaS 与自托管同构 | 是 | 是 | 不适用 | 不适用 |
README 特别强调:ZITADEL Cloud 与自托管版本运行同一套代码库,即 SaaS 与 self-host 在能力上完全对等。
面向架构师的四个关键差异点(README 原文归纳):
- 关系型核心 + 事件驱动内核:每一个变更(mutation)都会写成不可变事件,形成完整、可通过 API 访问的审计轨迹。与只记录部分活动的系统不同,ZITADEL 提供全面的事件流,可被审计或通过 Webhook 流式转发到外部系统。
- 严格的多租户层级:Identity System(实例)→ Organizations(组织)→ Projects(项目),数据与策略在多个层级隔离。
- API-first 设计:每一个资源和操作都可以通过 connectRPC、gRPC 与 HTTP/JSON API 访问。
- 零停机更新与横向扩展,且不需要外部会话存储。
三分钟自托管:Docker Compose 快速部署
快速开始
README.md 给出的快速部署命令是从本仓库拉取编排文件后一键启动:
# Docker Compose — 3 分钟内完成启动 curl -LO https://raw.githubusercontent.com/zitadel/zitadel/main/deploy/compose/docker-compose.yml \ && curl -LO https://raw.githubusercontent.com/zitadel/zitadel/main/deploy/compose/.env.example \ && cp .env.example .env \ && docker compose up -d --wait如果你已经克隆了本仓库,等价的做法是直接复用仓库内的两个文件:deploy/compose/docker-compose.yml(基础栈)和 deploy/compose/.env.example(配置模板),把.env.example复制为.env并填写域名、主密钥等值后执行docker compose up -d --wait即可。
仓库中还提供了几种 TLS 部署模式与进阶编排,均以基础栈为起点叠加 overlay:
| 文件 | 角色 |
|---|---|
| deploy/compose/docker-compose.yml | 基础栈,所有模式的起点,配合.env.example可独立运行 |
| deploy/compose/docker-compose.mode-letsencrypt.yml | TLS overlay:ACME HTTP challenge,声明独立的letsencrypt卷 |
| deploy/compose/docker-compose.mode-external-tls.yml | TLS overlay:由上游负载均衡器终结 TLS,启用转发头 |
| deploy/compose/docker-compose.mode-local-tls.yml | TLS overlay:自签名证书,挂载./certs/与 deploy/compose/traefik-local-tls.yml |
| deploy/compose/docker-compose.prodlike.yml | 生产形态:init/setup/start 分离启动,用 YAML 锚点共享数据库环境变量 |
| deploy/compose/otel-collector-config.yaml | OTEL Collector 管道配置,默认将 trace 输出到 stdout,可配置转发到后端 |
部署架构:五个服务的职责
从 deploy/compose/docker-compose.yml 的编排结构看,默认启动的栈由以下服务组成:
┌─────────────────────────┐ Browser ──────►│ Traefik (proxy) │ │ Port 80 / 443 │ └───┬──────────┬──────────┘ │ │ ┌──────────▼──┐ ┌───▼──────────┐ │ zitadel-api │ │ zitadel-login │ │ Go :8080 │ │ Next.js :3000 │ └──────┬───────┘ └──────────────┘ │ ┌──────▼───────┐ │ PostgreSQL │ └──────────────┘该架构图来自 deploy/compose/README.md(面向贡献者的开发者参考文档)。各服务的要点:
- zitadel-api:核心 Go 后端,监听 8080,镜像命令为
start-from-init --masterkey "${ZITADEL_MASTERKEY}",健康检查通过/app/zitadel ready子命令探测(healthcheck配置,start_period: 20s、重试 12 次)。它依赖 PostgreSQL 健康后启动,并挂载共享卷zitadel-bootstrap。 - zitadel-login:基于 Next.js 的 Hosted Login V2 前端,监听 3000,以只读方式挂载
zitadel-bootstrap卷,通过ZITADEL_SERVICE_USER_TOKEN_FILE读取 API 侧生成的 bootstrap PAT(Personal Access Token)来调用后端 API。 - postgres:唯一的强制外部依赖(PostgreSQL,README 注明生产要求 ≥ 14),使用
pg_isready做健康检查,数据持久化在postgres-data卷。 - redis(可选,profile
cache):启用缓存连接器时使用,编排中关闭了持久化(--save "" --appendonly no)。 - otel-collector(可选,profile
observability):OpenTelemetry 采集管道,默认将日志/trace 打到 stdout。
此外,zitadel-api 的环境变量中有一组值得注意的初始化配置:ZITADEL_FIRSTINSTANCE_ORG_LOGINCLIENT_PAT_PATH指向/zitadel/bootstrap/login-client.pat——首次启动时后端会创建一个名为login-client的服务账号并写入 PAT 文件,供 Login 前端使用;ZITADEL_DEFAULTINSTANCE_FEATURES_LOGINV2_REQUIRED: true则强制默认实例启用 Login V2,并把 OIDC/SAML 的默认登录 URL 指到/ui/v2/login/路径下。
API 路由规则:一个端口承载 OIDC、SAML、gRPC 与 REST
deploy/compose/README.md 中的路由规则表值得完整保留,它解释了 ZITADEL 为何不需要为 gRPC 单独配置路由:
| 优先级 | 规则 | 目标 | 中间件 |
|---|---|---|---|
| 400 | Path(/) | zitadel-login | replacepath=/ui/v2/login/ |
| 250 | PathPrefix(/ui/v2/login) | zitadel-login | — |
| 200 | PathPrefix(/api) | zitadel-api | stripprefix=/api |
| 100 | 其余全部(OIDC、SAML、gRPC、gRPC-web、API v2 REST 等) | zitadel-api(h2c) | — |
设计动机(来自同一文档的 "Why this routing model" 一节):
/api前缀只是体验别名——工具可以用https://auth.example.com/api/...这种直观形式访问 API;- OIDC/SAML 的协议规范路径(如
/.well-known/openid-configuration、/oauth/v2/...)必须保留在根路径上,因此不能被 rewrite 规则覆盖; - gRPC、gRPC-web 与 REST 共享同一个 catch-all 路由——Traefik 的
h2c后端 scheme 让所有协议透明地走 HTTP/2,无需专门的 gRPC 路由器。deploy/compose/docker-compose.yml 中的注释也明确写道:"All gRPC and Connect-RPC traffic is handled by the catch-all router below since the backend already uses h2c"。 web(HTTP)与websecure(HTTPS)两个 entrypoint 拥有完全一致的路由集合。
部署的第一大坑:外部域名必须一致
deploy/compose/README.md 用一整节强调了一条部署不变量(External Settings Invariant):
ZITADEL_EXTERNALDOMAIN、ZITADEL_EXTERNALPORT和ZITADEL_EXTERNALSECURE必须与用户实际看到的公网 URL 完全一致。如果不一致,ZITADEL 会返回 "Instance not found" 错误。这是部署中最常见的问题。
在 deploy/compose/docker-compose.yml 中可以看到这三个变量直接映射为ZITADEL_EXTERNALDOMAIN、ZITADEL_EXTERNALPORT、ZITADEL_EXTERNALSECURE环境变量,而 Login V2 的基础 URI(ZITADEL_DEFAULTINSTANCE_FEATURES_LOGINV2_BASEURI)也是由ZITADEL_PUBLIC_SCHEME、ZITADEL_DOMAIN、ZITADEL_EXTERNALPORT组合拼出来的——三者任何一处与真实入口 URL 不符,都会导致 OIDC 跳转或实例解析失败。
冷启动命令的源码视角:start-from-init 做了什么
Docker 编排中zitadel-api的启动命令是start-from-init --masterkey ...。阅读 cmd/start/start_from_init.go 可以看到这个命令的完整执行链:
- 解析 TLS 模式(
tls.ModeFromFlag)与主密钥(key.MasterKey,用于加密敏感数据,缺失会直接报错); - 初始化数据库:
initialise.InitAll完成最小启动要求(schema、默认值等,对应 cmd/initialise/init.go); - 执行 setup 步骤:
setup.Setup按 cmd/setup/ 目录中编号(01.go、02.go……)的迁移步骤写入初始事件并绑定初始投影; - 启动服务:
startZitadel加载 start 配置并拉起 HTTP/gRPC 服务。
也就是说,start-from-init= 初始化(init)+ 迁移/初始事件(setup)+ 启动(start)三合一的"冷启动",这与 deploy/compose/docker-compose.prodlike.yml 中把三步拆分为独立容器(init/setup/start)的做法正好互补:开发环境用一个命令搞定,生产环境可以分阶段控制。程序入口 main.go 非常薄——构造 cobra 根命令并执行,所有子命令(start-from-init、ready、initialise、setup、key等)都挂在 cmd/zitadel.go 下。
API 集成:用 V2 REST API 创建用户
README.md 展示了 ZITADEL V2 REST API 的典型用法——创建一个人类用户:
curl -X POST https://$ZITADEL_DOMAIN/v2/users/human \ -H "Authorization: Bearer $ACCESS_TOKEN" \ -H "Content-Type: application/json" \ -d '{ "username": "alice@example.com", "profile": { "givenName": "Alice", "familyName": "Smith" }, "email": { "email": "alice@example.com", "sendCode": {} } }'要点说明:
- 请求路径以
/v2/开头。从路由设计(上一节的优先级 100 catch-all)与 deploy/compose/README.md 的说明可确认:API v2 以 REST/JSON 形式经由 gRPC-gateway 在/v2/...路径上提供——也就是说 REST 层是 gRPC 服务的投影,而非独立实现,这与 go.mod 中grpc-ecosystem/grpc-gateway/v2依赖吻合。 - 同一 API 也可以走 connectRPC / gRPC 传输,三者共享同一套类型化定义。仓库根目录的 proto/ 目录(152 个
.proto文件,buf.yaml/buf.lock管理)是所有服务契约的来源,buf.gen.yaml 与 buf.work.yaml 定义了代码生成工作流。 - 认证使用 Bearer Access Token(通过 OIDC 等流程获取)。
OpenAPI 文档同样内嵌在服务中:openapi/handler.go 通过//go:embed把生成的 v2 OpenAPI 规范挂载到/openapi/v2/swagger前缀下,并启用 CORS 放行——部署后可以直接访问https://$ZITADEL_DOMAIN/openapi/v2/swagger查看交互文档。
功能全景与源码位置速查
按 README.md 的功能分组,结合仓库目录结构,开发者可以在以下位置找到对应实现:
认证(Authentication)
- SSO、用户名/密码、Passkeys(FIDO2/WebAuthn);MFA 覆盖 OTP、U2F、OTP Email、OTP SMS
- LDAP、企业 IdP 与社交登录;OIDC 认证、SAML 2.0、设备授权
- 机器对机器:JWT Profile、PAT、Client Credentials
- Token 交换与模拟(impersonation)、面向 OIDC/SAML 之外流程的自定义会话
- 代码位置:协议层在 internal/api/oidc/、internal/api/saml/、internal/api/idp/,WebAuthn 逻辑在 internal/webauthn/,会话与 OTP 命令在 internal/command/session_otp.go 与 internal/command/session_webauhtn.go
多租户(Multi-Tenancy)
- 带预置 IdP 模板的身份代理;可自定义的 B2B 自助注册;向第三方委托角色管理;域名发现
- 代码位置:组织与项目领域模型集中在 internal/command/org.go、internal/command/project.go 及 internal/ 下的
org、project、iam子包
集成(Integration)
- 全部资源均提供 gRPC、connectRPC 与 REST API
- Actions:webhook、自定义代码、token enrichment——对应 internal/actions/ 目录(含
object/子包与 HTTP、日志、UUID 等内置模块) - RBAC、SCIM 2.0 Server(internal/api/scim/)、审计日志对接 SOC/SIEM
自助与管理(Self-Service & Admin)
- 带邮箱/手机验证的自助注册;面向组织与项目的 Admin Console;按组织的自定义品牌
- 代码位置:控制台前端在 console/(Angular 应用),Login V2 前端在 apps/login/(Next.js 应用)
部署(Deployment)
- PostgreSQL(≥ 14)、零停机更新、高扩展能力
- 数据库相关实现见 internal/database/,事件存储与投影见 internal/eventstore/ 与 internal/query/
仓库结构与延伸阅读
├── backend/v3/ # 后端 v3 模块:api、domain、instrumentation、storage ├── cmd/ # CLI 子命令:start、setup、initialise、key、mirror、ready、tls ├── internal/ # 核心实现:command、query、eventstore、api(oidc/saml/scim/ui…) ├── proto/ # 全部 .proto 契约与 buf 工作区配置 ├── openapi/ # v2 OpenAPI 规范的内嵌服务 ├── apps/ # 前端应用:login(Next.js)、console(Angular)、docs(文档站)、api(服务) ├── packages/ # zitadel-client、zitadel-proto 等 npm 包 ├── deploy/compose/ # Docker Compose 编排与 TLS overlay ├── benchmark/ # 性能基准测试(含 postmortems) └── tests/ # functional-ui 等功能测试几个值得深入阅读的入口:
- cmd/setup/steps.yaml:setup 步骤清单,配合 cmd/setup/setup.go 可理解初始事件的写入顺序;
- deploy/compose/README.md:compose 栈的架构决策、路由逻辑与被否决的备选方案(Rejected Alternatives),是理解部署设计意图的最佳材料;
- API_DESIGN.md 与 AGENTS.md:仓库级 API 设计与协作约定;
- TERMINOLOGY.md:ZITADEL 术语表(Instance、Organization、Project 等层级概念);
- benchmark/README.md:性能基准的说明与使用方式。
安全与许可证
- 安全策略见 SECURITY.md:漏洞应通过其中描述的流程负责任地报告;重大安全或稳定性问题会发布技术公告(Technical Advisory)。
- 许可证:仓库主体为 AGPL-3.0。LICENSING.md 明确了例外目录:
proto/、apps/docs/目录为Apache License 2.0;apps/login/、packages/zitadel-client/、packages/zitadel-proto/目录为MIT License;- 社区贡献统一以 Apache 2.0 许可提交,无需额外的 CLA。
- 如果你的应用会触发 AGPL-3.0 义务且希望规避,LICENSING.md 建议咨询法律专业人士或联系官方讨论商业授权。
- 贡献:阅读 CONTRIBUTING.md 入门;采用者名单维护在 ADOPTERS.md,欢迎通过 PR 添加自己的组织。
小结
ZITADEL 的核心卖点可以概括为三句话:关系型核心 + 事件驱动内核带来完整可审计的事件流;Instance → Organization → Project 的严格多租户层级;以及 connectRPC/gRPC/REST 三通道同构的 API-first 设计。部署侧,一个 deploy/compose/docker-compose.yml 加上.env即可在几分钟内获得 Traefik + Go API + Next.js Login + PostgreSQL 的完整栈;start-from-init一个命令覆盖初始化、迁移与启动。需要特别注意的唯一硬性约束是:ZITADEL_EXTERNALDOMAIN/EXTERNALPORT/EXTERNALSECURE必须与公网 URL 严格一致,否则会出现 "Instance not found"。在此基础上,/v2/...REST 端点、/openapi/v2/swagger文档端点与/api别名路由构成了完整的集成入口,配合 proto/ 契约即可在任何支持 connectRPC 或 gRPC 的语言中接入。
【免费下载链接】zitadelZITADEL - Identity infrastructure, simplified for you.项目地址: https://gitcode.com/GitHub_Trending/zi/zitadel
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考