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

282 lines
8.3 KiB
Markdown

# 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
```yaml
volumes:
- ./postgres-data:/var/lib/postgresql/data # ⚠️ CRITIQUE
- ./machinekey:/machinekey # ⚠️ CRITIQUE
```
---
## 📄 .env (variables clés)
```env
# 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
```bash
mkdir -p ~/docker/zitadel/{postgres-data,machinekey}
cd ~/docker/zitadel
# Copier docker-compose.yml et .env depuis les templates
```
### 2. Lancer
```bash
docker compose up -d
```
### 3. Suivre les logs (premier démarrage = 1-2 min)
```bash
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](./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é
```bash
# 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
- 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