// docs / baas security / clerk hardening
Liste de contrôle de sécurité Clerk : 20 éléments
Clerk gère l'authentification, les sessions et les organisations pour votre application — ce qui signifie qu'une intégration Clerk mal configurée est un contournement d'authentification, un vecteur de fixation de session ou un chemin de fuite entre organisations. Cette liste de contrôle est un audit de 20 éléments à travers les clés, la configuration de session, les webhooks, les organisations, les templates JWT et la surveillance continue. Les outils de codage IA câblent Clerk rapidement avec des défauts raisonnables ; cette liste attrape les éléments qu'ils laissent sur la table.
Pour le contexte sur pourquoi les mauvaises configurations au niveau de l'authentification sont un point faible des outils IA, voir Pourquoi les outils de codage IA laissent des failles de sécurité. Pour la liste de contrôle parallèle sur Auth0, voir Liste de contrôle de sécurité Auth0.
Clés d'environnement et liste d'origines autorisées
Clerk émet deux clés distinctes par projet. Les confondre ou les fuiter est le premier mode d'échec.
- Utilisez la clé publiable (
pk_live_*en production,pk_test_*en dev) dans le navigateur ; utilisez la clé secrète (sk_live_*/sk_test_*) uniquement sur le serveur. La clé publiable est sûre dansNEXT_PUBLIC_CLERK_PUBLISHABLE_KEY; la clé secrète ne doit jamais porter de préfixe env public et ne doit jamais apparaître dans un composant client. - Vérifiez que l'application de production utilise
pk_live_*, paspk_test_*. Les instances de test autorisent les adresses e-mail non vérifiées et le MFA désactivé — livrer le mode test en production est un contournement d'authentification. - Configurez les origines autorisées dans le tableau de bord Clerk. Settings → Domains → Allowed origins doit lister votre domaine de production exactement. Les listes d'origines vides ou avec joker permettent aux attaquants de créer des frontends Clerk frauduleux qui parlent à votre backend.
- Faites tourner la clé secrète à tout départ ou fuite suspectée. Tableau de bord → API Keys → Reset. L'ancienne clé est invalidée ; redéployez le code côté serveur avec la nouvelle valeur avant de faire tourner.
Configuration de session
L'expiration de session et les timeouts d'inactivité sont la différence entre une session volée qui devient un incident de 10 minutes ou de 30 jours.
- Définissez le timeout d'inactivité de session à 30 minutes ou moins pour les applications SaaS gérant des données sensibles. Tableau de bord → Sessions → Inactivity timeout. Les applications de niveau bancaire devraient utiliser 5-10 minutes ; SaaS standard 30-60 minutes ; applications grand public 1-7 jours. Le défaut est 7 jours.
- Activez la révocation de session lors d'un changement de mot de passe, changement d'e-mail et inscription au MFA. Tableau de bord → Sessions → Revoke on. Ce sont des événements de sécurité initiés par l'utilisateur ; les sessions existantes sur d'autres appareils devraient être tuées.
- Vérifiez les sessions côté serveur sur chaque route protégée, pas seulement à la connexion. En Next.js :
const { userId } = await auth();dans un composant serveur / route API lit le JWT depuis le cookie et le valide. Ne faites jamais confiance à une vérification de cookie seule. - Définissez
SameSite=Lax(défaut) ouStrictsur le cookie de session. Vérifiez dans DevTools → Application → Cookies.SameSite=Noneest un vecteur CSRF — ne l'utilisez jamais sauf si vous avez explicitement configuré une authentification inter-domaines.
Vérification des webhooks
Les webhooks Clerk se déclenchent sur les événements de cycle de vie utilisateur (créé, mis à jour, supprimé, session.ended). Ce sont le mécanisme de synchronisation pour votre base de données — et un webhook falsifié est une primitive d'écriture en base de données.
- Vérifiez la signature Svix sur chaque webhook. Les webhooks Clerk sont signés par Svix. Utilisez
new Webhook(secret).verify(body, headers). Rejetez avec401si la vérification échoue. - Stockez le secret du webhook dans une variable d'environnement, jamais dans le code. Le secret tourne à chaque régénération depuis le tableau de bord — votre déploiement doit le lire depuis l'env, pas depuis une constante.
- Idempotence sur chaque handler. Les livraisons de webhooks peuvent se répéter. Utilisez l'en-tête
svix-idcomme clé primaire dans une tablewebhook_eventspour dédupliquer. Enveloppez le changement d'état et l'insertion d'idempotence dans la même transaction. - Sur
user.deleted, supprimez ou anonymisez les PII en moins de 24 heures. RGPD / CCPA l'exigent. Auditez le chemin de suppression : quelles tables contiennent les données de cet utilisateur ? Utilisez FK ON DELETE CASCADE quand vous pouvez.
Organisations et permissions
Si vous utilisez Clerk Organizations, la frontière d'organisation est votre isolation de tenant. Chaque requête côté serveur doit filtrer par elle.
- Sur chaque route API, lisez à la fois
userIdetorgIddepuisauth()et filtrez les requêtes de base de données par les deux.WHERE org_id = $orgId AND user_id = $userId. Ne faites jamais confiance à unorg_iddu corps de la requête. - <strong>Use Clerk role checks for privileged operations, not boolean checks against the user object.</strong> <code>has({ role: 'org:admin' })</code> reads the role from the verified JWT. A user can spoof a boolean on a stale client object; they cannot spoof a JWT claim.
- Testez l'isolation inter-org avec deux comptes d'org réels. Créez Org A, peuplez les données, connectez-vous dans Org B dans un autre navigateur, tentez de lire les données de Org A via l'API. La réponse doit être
403ou404.
Templates JWT et intégrations externes
Les templates JWT poussent l'identité Clerk dans Supabase, Firebase et d'autres services en aval. Les templates mal configurés partagent trop de claims ou exposent des données non voulues.
- Pour chaque template JWT, listez chaque claim et confirmez qu'il est nécessaire. Tableau de bord → JWT Templates. Un template qui livre
emailetphoneà Supabase expose les PII à quiconque lit le JWT dans le navigateur. - Définissez une courte expiration sur les templates JWT utilisés pour les appels client-side en aval. 60 secondes pour les requêtes API en aval est le standard. Les JWT à plus longue durée de vie sont volés et rejoués.
- Vérifiez le claim d'audience (
aud) côté réception. Supabase, Firebase, etc. devraient vérifier queaudcorrespond à l'identifiant de service attendu. Sans cela, un JWT émis pour le service A peut s'authentifier au service B.
Surveillance opérationnelle
L'authentification est la source de logs au plus fort signal dont vous disposez. Surveillez-la.
- Alertez sur les pics d'échecs de connexion par IP / par compte. Un taux d'échec 50× normal est une attaque par credential stuffing. Clerk émet ces événements vers les webhooks ; routez-les vers votre SIEM.
- Revue trimestrielle de la dérive des paramètres de session et d'instance. Les défauts changent avec les mises à jour de Clerk ; les « anciennes configurations » deviennent silencieusement fausses avec le temps. Comparez l'export JSON du tableau de bord avec votre dernière copie connue-bonne.
Étapes suivantes
Lancez un scan FixVibe contre votre URL de production — le check baas.clerk-auth0 signale les clés publiables Clerk, les clés de test en production et les clés secrètes intégrées. Pour la liste de contrôle équivalente sur Auth0, voir Liste de contrôle de sécurité Auth0. Pour la vue d'ensemble sur les fournisseurs BaaS, lisez Scanner de mauvaises configurations BaaS.
