seize-infra-doc/docs/03-zitadel-setup.md
Hedi Kalboussi 1e90a85359 Documentation initiale infra Seize — passation J7
- 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
2026-06-05 17:49:43 +00:00

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 .env ZITADEL_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 :

  1. Default Settings → en haut à droite, cliquer sur "+" à côté des avatars
  2. Page "Administrators" → "+ New"
  3. Sélectionner l'user
  4. Cocher les rôles minimum nécessaires :
    • IAM_USER_MANAGER : pour gérer les users via API
    • IAM_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 :

  1. Postgres pas prêt → attendre 30s et docker compose restart zitadel-api
  2. .env mal configuré → vérifier les variables
  3. 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 :

  1. User existe : Console → Users → Search
  2. User actif (pas désactivé)
  3. Email vérifié (sinon le login peut bloquer)
  4. MFA bien configuré (si forcé au niveau policy)
  5. Pas de lockout actif (Failed login attempts)

"Le scope urn:zitadel:iam:org:project:roles ne retourne pas les rôles"

Vérifier :

  1. Project setting "Return user roles during authentication" est coché
  2. App setting "User roles inside ID Token" est coché
  3. Auth Token Type = JWT (pas Bearer Token)
  4. OAuth2-Proxy demande bien ce scope dans OAUTH2_PROXY_SCOPE

"Service account peut pas créer de users (401/403)"

Vérifier :

  1. Service account a bien le rôle IAM_USER_MANAGER (dans Default Settings → Administrators)
  2. Clé JSON valide et non expirée
  3. Token JWT signé correctement par le script Python

📚 Liens utiles