Skip to main content
  1. Posts/
  2. IAM and IdP Solutions/

ZITADEL: A Modern Open-Source IAM Solution

··481 words·3 mins· loading · loading · ·
Stilicho2011
Author
Stilicho2011
Writing about homelab, self-hosting, automation and open-source solutions
Table of Contents
IAM Solutions - This article is part of a series.
Part : This Article

What is ZITADEL?
#

If you enjoyed this article, you can support the author by becoming a sponsor on Boosty (link in the contacts section).

ZITADEL is an identity and access management (IAM) system, originally developed by the Swiss company CAOS AG (St. Gallen). The project is now developed under the ZITADEL Inc. brand, with CAOS AG remaining as its Swiss operating subsidiary. It provides a full set of features for user management, secure authentication, and authorization, suitable for both small projects and large enterprise solutions.

ZITADEL’s main advantage is the combination of open source, modern architecture, and cloud orientation, which makes it convenient for DevOps, SaaS platforms, and internal-tool authorization. How ZITADEL compares against Authelia, Authentik, and Keycloak - covered in a separate article.


Key features of ZITADEL
#

Support for modern protocols
#

  • OIDC (OpenID Connect)
  • OAuth 2.0
  • SAML 2.0

This makes Zitadel compatible with most modern web applications and services.

Multi-tenancy and organization management
#

  • Support for multi-tenant architecture
  • Separate spaces for organizations
  • Delegation of admin rights

Multi-factor authentication (MFA)
#

  • Email/OTP
  • TOTP (Google Authenticator)
  • SMS
  • WebAuthn (FIDO2, YubiKey, etc.)

Configured centrally or at the organization level.

API and CLI
#

  • Full REST and gRPC API
  • zitadel CLI
  • Support for DevOps infrastructure (CI/CD, GitOps)

Role-based access control
#

  • Roles at the project, application, and user level
  • Custom claims and scopes in tokens
  • RBAC/ABAC approach

Cloud and on-premises deployment
#

  • Developer-hosted (SaaS)
  • Self-hosted: Docker, Kubernetes, Podman
  • Support for PostgreSQL and CockroachDB

Advantages of ZITADEL
#

FeatureZITADELKeycloakAuth0Authelia / TinyAuth
Open Source
OIDC/SAML❌/partial
MFA❌/partial
Multi-tenantPartial
Self-service UI
API / CLIPartial

Getting started
#

Example docker compose file used in the video:

services:
    zitadel:
        restart: "always"
        container_name: zitadel
        networks:
            - zitadel
            - proxy
        image: "ghcr.io/zitadel/zitadel:v4.15.0" # don't use :latest - pin the version explicitly, check the current one at https://github.com/zitadel/zitadel/releases
        command: 'start-from-init --masterkey "${MASTERKEY_32}" --tlsMode external'
        env_file: .env
        environment:
            ZITADEL_DATABASE_POSTGRES_HOST: zitadel-db
            ZITADEL_DATABASE_POSTGRES_PORT: 5432
            ZITADEL_DATABASE_POSTGRES_DATABASE: zitadel
            ZITADEL_DATABASE_POSTGRES_USER_USERNAME: ${DB_USER}
            ZITADEL_DATABASE_POSTGRES_USER_PASSWORD: ${DB_PASSWORD}
            ZITADEL_DATABASE_POSTGRES_USER_SSL_MODE: disable
            ZITADEL_DATABASE_POSTGRES_ADMIN_USERNAME: ${DB_ADMIN_USER}
            ZITADEL_DATABASE_POSTGRES_ADMIN_PASSWORD: ${DB_ADMIN_PASSWORD}
            ZITADEL_DATABASE_POSTGRES_ADMIN_SSL_MODE: disable
            ZITADEL_FIRSTINSTANCE_ORG_HUMAN_USERNAME: ${ZITADEL_LOGIN_USER} 
            ZITADEL_FIRSTINSTANCE_ORG_HUMAN_PASSWORD: ${ZITADEL_LOGIN_PASSWORD}
            ZITADEL_FIRSTINSTANCE_ORG_HUMAN_PASSWORDCHANGEREQUIRED: false
            ZITADEL_FIRSTINSTANCE_ORG_NAME: HomeLab
            ZITADEL_PORT: 8080 #For External TLS (Also use h2c)
            ZITADEL_EXTERNALPORT: 443
            ZITADEL_EXTERNALDOMAIN: ${ZITADEL_SUBDOMAIN}.${DOMAIN_NAME} #eg. auth.DOMAIN_NAME
            ZITADEL_EXTERNALSECURE: true
        labels:
            - "traefik.enable=true"
            - "traefik.http.routers.zitadel.entrypoints=http"
            - "traefik.http.routers.zitadel.rule=Host(`${ZITADEL_SUBDOMAIN}.${DOMAIN_NAME}`)"
            - "traefik.http.middlewares.https-redirect.redirectscheme.scheme=https"
            - "traefik.http.routers.zitadel.middlewares=https-redirect"
            - "traefik.http.routers.zitadel-secure.entrypoints=https"
            - "traefik.http.routers.zitadel-secure.rule=Host(`${ZITADEL_SUBDOMAIN}.${DOMAIN_NAME}`)"
            - "traefik.http.routers.zitadel-secure.tls=true"
            - "traefik.http.routers.zitadel-secure.service=zitadel"
            - "traefik.http.services.zitadel.loadbalancer.server.scheme=h2c"
            - "traefik.http.services.zitadel.loadbalancer.passHostHeader=true"
            - "traefik.http.services.zitadel.loadbalancer.server.port=8080"
            - "traefik.docker.network=proxy"
        depends_on:
            zitadel-db:
                condition: "service_healthy"

    zitadel-db:
        restart: "always"
        container_name: zitadel-db
        image: postgres:17-alpine
        env_file: .env
        environment:
            POSTGRES_USER: ${DB_ADMIN_USER}
            POSTGRES_PASSWORD: ${DB_ADMIN_PASSWORD}
        networks:
            - zitadel
        healthcheck:
            test:
                [
                    "CMD-SHELL",
                    "pg_isready",
                    "-d",
                    "zitadel",
                    "-U",
                    "${DB_ADMIN_USER}",
                ]
            interval: "10s"
            timeout: "30s"
            retries: 5
            start_period: "20s"
        volumes:
            - ${DB_LOCATION}:/var/lib/postgresql/data

networks:
    zitadel:
        name: zitadel
    proxy:
        external: true
        name: proxy

Example environment variables file

MASTERKEY_32=GENERATE_RANDOM_KEY_LENGTH_32_ChangeMe  #Replace Master Key (tr -dc A-Za-z0-9 </dev/urandom | head -c 32)
DB_USER=Enter_DB_User_ChangeMe
DB_PASSWORD=Enter_DB_Password_ChangeMe
DB_ADMIN_USER=Enter_DB_Root_User_ChangeMe
DB_ADMIN_PASSWORD=Enter_DB_Root_Password_ChangeMe
ZITADEL_LOGIN_USER=Loginusername@Your_Domain_ChangeMe.com
ZITADEL_LOGIN_PASSWORD=Zitadel_Password_ChangeMe
ZITADEL_SUBDOMAIN=zitadel
DOMAIN_NAME=Your_Domain_ChangeMe.com
DB_LOCATION=/path/to/directory/zitadel/zitadel-db
IAM Solutions - This article is part of a series.
Part : This Article

Related