Cybersécurité

Zitadel passkeys et MFA : tutoriel sécurité 2026

11 دقائق للقراءة

Les passkeys (WebAuthn) sont la meilleure méthode d’authentification 2026 : pas de mot de passe à mémoriser, immunisé phishing, support natif iOS/Android/macOS/Windows. Zitadel les supporte nativement. Voici le tutoriel.

Voir notre guide Zitadel.

Pourquoi passkeys

  • Phishing-proof : ne fonctionne que sur le domaine légitime
  • Pas de mot de passe : utilisateur authentifie via Touch ID, Face ID, Windows Hello, security key
  • Sync iCloud / Google Password Manager : pratique sur tous les devices
  • Standard FIDO2 : universel

Activer passkeys dans Zitadel

  1. Console Zitadel → Login Behavior → Login Settings
  2. Force MFA : Optional ou Force passkeys
  3. Allowed second factors : passkey, U2F, OTP
  4. Multi-factor login : Allow passkey-only login
  5. Save

Enregistrer un passkey utilisateur

  1. Login utilisateur → Profile → Multi-Factor Authentication
  2. Add Passkey
  3. Browser invite à utiliser Touch ID / Windows Hello / clé physique
  4. Le passkey est enregistré, prêt à être utilisé en login futur

MFA TOTP en backup

Toujours laisser TOTP comme backup au cas où l’utilisateur perd son device passkey. Aegis, Authy, Bitwarden Authenticator. Codes de récupération générés à l’enregistrement TOTP.

Force MFA pour rôles sensibles

Settings → Security Policy → Force MFA pour : Admins, Owners, et toute role à privilège. Reste optionnel pour utilisateurs basiques selon UX.

SMS OTP attention

SMS OTP est faible (SIM swapping possible). À éviter pour comptes sensibles. Si nécessaire (utilisateurs sans smartphone moderne), au moins coupler avec rate limiting.

À lire ensuite

Vous cherchez un hébergement web sérieux et abordable ?

Hostinger offre des serveurs avec installation WordPress en un clic et un panel simple. Notre équipe l’utilise au quotidien.

Découvrir Hostinger →

Lien d affiliation. Si vous achetez via ce lien, le blog reçoit une petite commission sans surcoût pour vous.

Pourquoi Zitadel et passkeys en 2026 sur un projet ouest-africain

Zitadel est un Identity Provider open-source ecrit en Go, edite par la societe suisse Zitadel, sous licence Apache 2.0. Il offre OIDC, OAuth2, SAML2, gestion d organisations multi-tenants et support natif des passkeys (WebAuthn FIDO2). Pour un freelance senegalais qui livre une plateforme SaaS B2B, Zitadel remplace avantageusement Auth0 (cher en USD) et Keycloak (lourd en operation), avec un modele cloud ou self-hosted au choix.

Les passkeys eliminent le mot de passe. L utilisateur s authentifie avec son empreinte (Touch ID, Face ID, Windows Hello) ou une cle physique YubiKey. Pour un public ouest-africain qui subit le phishing par SMS et la reutilisation massive de mots de passe, le passage aux passkeys reduit drastiquement le risque de compromission de comptes.

Etape 1 : creer un compte Zitadel Cloud ou installer self-hosted

Le plus rapide : creer un compte gratuit sur zitadel.cloud. Le tier free supporte 10 000 authentications par mois, suffisant pour la plupart des projets early-stage. Pour le self-hosted, la stack docker compose officielle deploie Zitadel en environ 3 minutes sur un VPS Hostinger 4 GB.

git clone https://github.com/zitadel/zitadel.git
cd zitadel
docker compose -f docker-compose.yaml up -d
# Acces sur http://localhost:8080
# Compte initial : zitadel-admin@zitadel.localhost
# Mot de passe imprime dans les logs : docker compose logs zitadel

Sortie de référence : ouvrez http://localhost:8080/ui/console, vous arrivez sur la page de login Zitadel. Si vous obtenez un 502, le conteneur cockroachdb n a pas demarre proprement. Inspectez les logs avec docker compose logs cockroach.

Etape 2 : creer une organisation et un projet

Apres connexion en tant qu admin, naviguez vers Organizations – Create. Nom : Votre-Entreprise. Une organisation regroupe utilisateurs, projets et roles. Dans Projects – Create, ajoutez le projet Mon-App-SaaS. Puis Applications – Create, choisissez User Agent (pour Single Page App React/Vue) ou Web (pour Next.js avec backend).

Dans le wizard, choisissez OIDC, type Code (avec PKCE), redirect URI https://app.votredomaine.com/auth/callback. Apres creation, copiez le Client ID. Résultat type : un Client ID au format 287614…@mon-app-saas qui sera utilise dans la config front-end. Pas de Client Secret pour les SPA, c est attendu.

Etape 3 : activer les passkeys au niveau de l organisation

