- 6 docs racine (README, HANDOVER, ARCHITECTURE, DECISIONS, INSTALL, OPERATIONS) - 9 docs thématiques dans docs/ - 10 templates docker-compose dans configs/ - 7 scripts Python/Shell d'import Furious vers Zitadel - 2 matrices RBAC Etat infra au 5 juin 2026 : - 88 users Furious importes dans Zitadel - 8 roles RBAC crees et attribues - Intranet filtre les cartes selon role (Approche A) - 7 outils SSO operationnels
8.3 KiB
03 — Zitadel (Identity Provider)
Zitadel est le cœur de l'authentification. Tous les outils se loggent via lui.
🎯 Architecture Zitadel
⚠️ Spécificité importante : Zitadel se déploie via un docker-compose complet qui inclut :
- Le serveur API Zitadel
- L'UI de login (login v2)
- Postgres dédié (séparé du Postgres principal)
- Un Traefik dédié interne (séparé du Traefik principal !)
→ Le Traefik principal de Seize route uniquement vers le Traefik interne de Zitadel via la règle Host(sso.seizeconsulting.com).
┌───────────────────────────────────┐
│ Réseau Docker "zitadel" │
│ │
Traefik │ ┌──────────┐ ┌──────────────┐ │
principal ─────▶│ │ Traefik │───▶│ Zitadel │ │
(web) │ │ interne │ │ - API │ │
│ │ │ │ - Login UI │ │
│ └──────────┘ └──────┬───────┘ │
│ │ │
│ ┌───────▼──────┐ │
│ │ Postgres │ │
│ │ (zitadel) │ │
│ └──────────────┘ │
└───────────────────────────────────┘
📁 Structure
~/docker/zitadel/
├── docker-compose.yml # Multi-services (proxy + api + login + db)
├── .env # Configuration et secrets
└── machinekey/ # Clés des service accounts (à backup)
📄 docker-compose.yml (résumé)
⚠️ Le fichier officiel de Zitadel fait ~150 lignes. Voir configs/zitadel/docker-compose.yml.template pour la version complète.
Services inclus :
proxy(Traefik interne)zitadel-api(le moteur Zitadel)zitadel-login(UI de connexion v2)postgres(database dédiée)
Volumes critiques à backuper
volumes:
- ./postgres-data:/var/lib/postgresql/data # ⚠️ CRITIQUE
- ./machinekey:/machinekey # ⚠️ CRITIQUE
📄 .env (variables clés)
# Domaine d'accès
ZITADEL_EXTERNALDOMAIN=sso.seizeconsulting.com
ZITADEL_EXTERNALPORT=443
ZITADEL_EXTERNALSECURE=true
ZITADEL_TLS_ENABLED=false # TLS géré par Traefik externe
# Master key (⚠️ NE JAMAIS perdre, NE JAMAIS changer après init)
ZITADEL_MASTERKEY=<32-char-random-key>
# Postgres
ZITADEL_DATABASE_POSTGRES_HOST=postgres
ZITADEL_DATABASE_POSTGRES_PORT=5432
ZITADEL_DATABASE_POSTGRES_DATABASE=zitadel
ZITADEL_DATABASE_POSTGRES_USER_USERNAME=zitadel
ZITADEL_DATABASE_POSTGRES_USER_PASSWORD=<password>
ZITADEL_DATABASE_POSTGRES_ADMIN_USERNAME=postgres
ZITADEL_DATABASE_POSTGRES_ADMIN_PASSWORD=<admin-password>
# Admin initial
ZITADEL_FIRSTINSTANCE_ORG_HUMAN_USERNAME=zitadel-admin
ZITADEL_FIRSTINSTANCE_ORG_HUMAN_PASSWORD=<temp-password-to-change>
# Traefik image (pour le proxy interne)
TRAEFIK_IMAGE=traefik:v3.6.8
TRAEFIK_DASHBOARD_ENABLED=false
TRAEFIK_LOG_LEVEL=INFO
TRAEFIK_ACCESSLOG_ENABLED=false
PROXY_HTTP_PUBLISHED_PORT=80
⚠️ ZITADEL_MASTERKEY est immuable une fois l'instance initialisée. Le perdre = pouvoir reconstruire from scratch uniquement.
🚀 Premier démarrage
1. Préparer l'environnement
mkdir -p ~/docker/zitadel/{postgres-data,machinekey}
cd ~/docker/zitadel
# Copier docker-compose.yml et .env depuis les templates
2. Lancer
docker compose up -d
3. Suivre les logs (premier démarrage = 1-2 min)
docker compose logs -f zitadel-api
Attendre le message :
init step done: type=instance_setup
4. Tester l'UI
Navigateur : https://sso.seizeconsulting.com
→ Doit afficher la page de login Zitadel.
5. Se logger en admin
- Username :
zitadel-admin@zitadel.sso.seizeconsulting.com - Password : celui défini dans
.envZITADEL_FIRSTINSTANCE_ORG_HUMAN_PASSWORD
⚠️ Changer le mdp immédiatement au premier login.
⚙️ Configuration post-install via UI
1. Default Settings → Policies
Aller dans Default Settings (icône ⚙️ en haut à droite).
Password Complexity
- ☑️ Min length : 14
- ☑️ Has uppercase
- ☑️ Has lowercase
- ☑️ Has number
- ☑️ Has symbol
Lockout Policy
- ☑️ Max password attempts : 5
- ☑️ Show lockout failures (sécurité : ne pas révéler les comptes)
MFA (Force MFA pour tous)
- ☑️ Force MFA : Enabled
- ☑️ MFA Init methods : TOTP, U2F, OTP Email
2. Branding
- Logo Seize
- Couleurs :
--c-accent: #008A81 - Texte personnalisé
3. SMTP Provider (à faire quand admin M365 dispo)
Default Settings → Notifications → SMTP Provider :
Host : smtp.office365.com:587
Username : noreply@seizeconsulting.com
Password : <App Password M365>
From : noreply@seizeconsulting.com
TLS : ✅
4. Créer un Project "Infra Seize"
Menu Projects → New :
- Name :
Infra Seize - Type : Owned project
Project ID à noter : sera utilisé dans tous les scripts.
5. Créer le service account furious-import-service
Voir 06-import-furious.md.
🔐 Gestion des Administrators IAM
Pour ajouter un user/service account comme admin de toute l'instance :
- Default Settings → en haut à droite, cliquer sur "+" à côté des avatars
- Page "Administrators" → "+ New"
- Sélectionner l'user
- Cocher les rôles minimum nécessaires :
IAM_USER_MANAGER: pour gérer les users via APIIAM_ORG_MANAGER: pour gérer les organisations- ❌ Éviter
IAM_OWNER(trop puissant)
📊 Volumes critiques à backuper
| Volume | Contenu | Criticité |
|---|---|---|
postgres-data/ |
Base Zitadel (users, projects, sessions) | 🔴 CRITIQUE |
machinekey/ |
Clés des service accounts | 🔴 CRITIQUE |
.env |
Secrets de config + MASTERKEY | 🔴 CRITIQUE |
Backup recommandé
# Backup quotidien automatique (cron)
0 3 * * * docker exec zitadel-postgres-1 pg_dump -U zitadel zitadel > /home/admin/backups/zitadel-$(date +\%Y\%m\%d).sql
🐛 Troubleshooting
"Service zitadel-api ne démarre pas"
Causes possibles :
- Postgres pas prêt → attendre 30s et
docker compose restart zitadel-api .envmal configuré → vérifier les variables- Migration DB échouée →
docker compose logs zitadel-api | grep -i error
"Master key mismatch"
⚠️ Très grave : ZITADEL_MASTERKEY a changé alors que l'instance était déjà init.
Solution :
- Soit retrouver l'ancienne clé
- Soit restore depuis backup
- Soit reset complet (perte de toutes les données)
→ Ne jamais changer ZITADEL_MASTERKEY après le premier démarrage.
"Login impossible pour un user"
Vérifier :
- User existe : Console → Users → Search
- User actif (pas désactivé)
- Email vérifié (sinon le login peut bloquer)
- MFA bien configuré (si forcé au niveau policy)
- Pas de lockout actif (Failed login attempts)
"Le scope urn:zitadel:iam:org:project:roles ne retourne pas les rôles"
Vérifier :
- Project setting "Return user roles during authentication" est coché
- App setting "User roles inside ID Token" est coché
- Auth Token Type = JWT (pas Bearer Token)
- OAuth2-Proxy demande bien ce scope dans
OAUTH2_PROXY_SCOPE
"Service account peut pas créer de users (401/403)"
Vérifier :
- Service account a bien le rôle
IAM_USER_MANAGER(dans Default Settings → Administrators) - Clé JSON valide et non expirée
- Token JWT signé correctement par le script Python
📚 Liens utiles
- Documentation Zitadel : https://zitadel.com/docs
- API v2 reference : https://zitadel.com/docs/apis/resources/user_service_v2
- Self-hosting guide : https://zitadel.com/docs/self-hosting/deploy/overview
- Custom claims (Actions V2) : https://zitadel.com/docs/concepts/features/actions_v2