Pourquoi choisir ZITADEL plutôt qu'Authentik ou Keycloak ?
ZITADEL occupe un créneau précis parmi les plateformes d'authentification open source. Contrairement à Authelia (proxy d'authentification sans gestion d'utilisateurs propre) ou Authentik (IdP full-stack riche en fonctionnalités), il vise les équipes de développement qui veulent un IAM de niveau entreprise dès le départ : multi-tenant natif, APIs gRPC + REST complètes, provider Terraform officiel (zitadel/zitadel sur le registre Terraform).
Sur la mémoire, restez prudent. La documentation d'exploitation indique que ZITADEL lui-même demande environ 512 Mo de RAM et moins d'un cœur CPU, base de données non comprise, avec des pics CPU au hachage des mots de passe. L'ancienne version de cet article annonçait « moins de 100 Mo » : ce chiffre ne figure pas dans la documentation, ne dimensionnez pas votre VPS dessus. Le comparatif de ressources avec Keycloak n'est pas chiffré ici faute de mesure sourcée.
Prérequis chiffrés
- VPS : 2 vCPU et 2 Go de RAM (le guide Docker Compose amont demande au moins 2 Go), Ubuntu 24.04. Prévoyez davantage dès que la base grossit : l'amont compte environ 4 Go de RAM par cœur de base de données.
- Docker : Docker Engine 24 ou plus avec Compose v2 ; l'ancien binaire
docker-compose(v1) n'est pas pris en charge. - PostgreSQL : les versions 14 à 18 sont prises en charge. Le template ServOrbit déploie PostgreSQL 16.
- Ports : ZITADEL écoute en interne sur
8080. Seul443doit être public (plus80si vous laissez Let's Encrypt émettre le certificat). Le template lie8080à127.0.0.1et laisse nginx servir l'extérieur. - Domaine : un nom ou sous-domaine pointant vers l'IP du VPS, par exemple
auth.votre-domaine.com, en HTTPS. - Masterkey :
ZITADEL_MASTERKEYdoit faire exactement 32 caractères et ne peut plus changer après l'initialisation sans perdre l'accès aux données chiffrées. Le template la génère ; sauvegardez-la hors du VPS.
Installer ZITADEL depuis le Marketplace
Installation en 3 étapes
Créer le VPS
Depuis votre espace client ServOrbit, choisissez la gamme VPS et cliquez sur Configurer. Dans le champ Application, sélectionnez ZITADEL. Saisissez votre domaine (ex.
auth.votre-domaine.com).Si vous n'avez pas de domaine, le sous-domaine gratuit ServOrbit est disponible immédiatement, HTTPS inclus.
Démarrage automatique
Le script d'installation génère le
MASTERKEY, le mot de passe PostgreSQL et le mot de passe admin, puis lance PostgreSQL 16 et ZITADEL via Docker Compose. Durée habituelle : 2 à 4 minutes.Accéder à la console
Une fois l'installation terminée, vos identifiants sont affichés dans l'espace client.
- URL :https://<votre-domaine>/ui/console
- Identifiant :admin. Si la page le refuse, essayezadmin@zitadel.<votre-domaine>: ZITADEL compose les noms de connexion sous la forme [email protected], comme dans l'exemple[email protected]de l'amont.
- Mot de passe : celui qui a été généréConnectez-vous et changez-le immédiatement.
Ce que déploie le template
Le template est un fichier Docker Compose de deux services : db (PostgreSQL 16) et zitadel, lancé avec start-from-init --tlsMode disabled --masterkeyFromEnv. Le TLS est donc terminé par nginx, pas par ZITADEL. L'image suivie est le tag stable de ghcr.io/zitadel/zitadel, ce qui signifie que la version réellement démarrée dépend du jour où l'image a été tirée : contrôlez-la avec docker compose images (voir la section sur les mises à jour).
Le domaine est transmis à ZITADEL_EXTERNALDOMAIN, avec ZITADEL_EXTERNALPORT=443 et ZITADEL_EXTERNALSECURE=true. Le template considère le domaine comme figé au premier démarrage : choisissez le bon dès le départ.
Domaine externe, TLS et reverse proxy
- Trois valeurs à aligner —
ZITADEL_EXTERNALDOMAIN,ZITADEL_EXTERNALPORTetZITADEL_EXTERNALSECUREdoivent décrire l'URL publique réelle. ZITADEL ne sert que les requêtes envoyées au protocole, à l'hôte et au port attendus ; sinon vous obtenez « Instance not found ». - Changer de domaine — l'amont documente que ces options peuvent être modifiées à tout moment, à condition de rejouer la phase de setup. Ce n'est donc pas impossible comme l'affirmait l'ancienne version, mais ce n'est pas un geste anodin : toute application cliente référence l'ancienne URL.
- Hôte conservé — le reverse proxy doit transmettre l'en-tête
Hostd'origine etX-Forwarded-Proto: https. L'exemple nginx amont termine le TLS puis parle à ZITADEL en HTTP/2 non chiffré (h2c) avecgrpc_pass. - HTTP/2 de bout en bout — la console exige HTTP/2 jusqu'à ZITADEL. Les proxys testés par l'amont sont Traefik v3, NGINX 1.x stable, Caddy v2 et Apache httpd 2.4.
- CDN ou WAF devant — la documentation précise qu'un proxy, un WAF ou un CDN placé devant ZITADEL doit lui aussi supporter HTTP/2. Testez la console après toute bascule de DNS vers un mode proxifié.
Créer votre première application OIDC
Une fois connecté à la console ZITADEL :
1. Allez dans Projects puis Create
2. Nommez votre projet (ex. My App)
3. Cliquez sur Add Application
4. Choisissez le type : Web (applications serveur), Native (mobile/desktop) ou API (machine-to-machine)
5. Pour une app Web, choisissez PKCE (recommandé) et renseignez vos Redirect URIs
ZITADEL génère le Client ID. Notez le discovery endpoint OIDC : https://<votre-domaine>/.well-known/openid-configuration.
Intégrer ZITADEL avec vos applications self-hosted
Toute application qui parle OIDC peut s'appuyer sur ZITADEL : il suffit du Client ID, du secret éventuel et du discovery endpoint. Exemples courants :
- Gitea : Administration du site, Authentification, ajouter une source OAuth2 de type OpenID Connect, puis saisir Client ID, secret et discovery endpoint
- Grafana : section
[auth.generic_oauth]degrafana.iniavec les URL d'autorisation, de jeton et d'informations utilisateur de ZITADEL - Nextcloud : application
Social LoginouOpenID Connect user backend - Toute autre application OIDC : renseignez le discovery endpoint, le Client ID et les Redirect URIs déclarées dans le projet ; consultez la documentation de l'application pour les réglages exacts
Gérer le multi-tenant : organisations et projets
ZITADEL repose sur un modèle multi-tenant natif : vous créez plusieurs Organisations (par exemple une par client de votre SaaS), chacune avec ses utilisateurs et ses politiques de connexion. Chaque organisation peut avoir ses Projets et Rôles.
Attention : les rôles ne sont pas inscrits dans les jetons automatiquement, contrairement à ce qu'affirmait l'ancienne version. Il faut cocher Assert Roles on Authentication dans le projet pour les obtenir via userinfo, ou User Roles Inside ID Token dans l'application, et demander le scope de rôles urn:zitadel:iam:org:project:{projectId}:roles. Ajoutez aussi urn:zitadel:iam:org:project:id:{projectId}:aud si vous obtenez « Invalid audience ».
Conseil : activer les passkeys dès le départ
Dans les paramètres de l'instance, activez l'authentification Passkey/WebAuthn. Vos utilisateurs s'authentifient sans mot de passe depuis leur navigateur.
Découverte de domaine : ce qui doit fonctionner
La découverte de domaine (Domain Discovery) route un utilisateur vers la bonne organisation d'après le domaine de son adresse e-mail. Dans le scénario décrit par l'amont, un utilisateur de [email protected] est redirigé vers le fournisseur d'identité de son entreprise, tandis qu'un utilisateur de [email protected] voit une page de connexion par mot de passe et MFA, et qu'un domaine inconnu tombe dans l'organisation par défaut.
Les conditions décrites dans le guide amont sont les suivantes :
- Instance — dans Login Behavior and Security, l'option « Domain discovery allowed » est activée
- Organisation par défaut — elle reçoit tous les utilisateurs sans correspondance
- Domaine vérifié — chaque domaine est vérifié dans les Organization Domains de l'organisation, par enregistrement DNS TXT ou défi HTTP ; gardez l'enregistrement DNS, car ZITADEL revérifie périodiquement
- Politique de connexion de l'organisation — « External IDP allowed » activé, et pour une organisation purement fédérée « Username Password allowed » désactivé
- Fournisseur d'identité — configuré et rattaché à cette organisation ; avec un seul fournisseur la redirection est automatique, avec plusieurs l'utilisateur choisit
- Connexion par e-mail — le nom de connexion saisi doit pouvoir être une adresse e-mail dont le domaine correspond
Limites connues : le ticket zitadel/zitadel n°10662
Sur ZITADEL v4.1.2 auto-hébergé, la découverte de domaine ne fonctionne pas pour certains déploiements malgré des organisations au domaine vérifié et un fournisseur d'identité configuré. Le ticket n°10662 (« Domain Discovery doesn't work ») a été ouvert en septembre 2025 et est toujours ouvert à la rédaction de cet article. Le tableau sépare ce que l'équipe ou la documentation établit de ce que des utilisateurs rapportent.
Ticket n°10662 : confirmé et rapporté
Faites défiler le tableau
| Point | Confirmé (équipe ou documentation) | Rapporté par des utilisateurs, non confirmé |
|---|---|---|
| Symptôme | Le ticket est ouvert, classé priorité moyenne en octobre 2026, avec les étiquettes area/console, area/loginV1 et ng-v4-legacy | Message « User not found in the system » pour une adresse au domaine vérifié, sur v4.1.2, identique sous OKD et sous Docker |
| Correctif annoncé | Un mainteneur a indiqué en octobre 2025 que la PR n°10729 le corrigeait, puis le ticket a été rouvert | Le défaut persiste sur v4.3.1, puis en Login V1 sur v4.5.0, v4.6.3, v4.7.0 et v4.11.0 |
| Cause | Aucune cause n'est établie publiquement | Aucune hypothèse vérifiée |
| Périmètre | Des sous-tickets existent (état du 16 juillet 2026 : un terminé, deux en cours, un non démarré), rattachés au chantier parent n°12337 | Reproduit en Login V2 (rapport initial) puis en Login V1 ; le cas de plusieurs domaines dans une même organisation reste sans réponse |
| Console | Le 27 juillet 2026, une contributrice indique que la Console doit être dépréciée dans les 12 mois et qu'aucun correctif n'est priorisé d'ici là ; le ticket est maintenu ouvert | Rien à signaler |
| Contournement | Aucun contournement n'est documenté dans le fil | Aucun n'est éprouvé par les participants |
En pratique : ne bâtissez pas une architecture SSO d'entreprise sur la seule découverte de domaine tant que ce ticket est ouvert. Prévoyez un second chemin (lien de connexion par fournisseur, voir plus bas) et testez le routage avec un utilisateur réel avant la mise en production. Le 27 octobre 2026, un membre de l'équipe a demandé la vérification de l'état du ticket : suivez-le plutôt que cet article pour son issue.
Dépannage de la connexion SSO et du domaine vérifié
Diagnostic en 5 étapes
Contrôler l'instance
Dans les paramètres de l'instance, section Login Behavior and Security, vérifiez que « Domain discovery allowed » est bien activé. Sans lui, aucune règle d'organisation n'est consultée.
Contrôler le domaine
Dans l'organisation visée, ouvrez les Organization Domains : le domaine doit être au statut vérifié. Si la vérification échoue, rétablissez l'enregistrement TXT ou le défi HTTP demandé, et ne supprimez jamais l'enregistrement après coup.
Contrôler la politique de connexion
Dans la même organisation, « External IDP allowed » doit être activé et le fournisseur d'identité actif. Si « Username Password allowed » reste activé, l'utilisateur peut atterrir sur la saisie du mot de passe au lieu d'être redirigé, symptôme décrit dans le ticket.
Tester le nom de connexion
En navigation privée, saisissez une adresse complète dont le domaine est exactement celui qui est vérifié. Une faute de domaine, un sous-domaine ou un utilisateur déjà existant dans une autre organisation changent le résultat.
Court-circuiter la découverte
Si tout est conforme et que « User not found in the system » persiste, vous êtes probablement dans le cas du ticket n°10662. Le scope
urn:zitadel:iam:org:idp:id:<idp_id>redirige directement l'utilisateur vers le fournisseur d'identité choisi : la documentation le décrit, mais il n'a pas été éprouvé sur ce défaut.
- « User not found in the system » : appliquez les cinq étapes ci-dessus ; si elles sont conformes, c'est le défaut du ticket
- « Instance not found » (404) : le couple hôte, port et protocole reçu ne correspond pas à
ZITADEL_EXTERNALDOMAIN,ZITADEL_EXTERNALPORTetZITADEL_EXTERNALSECURE; vérifiez que nginx conserve l'en-têteHost - Console blanche ou appels API en échec derrière un proxy ou un CDN : contrôlez HTTP/2 de bout en bout
- Identifiant
adminrefusé : essayez la formeadmin@zitadel.<votre-domaine>indiquée plus haut - Vérification de domaine qui échoue : le guide amont précise que le défi ACME de vérification peut être désactivé dans les réglages par défaut, mais ne le faites qu'en connaissance de cause
Mises à jour et sécurité
- Version courante — à la rédaction, la dernière version stable publiée est la v4.20.0, parue en octobre 2026 ; lisez les notes de version avant chaque montée
- Avis GHSA-jh92-5mrj-p2w2 — prise de contrôle de compte par des identifiants de session prévisibles dans le Login V2 (sévérité haute, aucun identifiant CVE indiqué). Versions 4.0.0 à 4.19.1 touchées, correctif en 4.19.2 ; un déploiement qui n'utilise que le Login V1 n'est pas concerné
- Secret de cookie de session — le correctif demande
ZITADEL_SESSION_COOKIE_SECRET(32 caractères au moins, identique sur tous les réplicas) ; les utilisateurs doivent se reconnecter après la montée - Branche 3.x — elle est arrivée en fin de vie le 31 août 2026 et ne recevra pas de correctif : migrez vers une 4.x récente
Avant de mettre à jour
Sauvegardez la base avec pg_dump et la masterkey, puis lancez docker compose pull suivi de docker compose up -d depuis le dossier du Compose. Comme le template suit le tag stable, vérifiez ensuite la version démarrée avec docker compose images.
Installer ZITADEL via le Marketplace ServOrbit
Vous pouvez installer ZITADEL directement depuis le [Marketplace ServOrbit](/marketplace/security/zitadel) : VPS préconfiguré avec Docker Compose, nginx, HTTPS et secrets générés automatiquement. Le template est fourni comme point de départ, sans prise en charge de votre configuration d'identité.