Allez dans Organization – Settings – Login Behavior and Security. Activez Passwordless. Choisissez Allowed pour autoriser passkey en complement, ou Required pour rendre obligatoire. Pour une migration douce, commencez par Allowed, communiquez vers les utilisateurs, basculez vers Required apres 90 jours d adoption.

Dans la meme page, activez aussi MFA Force pour exiger un second facteur. Avec passkey, le passkey lui-meme satisfait l exigence MFA car il combine possession (l appareil) et inherence (la biometrie). Ce que vous devez voir : la prochaine connexion utilisateur propose Set up Passkey apres l email.

Etape 4 : integrer le SDK Zitadel cote front-end

Pour une app React, installez la librairie officielle ou utilisez oidc-client-ts qui est generique. La config OIDC pointe vers https://votre-instance.zitadel.cloud comme issuer.

npm install oidc-client-ts
import { UserManager } from 'oidc-client-ts';

const userManager = new UserManager({
  authority: 'https://votre-instance.zitadel.cloud',
  client_id: '287614...@mon-app-saas',
  redirect_uri: 'https://app.votredomaine.com/auth/callback',
  response_type: 'code',
  scope: 'openid profile email offline_access',
});

// Au clic sur le bouton Connexion
await userManager.signinRedirect();

Ce que vous devez voir : le clic redirige vers la page de login Zitadel, qui propose email puis passkey. Apres scan biometrique reussi, retour sur https://app.votredomaine.com/auth/callback avec un code, echange code contre tokens, redirection vers l app authentifiee.

Etape 5 : enregistrer un passkey pour un utilisateur de test

Connectez-vous avec un compte de test sur https://votre-instance.zitadel.cloud/ui/login. Apres login email plus mot de passe initial, allez dans Profile – Authentication Methods – Add Passwordless. Le navigateur demande l autorisation WebAuthn. Sur Android Chrome, choisir Cle de cet appareil utilisera l empreinte digitale ; sur Windows, Windows Hello propose le PIN ou la webcam ; sur iOS Safari, Face ID via le KeyChain iCloud (passkey synchronisee multi-appareils Apple).

Sortie de référence : la liste Authentication Methods affiche un passkey nomme par defaut (ex : Pixel 8, MacBook Pro). Renommez-le pour identifier l appareil. La prochaine connexion peut se faire sans mot de passe : email puis passkey direct.

Etape 6 : tester le flow complet et capter les tokens

Apres signinRedirectCallback() cote app, userManager.getUser() retourne un objet User contenant access_token (JWT), id_token (JWT signe avec claims), expires_at, profile (sub, email, name). Decodage du JWT via jwt.io pour verifier la presence du claim amr (Authentication Method Reference) qui contient pwd, mfa, ou hwk pour hardware key.

Pour validation cote API : la valeur amr permet d enforcer une politique. Par exemple, refuser les operations sensibles (changement IBAN, suppression compte) si amr ne contient pas hwk ou mfa. Cette granularite n est pas accessible avec une auth password-only.

Etape 7 : verifier les tokens cote backend Node ou Go

Cote backend, validez les JWT avec la JWKS de Zitadel. En Node Express avec express-jwt et jwks-rsa :

import { expressjwt } from 'express-jwt';
import jwksRsa from 'jwks-rsa';

app.use('/api', expressjwt({
  secret: jwksRsa.expressJwtSecret({
    jwksUri: 'https://votre-instance.zitadel.cloud/oauth/v2/keys'
  }),
  audience: '287614...@mon-app-saas',
  issuer: 'https://votre-instance.zitadel.cloud',
  algorithms: ['RS256']
}));

Résultat attendu : un appel curl https://api.votredomaine.com/api/me avec le bearer token retourne 200 et le contenu protege. Sans token ou token expire, 401 Unauthorized. Si signature invalide, le middleware loggue UnauthorizedError: invalid signature.

Etape 8 : configurer les roles et permissions

Zitadel supporte les roles au niveau projet. Dans Project – Roles – Create, definissez admin, manager, customer. Assignez aux utilisateurs via Users – Authorizations – Add. Le claim urn:zitadel:iam:org:project:roles est inclus dans le ID Token. Cote front, lisez-le pour conditionner l UI ; cote back, lisez-le pour conditionner les permissions API.

Pour un SaaS B2B avec organisations clientes, activez le mode multi-organisation. Chaque client devient une org avec ses propres utilisateurs. Le user qui appartient a 3 orgs choisit son contexte au login. Cette architecture evite la pollution croisee des donnees.

Etape 9 : sauvegarde, monitoring et conclusion

En self-hosted, sauvegardez quotidiennement le volume cockroachdb avec un timer systemd. Ouvrez les metriques Prometheus exposees par Zitadel sur le port 8080 endpoint /debug/metrics et connectez-y Prometheus pour surveiller le taux d auth, les erreurs et la latence. Une chute du taux d auth doit declencher une alerte.

Pour completer la chaine : voyez notre guide Prometheus node-exporter VPS pour exposer les metriques systeme du serveur Zitadel, et notre comparatif Uptime Kuma vs Healthchecks vs Statping vs Gatus pour configurer une sonde HTTP vers /debug/healthz qui alerte en cas de panne.

