↓ Перейти к основному содержимому
  1. Posts/
  2. IAM и IdP решения./

ZITADEL - современное IAM-решение с открытым исходным кодом

Stilicho2011
Автор
Stilicho2011
Пишу о homelab, self-hosting, автоматизации и open-source решениях
Оглавление
IAM-решения - This article is part of a series.
Part : This Article

Что такое ZITADEL и почему я на него вообще посмотрел
#

Раз уж я по очереди прошелся почти по всем заметным self-hosted SSO/IAM решениям - Authentik, Authelia, Keycloak - было бы странно пропустить ZITADEL. Тем более что его довольно часто рекомендуют как “то, на что стоит смотреть, если вырос из Authelia, но Keycloak кажется монстром” - и мне стало интересно, так ли это на самом деле.

Разработала его швейцарская компания CAOS AG (Санкт-Галлен), сейчас проект живет под собственным брендом ZITADEL Inc., а CAOS AG осталась чем-то вроде местной операционной “дочки” - деталь скорее для справки, чем для практики. По сути это open-source IAM-платформа: управление пользователями, аутентификация, авторизация, причем в отличие от Authelia она не просит “принеси мне уже настроенный SSO-провайдер”, а сама и есть этот провайдер, со своей базой пользователей, MFA и панелью администратора.

Если хочется сразу понять, куда его ставить относительно остальных трех решений - у меня есть отдельное сравнение Authelia/Authentik/Keycloak/ZITADEL, там расклад по сценариям использования.

Если статья или видео оказались полезны - поддержать канал можно на бусти, ссылка в контактах.

Что внутри
#

Смысла пересказывать документацию построчно нет, но пробежаться по тому, что реально важно, стоит.

Протоколы - OIDC, OAuth 2.0 и SAML 2.0 из коробки, то есть подружить с ним современное веб-приложение почти всегда не проблема.

Multi-tenant из коробки - можно завести несколько организаций внутри одного инстанса, у каждой свои пользователи и права. Для домашней лаборатории с одним человеком за пультом это, честно говоря, избыточно - но если вы, как и я, держите ZITADEL не только для себя, а еще и для родственников или небольшой команды, разделение на организации быстро становится удобным, а не просто галочкой в фиче-листе.

MFA - Email/OTP, TOTP (тот же Google Authenticator), SMS, WebAuthn (значит и YubiKey заходит). Настраивается и глобально, и на уровне отдельной организации.

API и CLI - REST, gRPC, свой zitadel CLI. Если вы из тех, кто автоматизирует управление доступом через GitOps/CI, тут есть на чем развернуться - но для обычного homelab-сценария вы, скорее всего, этим даже не воспользуетесь, и это нормально.

RBAC/ABAC - роли на уровне проектов, приложений, пользователей, плюс кастомные claims и scopes в токенах, если нужно передавать в приложение что-то нестандартное.

Развертывание - можно взять готовый облачный SaaS от самих разработчиков, а можно поднять self-hosted через Docker, Kubernetes или Podman. База - PostgreSQL или CockroachDB, третьего варианта не предусмотрено.

Как он смотрится на фоне соседей
#

ВозможностьZITADELKeycloakAuth0Authelia / TinyAuth
Open Source✅✅❌✅
OIDC/SAML✅✅✅❌/частично
MFA✅✅✅❌/частично
Multi-tenant✅Частично✅❌
UI для self-service✅❌✅❌
API/CLI✅Частично✅❌

Если совсем грубо: там, где Authelia просто открывает или закрывает дверь перед уже настроенным приложением, ZITADEL (как и Keycloak) сам является полноценным центром выдачи личности - со своей базой пользователей, ролями и токенами. Плата за это - он тяжелее и не такой “поставил и забыл”, как Authelia.

Разворачиваем
#

Ниже - тот же docker-compose, что я использовал в видео:

services:
    zitadel:
        restart: "always"
        container_name: zitadel
        networks:
            - zitadel
            - proxy
        image: "ghcr.io/zitadel/zitadel:v4.15.0" # не используйте :latest - зафиксируйте версию явно, актуальную смотрите на 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

И рядом .env с переменными:

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

Пара моментов, на которых реально можно застрять:

  • MASTERKEY_32 - должен быть ровно 32 символа, не больше и не меньше. Генерируется командой из комментария рядом (tr -dc A-Za-z0-9 </dev/urandom | head -c 32), но если решите придумать его сами - обязательно посчитайте длину, иначе ZITADEL просто не запустится с невнятной ошибкой про мастер-ключ.
  • command: start-from-init - это команда именно для первого запуска, она создает первую организацию и первого пользователя из переменных ZITADEL_FIRSTINSTANCE_*. После того как инстанс поднялся и вы залогинились, часть гайдов рекомендует переключить команду на обычный start - я оставил start-from-init, он безопасен и для повторных запусков (просто не находит, что инициализировать, и идет дальше), но знать про существование обычного start не лишнее.
  • loadbalancer.server.scheme=h2c в лейблах Traefik - не опечатка и не “для красоты”. ZITADEL общается по gRPC, а gRPC поверх обычного HTTP/1.1 не работает - нужен HTTP/2 без TLS между Traefik и контейнером (тот самый h2c, “HTTP/2 Cleartext”). Если убрать эту строку “для простоты”, получите на входе загадочные ошибки авторизации, которые никак не намекают на настоящую причину.

Если у вас уже есть отдельный ZITADEL_LOGIN_USER/PASSWORD с реальными данными - не забудьте, что это учетка первого администратора, а не просто “тестовый пользователь для проверки” - именно под ней вы будете заходить в консоль и настраивать все остальное.

Что в итоге
#

Однозначного вывода “берите ZITADEL, а не Х” здесь не будет - слишком по-разному стоит вопрос у каждого. Если вам просто нужна форма логина перед парой веб-сервисов - ZITADEL для этого явно избыточен, возьмите Authelia или TinyAuth. А вот если хочется собственного центра идентификации с ролями, MFA и API - причем не такого тяжелого в администрировании, как Keycloak - ZITADEL стоит попробовать всерьез, а не просто прочитать про него в очередном сравнительном списке.

IAM-решения - This article is part of a series.
Part : This Article

Related

Authentik - обзор, архитектура, возможности и сравнение с Keycloak

··1013 слов·5 минут· loading · loading
Подробный обзор Authentik - open source системы для централизованной аутентификации и авторизации (IdP/SSO). Рассмотрим зачем нужны IAM-решения, архитектуру, ключевые функции и сравнение с альтернативами.

TOTP vs WebAuthn vs Passwordless - в чем разница и что выбрать

··1542 слов·8 минут· loading · loading
Подробно о TOTP, WebAuthn, passkeys и Passwordless Login: как они работают, их сильные и слабые стороны, а также рекомендации по выбору подходящей технологии для входа в свои сервисы.

Authelia в Docker - устанавливаем ForwardAuth-защиту для сервисов за Traefik

··1325 слов·7 минут· loading · loading
Пошаговая инструкция по установке и настройке Authelia в Docker - развертывание, конфигурация 2FA, интеграция с Traefik через forwardAuth и разбор основных параметров конфига.