All apps · 0 apps
zitadel
OfficialDocker app from Nebur692's Repository
Overview
Readme
View on GitHub
The Identity Infrastructure for Developers
ZITADEL is an open-source identity and access management platform built for teams that need more than basic auth. Whether you're securing a SaaS product, building a B2B platform, or self-hosting a production IAM stack — ZITADEL gives you everything out of the box: SSO, MFA, Passkeys, OIDC, SAML, SCIM, and a battle-tested multi-tenancy model.
No vendor lock-in. No compromise on control. Just a robust, API-first identity platform you can own.
🏡 Website | 💬 Chat | 📋 Docs | 🧑💻 Blog | 📞 Contact
Why ZITADEL
We built ZITADEL to handle the hardest IAM challenges at scale — starting with multi-tenancy.
| ZITADEL | FusionAuth | Keycloak | Auth0/Okta | |
|---|---|---|---|---|
| Open-source | ✅ | ❌ | ✅ | ❌ |
| Self-hostable | ✅ | ✅ | ✅ | ❌ |
| Infrastructure-level tenants | ✅ Instances (High scale) | ✅ Tenants | 🟡 Realms (Scaling limits) | ❌ (Multi-tenant = multi-account) |
| B2B Organizations | ✅ Native & Unlimited | 🟡 via Entity Management | ✅ (Recent addition) | 🟡 (Plan/Account dependent) |
| Full audit trail | ✅ Comprehensive Event Stream* | 🟡 Audit logs | 🟡 Audit logs | 🟡 Audit logs |
| Passkeys (FIDO2) | ✅ | ✅ | ✅ | ✅ |
| Actions / webhooks | ✅ | ✅ | 🟡 via SPI | ✅ |
| API-first (gRPC + REST) | ✅ | 🟡 REST only | 🟡 REST only | 🟡 REST only |
| SaaS + self-host parity | ✅ | ✅ | ➖ N/A | ➖ N/A |
ZITADEL Cloud and self-hosted ZITADEL run the same codebase.
Key differentiators for architects:
- Relational core, event-driven soul — every mutation is written as an immutable event for a complete, API-accessible audit trail. Unlike systems that log only select activities, ZITADEL provides a comprehensive event stream that can be audited or streamed to external systems via Webhooks.
- Strict multi-tenant hierarchy — Identity System → Organizations → Projects, with isolated data and policy scoping at multiple levels
- API-first design — every resource and action is available via connectRPC, gRPC, and HTTP/JSON APIs
- Zero-downtime updates and horizontal scalability without external session stores
Get Started in 3 Minutes
ZITADEL Self-Hosted
# Docker Compose — up and running in under 3 minutes
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
Full deployment guides:
Need professional support for your self-hosted deployment? Contact us.
ZITADEL Cloud (SaaS)
Start for free at zitadel.com — no credit card required. Available in US · EU · AU · CH. Pay-as-you-go pricing.
Integrate with the V2 API
ZITADEL exposes every capability over a typed API. Here's how to create a user with the 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": {} }
}'
Explore the full API reference — including connectRPC and gRPC transports — or jump straight to quickstart examples.
Features
Authentication
- Single Sign On (SSO) · Username/Password · Passkeys (FIDO2 / WebAuthn)
- MFA: OTP, U2F, OTP Email, OTP SMS
- LDAP · Enterprise IdPs and social logins
- OpenID Connect certified · SAML 2.0 · Device authorization
- Machine-to-machine: JWT Profile, PAT, Client Credentials
- Token exchange and impersonation
- Custom sessions for flows beyond OIDC/SAML
- Hosted Login V2
Multi-Tenancy
- Identity brokering with pre-built IdP templates
- Customizable B2B onboarding with self-service for customers
- Delegated role management to third parties
- Domain discovery
Integration
- gRPC, connectRPC, and REST APIs for every resource
- Actions: webhooks, custom code, token enrichment
- RBAC · SCIM 2.0 Server
- Audit log and SOC/SIEM integration
- SDKs and example apps
Self-Service & Admin
- Self-registration with email/phone verification
- Administration Console for orgs and projects
- Custom branding per organization
Deployment
- PostgreSQL (≥ 14) · Zero-downtime updates · High scalability
Track upcoming features on our roadmap and follow our changelog for recent updates.
Showcase
Login V2
Our new, fully customizable login experience — documentation
Adopters & Ecosystem
Used in production by organizations worldwide. See the full Adopters list — and add yours by submitting a pull request.
- SDKs: All supported languages and frameworks
- Examples: Clone and use our examples
How To Contribute
ZITADEL is built in the open and welcoming to contributions of all kinds.
- 📖 Read the Contribution Guide to get started
- 💬 Join the conversation on Discord
- 🐛 Report bugs or request features via GitHub Issues
Contributors
Made with contrib.rocks.
Security
Security policy: SECURITY.md
Vulnerability Disclosure Policy — how to responsibly report security issues.
Technical Advisories are published for major issues that could impact security or stability in production.
License
AGPL-3.0 — see LICENSING.md for the full licensing policy, including Apache 2.0 and MIT exceptions for specific directories.
Requirements
Categories
Related apps
Explore more like this
Explore allDetails
ghcr.io/zitadel/zitadel:latestRuntime arguments
- Web UI
http://[IP]:[PORT:8080]/ui/console- Network
bridge- Shell
sh- Privileged
- false
- Extra Params
--restart unless-stopped
Template configuration
REQUIRED. Exactly 32 characters, used to encrypt secrets at rest. Generate once, keep it safe, never change it after first start (you will lose access to encrypted data). Example: openssl rand -base64 24 | cut -c1-32. IMPORTANT: ZITADEL has a known bug where this environment variable alone is not always read with the start-from-init command — you MUST also replace the placeholder in Post Arguments (Extra Parameters section) with this exact same value, or the container will crash-loop with 'no master key provided'.
- Target
- ZITADEL_MASTERKEY
REQUIRED. The public domain users will use to reach ZITADEL (e.g. sso.example.com), without protocol or port. Must match what your reverse proxy serves.
- Target
- ZITADEL_EXTERNALDOMAIN
- Default
- localhost
- Value
- localhost
The public-facing port your reverse proxy exposes ZITADEL on (usually 443 for HTTPS). This is NOT the container's internal port.
- Target
- ZITADEL_EXTERNALPORT
- Default
- 443
- Value
- 443
Set to true if users reach ZITADEL over HTTPS (normal case, e.g. behind Nginx Proxy Manager with a valid certificate). Set to false only for plain-HTTP test setups.
- Target
- ZITADEL_EXTERNALSECURE
- Default
- true
- Value
- true
Whether ZITADEL itself terminates TLS inside the container. Leave false if a reverse proxy (Nginx Proxy Manager, Traefik, Caddy...) handles HTTPS in front of it, which is the recommended setup.
- Target
- ZITADEL_TLS_ENABLED
- Default
- false
- Value
- false
REQUIRED. Hostname or IP of your external Postgres server/container.
- Target
- ZITADEL_DATABASE_POSTGRES_HOST
Postgres port.
- Target
- ZITADEL_DATABASE_POSTGRES_PORT
- Default
- 5432
- Value
- 5432
Database name ZITADEL will use/create.
- Target
- ZITADEL_DATABASE_POSTGRES_DATABASE
- Default
- zitadel
- Value
- zitadel
Username with rights to create the app role/database on first start. IMPORTANT: if your Postgres container was created with a custom POSTGRES_USER (instead of leaving it as the default 'postgres'), that custom user IS your superuser — put that same username here, not 'postgres'. Using the wrong one causes a password authentication failed / restart loop.
- Target
- ZITADEL_DATABASE_POSTGRES_ADMIN_USERNAME
- Default
- postgres
- Value
- postgres
Password for the admin username above.
- Target
- ZITADEL_DATABASE_POSTGRES_ADMIN_PASSWORD
SSL mode for the admin connection (disable/require/verify-ca/verify-full).
- Target
- ZITADEL_DATABASE_POSTGRES_ADMIN_SSL_MODE
- Default
- disable
- Value
- disable
Username ZITADEL uses day-to-day (created automatically on first start using the admin credentials above, unless it's the same as the admin username).
- Target
- ZITADEL_DATABASE_POSTGRES_USER_USERNAME
- Default
- zitadel
- Value
- zitadel
Password for the day-to-day database user above.
- Target
- ZITADEL_DATABASE_POSTGRES_USER_PASSWORD
SSL mode for the app connection (disable/require/verify-ca/verify-full).
- Target
- ZITADEL_DATABASE_POSTGRES_USER_SSL_MODE
- Default
- disable
- Value
- disable
Whether the default admin account must change its password on first login. Recommended: true. Only has effect on the very first start.
- Target
- ZITADEL_FIRSTINSTANCE_ORG_HUMAN_PASSWORDCHANGEREQUIRED
- Default
- true
- Value
- true
CRITICAL, do not change. On first start, ZITADEL writes here the access token that the companion zitadel-login container needs to function. Must point inside the shared bootstrap volume below.
- Target
- ZITADEL_FIRSTINSTANCE_LOGINCLIENTPATPATH
- Default
- /zitadel/bootstrap/login-client.pat
- Value
- /zitadel/bootstrap/login-client.pat
Do not change unless you know why. Internal service-account username created on first start for the login UI to authenticate as.
- Target
- ZITADEL_FIRSTINSTANCE_ORG_LOGINCLIENT_MACHINE_USERNAME
- Default
- login-client
- Value
- login-client
Display name for the internal login-client service account.
- Target
- ZITADEL_FIRSTINSTANCE_ORG_LOGINCLIENT_MACHINE_NAME
- Default
- Automatically Initialized IAM_LOGIN_CLIENT
- Value
- Automatically Initialized IAM_LOGIN_CLIENT
CRITICAL, do not leave empty: without a valid RFC3339 date here, ZITADEL silently skips writing the login-client.pat file entirely (no error logged) and zitadel-login will never work. The default is ~100 years out, effectively 'never expires' for practical purposes.
- Target
- ZITADEL_FIRSTINSTANCE_ORG_LOGINCLIENT_PAT_EXPIRATIONDATE
- Default
- 2124-01-01T00:00:00Z
- Value
- 2124-01-01T00:00:00Z
Do not change: v4 always requires the new login UI. Kept visible for transparency.
- Target
- ZITADEL_DEFAULTINSTANCE_FEATURES_LOGINV2_REQUIRED
- Default
- true
- Value
- true
REQUIRED. Full public URL of the login pages, e.g. https://sso.example.com/ui/v2/login/ — must match your External Domain/Port/Secure settings above, with the trailing slash.
- Target
- ZITADEL_DEFAULTINSTANCE_FEATURES_LOGINV2_BASEURI
REQUIRED. e.g. https://sso.example.com/ui/v2/login/login?authRequest=
- Target
- ZITADEL_OIDC_DEFAULTLOGINURLV2
REQUIRED. e.g. https://sso.example.com/ui/v2/login/logout?post_logout_redirect=
- Target
- ZITADEL_OIDC_DEFAULTLOGOUTURLV2
REQUIRED if you plan to use SAML (e.g. Zabbix). e.g. https://sso.example.com/ui/v2/login/login?samlRequest=
- Target
- ZITADEL_SAML_DEFAULTLOGINURLV2
Shared with the zitadel-login container (mounted read-only there) so it can read the login-client.pat token written here on first start. Both templates must point at the exact same host path. IMPORTANT: ZITADEL runs internally as UID 1000. If Unraid auto-creates this folder on first start, it may end up owned by root/nobody without write access for UID 1000, causing the token to silently fail to write with no error in the log. If the folder stays empty after 'setup completed', run: chown -R 1000:1000 this path on the Unraid host, then wipe the Postgres database (the first-instance bootstrap only runs once per empty database) and restart.
- Target
- /zitadel/bootstrap
- Default
- /mnt/user/appdata/zitadel/bootstrap
- Value
- /mnt/user/appdata/zitadel/bootstrap
Internal port. Put your reverse proxy in front of this — do not expose it directly to the internet without TLS.
- Target
- 8080
- Default
- 8080
- Value
- 8080
ZITADEL blocks Actions V2 Target endpoints on private IP ranges by default (SSRF protection) — this INCLUDES 192.168.0.0/16 by default, which breaks creating a Target pointing at any container on a typical home LAN (fails with 'Errors.Target.DeniedURL'). This default value is the stock deny list with 192.168.0.0/16 removed, so LAN targets work while keeping protection against loopback, link-local, and cloud metadata endpoints (169.254.169.254) intact. Only widen this further if you understand the SSRF risk of doing so.
- Target
- ZITADEL_HTTPCLIENT_DENYLIST
- Default
- localhost,0.0.0.0/8,10.0.0.0/8,100.64.0.0/10,127.0.0.0/8,169.254.0.0/16,172.16.0.0/12,198.18.0.0/15,::/128,::1/128,fc00::/7,fe80::/10
- Value
- localhost,0.0.0.0/8,10.0.0.0/8,100.64.0.0/10,127.0.0.0/8,169.254.0.0/16,172.16.0.0/12,198.18.0.0/15,::/128,::1/128,fc00::/7,fe80::/10