Etape 10 : strategie de migration depuis Auth0 ou Keycloak

Pour un projet existant sur Auth0, la migration vers Zitadel suit un pattern progressif. D abord, exporter la liste des utilisateurs Auth0 via le Management API endpoint /api/v2/users avec pagination 50 par page. Le dump produit un JSON Lines contenant email, sub, metadata, mais sans le hash du mot de passe en clair (Auth0 ne l expose qu apres demande commerciale).

Strategie 1 : import des emails sans mot de passe et reset force au premier login. Strategie 2 : passerelle SAML temporaire ou Zitadel federe vers Auth0 le temps de la transition douce. Strategie 3 : double-write pendant 30 jours puis cutover. La premiere strategie est la plus simple et acceptable si vous communiquez clairement aux utilisateurs.

Etape 11 : durcissement de l instance self-hosted

Sur un VPS, exposez Zitadel uniquement derriere un reverse proxy Caddy ou Nginx avec certificat Let s Encrypt valide. Configurez un firewall UFW ou nftables qui n autorise que les ports 80 et 443 vers Internet, le 8080 etant accessible uniquement depuis localhost. Ajoutez fail2ban pour bloquer les tentatives de bruteforce sur /ui/login.

Activez les logs structures JSON de Zitadel et expediez-les vers Loki ou un Elasticsearch via Promtail. Configurez une alerte sur le pattern login failed plus de 10 fois en 5 minutes pour la meme IP. C est le pattern classique de credential stuffing qu il faut bloquer rapidement.

Etape 12 : couts compares cloud vs self-hosted

Zitadel Cloud Free : 25 000 authentications par mois, 25 000 actions, support communautaire. Zitadel Cloud Pro : 90 USD par mois (environ 59 000 FCFA mensuels) pour 100 000 utilisateurs actifs. Self-hosted : un VPS Hostinger 4 GB a 7 EUR par mois (environ 4 600 FCFA mensuels) tient confortablement 50 000 utilisateurs avec des authentications regulieres.

Le break-even self-hosted vs Pro est tres rapide pour un projet ouest-africain typique. Mais comptez 2 a 4 heures par mois de maintenance (mises a jour, sauvegardes, monitoring). Si votre temps vaut plus que ce delta, le cloud reste pertinent malgre le cout USD.

Etape 13 : pieges courants et debug

Premier piege : oublier d ajouter le redirect URI exact dans la config de l Application Zitadel. Une difference de slash final ou de protocole http vs https provoque l erreur invalid_redirect_uri. Verifiez exactement la chaine entre votre code front et le champ Zitadel.

Deuxieme piege : tester en local avec http alors que WebAuthn exige soit localhost soit https. Si vous testez votre app en http://192.168.1.10:3000, l API navigator.credentials.create() echoue avec NotAllowedError. Utilisez ngrok ou un tunnel HTTPS local pour les tests cross-device.

Troisieme piege : utiliser la meme adresse mail pour deux organisations differentes. Zitadel supporte mais l UX devient confuse car l utilisateur doit choisir son contexte a chaque login. Documentez ce comportement aupres des admins clients pour eviter les tickets support.

Etape 14 : audit de securite et conformite

Une fois Zitadel en production, programmez un audit trimestriel : verifier que les passkeys sont effectivement utilises (le dashboard Zitadel expose un % d adoption), que les sessions inactives expirent (parametrer 30 jours par defaut, 7 jours pour comptes admin), que les rotation tokens fonctionnent (refresh_token expirant apres 14 jours d inactivite). Documenter chaque parametre dans un README versionne.

Pour la conformite RGPD applicable aux entreprises traitant des donnees de citoyens europeens, Zitadel offre l export des donnees utilisateur via l API /v2/users/{id}/dataexport et la suppression complete via /v2/users/{id} en DELETE. Documentez la procedure dans votre politique de confidentialite et automatisez via un endpoint d auto-service utilisateur.

Etape 15 : recap et prochaines etapes

En resume : Zitadel + passkeys offre en 2026 une experience d auth moderne, sans mot de passe, multi-tenant, deployable en self-hosted ou cloud. Pour une PME ouest-africaine, le combo VPS 4 GB + Zitadel + passkeys + Cloudflare devant evite la dependance a Auth0 ou Cognito factures en USD. Le ticket d entree est de 4 a 6 heures de setup, l ROI s amortit des le 2eme mois.

Une fois Zitadel en place, etendez vers : federation SAML avec Microsoft Entra ID pour les clients enterprise, integration Actions custom (Zitadel Actions en Go) pour appliquer des regles metier au login, et webhook vers votre CRM pour synchroniser les profils utilisateurs en temps reel.

Cette extensibilite par Actions et webhooks transforme Zitadel d un simple IdP en un veritable hub d identite operationnel, capable d enrichir et orchestrer le parcours utilisateur a chaque etape critique du cycle de vie du compte.

مشاركة