Migration Auth0 zéro downtime : stratégie pour 10M+ utilisateurs
Comment migrer des millions d'utilisateurs vers Auth0 sans interruption de service ? Double-write, migration progressive et rollback plan.
Par Auth0.Expert · 2025-02-22 · 14 min de lecture
Migration Auth0 zéro downtime : guide pour les grandes bases
TL;DR
Migrer 10M d'utilisateurs vers Auth0 sans downtime est possible avec la bonne stratégie : migration lazy (à la première connexion), double-write et feature flags. Ce guide présente l'approche complète.
---
Les 3 stratégies de migration
Ce tableau présente les approches possibles pour migrer des utilisateurs vers Auth0, en comparant le niveau de risque et la probabilité de downtime selon chaque méthode.
| Stratégie | Description | Downtime | Risque | |-----------|-------------|---------|--------| | Big Bang | Migrer tout d'un coup | Oui (maintenance) | Élevé | | Progressive (batch) | Migrer par lots | Non | Moyen | | Lazy (à la connexion) | Migrer au premier login | Non | Faible |
Notre recommandation : Lazy Migration + Progressive pour les comptes inactifs.
---
Architecture de migration lazy
Ce schéma illustre le processus de la migration lazy : si l'utilisateur n'existe pas encore dans Auth0, on interroge le système legacy pour valider la connexion, puis on crée l'utilisateur dans Auth0.
Ancien système (Legacy IdP)
↓
Feature Flag
/ Auth0 Legacy Login
↓
Utilisateur existe ?
OUI → Login normal Auth0
NON → Migrer depuis Legacy
Créer dans Auth0
Login Auth0
---
Database Migration Custom Connection
Voici un exemple de script d'Auth0 pour une connexion custom Database : ce script vérifie d'abord l'existence de l'utilisateur dans Auth0 et, si absent, interroge votre API legacy pour valider les identifiants avant de créer l'utilisateur dans Auth0.
// Auth0 Custom Database Connection - Login Script
exports.login = async function (email, password, callback) {
const axios = require('axios');
// 1. Essayer d'abord dans Auth0 (connexion normale)
// Si l'utilisateur n'existe pas encore dans Auth0,
// Auth0 appelle ce script automatiquement
try {
// Vérifier les credentials dans votre système legacy
const response = await axios.post(
`${configuration.LEGACY_API_URL}/auth/verify`,
{ email, password },
{
headers: { 'X-Internal-Token': configuration.INTERNAL_TOKEN },
timeout: 5000,
}
);
const legacyUser = response.data;
if (!legacyUser.success) {
return callback(null, null); // Credentials incorrects
}
// 2. Retourner le profil utilisateur pour création dans Auth0
return callback(null, {
user_id: legacyUser.id,
email: legacyUser.email,
email_verified: legacyUser.email_verified || true,
username: legacyUser.username,
given_name: legacyUser.first_name,
family_name: legacyUser.last_name,
app_metadata: {
legacy_id: legacyUser.id,
legacy_plan: legacyUser.plan,
migrated_at: new Date().toISOString(),
migration_source: 'lazy',
},
});
} catch (err) {
return callback(err);
}
};
Ce script permet à Auth0 de vérifier les identifiants dans le système legacy, d'importer dynamiquement le profil utilisateur, puis d'assurer la transition lors du premier login.
---
Get User Script : vérifier si l'utilisateur existe
Ce script permet à Auth0 de rechercher dans votre système legacy si un utilisateur existe déjà lors d'une tentative de login ou de création de compte.
// Auth0 Custom Database - Get User Script
exports.getUserByEmail = async function (email, callback) {
const axios = require('axios');
try {
const response = await axios.get(
`${configuration.LEGACY_API_URL}/users/by-email/${encodeURIComponent(email)}`,
{ headers: { 'X-Internal-Token': configuration.INTERNAL_TOKEN } }
);
if (!response.data) return callback(null);
const legacyUser = response.data;
return callback(null, {
user_id: legacyUser.id,
email: legacyUser.email,
email_verified: true,
});
} catch (err) {
if (err.response?.status === 404) return callback(null);
return callback(err);
}
};
---
Feature Flag : migration progressive par cohorte
Voici un exemple de middleware pour router dynamiquement les utilisateurs entre Auth0 et votre système legacy, en fonction de leur email ou d'une règle de pourcentage.
// Middleware : diriger certains utilisateurs vers Auth0
function authRouter(req, res, next) {
const email = req.body.email || req.query.email || '';
// Feature flag par domaine email (migrer d'abord les @nouveaudomaine.com)
const useAuth0 = shouldUseAuth0(email);
if (useAuth0) {
return res.redirect(`https://login.yourapp.com/authorize?...`); // Auth0
} else {
return legacyLogin(req, res, next);
}
}
function shouldUseAuth0(email) {
const domain = email.split('@')[1]?.toLowerCase();
// Phase 1 : Nouveaux utilisateurs (aucun compte legacy)
// Phase 2 : Utilisateurs @earlyadopter.com
// Phase 3 : 10% aléatoire (hash stable)
// Phase 4 : 50%
// Phase 5 : 100%
const MIGRATED_DOMAINS = ['earlyadopter.com', 'beta.com'];
if (MIGRATED_DOMAINS.includes(domain)) return true;
// Hash stable pour cohérence (même utilisateur → même expérience)
const hash = crc32(email) % 100;
return hash < parseInt(process.env.AUTH0_ROLLOUT_PERCENT || '0');
}
Ce code permet d'augmenter progressivement le taux de migration selon la stratégie de feature flag et cohorte, réduisant ainsi le risque.
---
Migration progressive par lots (comptes inactifs)
Ce script Python exécute la migration des utilisateurs inactifs en lots, utile pour déplacer en amont les comptes qui ne se reconnecteront sans doute jamais.
# Migrer les comptes inactifs qui ne se reconnecteront peut-être jamais
import asyncio
from datetime import datetime, timedelta
async def migrate_inactive_users_batch(
legacy_db,
auth0_client,
inactive_since_days: int = 180,
batch_size: int = 100,
):
cutoff = datetime.utcnow() - timedelta(days=inactive_since_days)
# Récupérer les utilisateurs non encore migrés
users = await legacy_db.execute("""
SELECT id, email, email_verified, first_name, last_name, plan, created_at
FROM users
WHERE last_login < %s
AND auth0_migrated = FALSE
ORDER BY last_login ASC
LIMIT %s
""", (cutoff, batch_size))
migrated = 0
errors = 0
for user in users:
try:
await auth0_client.create_user({
"connection": "Username-Password-Authentication",
"email": user['email'],
"email_verified": user['email_verified'],
"given_name": user['first_name'],
"family_name": user['last_name'],
"app_metadata": {
"legacy_id": user['id'],
"plan": user['plan'],
"migrated_at": datetime.utcnow().isoformat(),
"migration_source": "batch",
},
"password": generate_temporary_password(), # Reset requis
})
await legacy_db.execute(
"UPDATE users SET auth0_migrated = TRUE WHERE id = %s",
(user['id'],)
)
migrated += 1
except Exception as e:
errors += 1
await log_migration_error(user['id'], str(e))
await asyncio.sleep(0.1) # 10 req/s max
return {"migrated": migrated, "errors": errors}
Ce script gère la migration par petits lots en mode asynchrone, tout en suivant précisément les réussites et les erreurs.
---
Rollback plan
Ce plan d'action décrit comment désactiver la migration vers Auth0 en cas de problème, en inversant simplement le feature flag.
# Si la migration doit être annulée
# 1. Feature flag → 0% Auth0
export AUTH0_ROLLOUT_PERCENT=0
# 2. Tous les utilisateurs retournent vers Legacy
# (leurs comptes Auth0 restent créés mais inactifs)
# 3. Analyser les erreurs
SELECT * FROM migration_errors ORDER BY created_at DESC LIMIT 100;
# 4. Corriger et re-déployer
---
Tracking de la progression
Ce rapport SQL permet de suivre l'avancement de la migration dans le temps, en distinguant les utilisateurs migrés lors du login (lazy) et ceux en batch.
-- Vue de suivi de migration
SELECT
COUNT(*) as total_users,
SUM(CASE WHEN auth0_migrated THEN 1 ELSE 0 END) as migrated,
ROUND(100.0 * SUM(CASE WHEN auth0_migrated THEN 1 ELSE 0 END) / COUNT(*), 2) as progress_pct,
SUM(CASE WHEN migration_source = 'lazy' THEN 1 ELSE 0 END) as lazy_migrated,
SUM(CASE WHEN migration_source = 'batch' THEN 1 ELSE 0 END) as batch_migrated
FROM users;
---
> 🔄 Migration zéro downtime : nous avons migré plus de 50 millions d'utilisateurs vers Auth0 sans aucune interruption de service. Contactez-nous pour un devis.
📞 +33 1 23 45 67 89 · 📧 [email protected]
Autres articles
- Auth0 et OAuth 2.0 : architecture complète pour comprendre les flux d'autorisation
- OpenID Connect sur Auth0 : ID Token, UserInfo et discovery endpoint expliqués
- Configurer SAML 2.0 avec Auth0 : guide complet pour l'entreprise
- Migrer des Rules vers les Auth0 Actions : guide pas à pas
- Architecture multi-tenant avec Auth0 : organisations, isolation et bonnes pratiques
- Validation des JWT Auth0 : RS256 vs HS256, JWKS et pièges communs
- Concevoir son architecture de tenants Auth0 : dev, staging, prod
- Configurer un domaine personnalisé Auth0 : login.votredomaine.com étape par étape