What Zitadel Does
Zitadel handles the complete identity lifecycle:
- Authentication: Username/password, social login (Google, GitHub, Apple, etc.), passwordless (FIDO2/passkeys), and magic links
- Multi-Factor Auth: TOTP, WebAuthn, SMS OTP, and email OTP as second factors
- Single Sign-On: OIDC and SAML federation for enterprise SSO
- Multi-Tenancy: First-class organization support with per-org settings, branding, and policies
- User Management: Self-service registration, password reset, email/phone verification, and admin console
- Authorization: Role-based access control (RBAC) with project-level and organization-level roles
- SCIM Provisioning: Automated user provisioning from identity providers
Architecture
┌──────────────┐ ┌──────────────┐ ┌──────────────┐
│ Your App │────▶│ Zitadel │────▶│ CockroachDB │
│ (OIDC SDK) │ │ Server (Go) │ │ or Postgres │
└──────────────┘ └──────┬───────┘ └──────────────┘
│
┌──────┴───────┐
│ Console UI │
│ (Angular) │
└──────────────┘Zitadel uses event sourcing internally, meaning every change is stored as an immutable event. This provides complete audit trails and enables powerful projections for different read models.
Self-Hosting
Docker Compose
services:
zitadel:
image: ghcr.io/zitadel/zitadel:latest
command: start-from-init --masterkey "MasterkeyNeedsToHave32Characters" --tlsMode disabled
ports:
- "8080:8080"
environment:
ZITADEL_DATABASE_POSTGRES_HOST: db
ZITADEL_DATABASE_POSTGRES_PORT: 5432
ZITADEL_DATABASE_POSTGRES_DATABASE: zitadel
ZITADEL_DATABASE_POSTGRES_USER_USERNAME: zitadel
ZITADEL_DATABASE_POSTGRES_USER_PASSWORD: zitadel
ZITADEL_DATABASE_POSTGRES_ADMIN_USERNAME: postgres
ZITADEL_DATABASE_POSTGRES_ADMIN_PASSWORD: postgres
ZITADEL_EXTERNALDOMAIN: localhost
ZITADEL_EXTERNALSECURE: "false"
depends_on:
db:
condition: service_healthy
db:
image: postgres:16-alpine
environment:
POSTGRES_USER: postgres
POSTGRES_PASSWORD: postgres
POSTGRES_DB: zitadel
healthcheck:
test: ["CMD-SHELL", "pg_isready -U postgres"]
interval: 5s
timeout: 5s
retries: 5
volumes:
- pg-data:/var/lib/postgresql/data
volumes:
pg-data:Integration Example
Next.js with OIDC
// lib/zitadel.ts
import { createZitadelAuth } from '@zitadel/react';
export const zitadel = createZitadelAuth({
authority: 'http://localhost:8080',
client_id: 'your-client-id',
redirect_uri: 'http://localhost:3000/callback',
post_logout_redirect_uri: 'http://localhost:3000',
scope: 'openid profile email',
});API (gRPC + REST)
# Create a user via REST API
curl -X POST http://localhost:8080/management/v1/users/human
-H "Authorization: Bearer $TOKEN"
-H "Content-Type: application/json"
-d '{
"userName": "john@example.com",
"profile": {
"firstName": "John",
"lastName": "Doe"
},
"email": {
"email": "john@example.com",
"isEmailVerified": true
},
"password": "InitialPassword1!"
}'Key Differentiators
Event Sourcing
Every operation in Zitadel creates an event:
- Complete audit trail of all changes
- Time-travel queries (what did the user look like at time X?)
- Event-driven projections for custom read models
- No data loss from update operations
Actions (Custom Code)
Run custom code at authentication events:
// Pre-creation action
function preCreation(ctx, api) {
// Validate email domain
if (!ctx.v1.user.email.endsWith('@company.com')) {
api.setHumanEmailVerified(false);
}
// Set metadata
api.metadata.push({ key: 'department', value: 'engineering' });
}Zitadel vs Alternatives
| Feature | Zitadel | Keycloak | Auth0 | Logto |
|---|---|---|---|---|
| Open Source | Yes (AGPL-3.0) | Yes (Apache-2.0) | No | Yes (MPL-2.0) |
| Multi-tenancy | Native | Realms | Organizations | Organizations |
| Passkeys | Yes | Yes | Yes | Yes |
| SAML + OIDC | Both | Both | Both | OIDC only |
| SCIM | Yes | Community | Enterprise | No |
| Event sourcing | Yes | No | No | No |
| Language | Go | Java | N/A | TypeScript |
| Resource usage | Low | High (JVM) | N/A | Low |
FAQ
Q: Zitadel or Keycloak? A: Zitadel is lighter (Go vs Java), has native multi-tenancy, and uses an event-sourced architecture. Keycloak has a more mature ecosystem, a larger community, and better LDAP/AD integration. Pick Zitadel for new projects; enterprises with existing Keycloak ecosystems can stay on Keycloak.
Q: Does it support social login? A: Yes — 20+ social identity providers including Google, GitHub, GitLab, Apple, Microsoft, Facebook, and more. Generic OIDC and SAML providers are also supported.
Q: How does it handle millions of users? A: Zitadel uses CockroachDB or PostgreSQL for storage; the event-sourced architecture is naturally horizontally scalable. The Cloud version handles millions of users. For self-hosting at scale, CockroachDB clustering is recommended.