Gestion du consentement avec Auth0 : RGPD, ePrivacy et cookie consent

Implémentez une gestion du consentement conforme RGPD avec Auth0 : enregistrement des préférences, versioning des politiques et retrait du consentement.

Par Auth0.Expert · 2025-06-16 · 11 min de lecture

RGPD Consentement Privacy Auth0

Gestion du consentement avec Auth0 : RGPD complet

TL;DR

Le consentement RGPD doit être explicite, granulaire, versioned et révocable. Auth0 peut stocker les préférences de consentement dans user_metadata et déclencher des actions sur les changements. Mais ne stockez pas le consentement uniquement dans Auth0 — utilisez un système d'audit externe.

Architecture du consentement

Ce schéma illustre le parcours utilisateur pour la gestion du consentement, depuis l'inscription jusqu'au stockage en audit externe et dans Auth0 pour un accès rapide.

Signup/Login
     │
     ▼
Formulaire consentement
(Universal Login ou votre app)
     │
     ├── Consentement marketing ✅/❌
     ├── Analytics ✅/❌
     ├── Partage tiers ✅/❌
     └── Communications email ✅/❌
     │
     ▼
Auth0 Action (Post-Registration/Post-Login)
     │
     ├──▶ user_metadata.consent (pour accès rapide)
     └──▶ Votre DB d'audit consentement (source de vérité)

Stockage du consentement dans Auth0

Ce code montre comment collecter et encoder le consentement de l'utilisateur lors du signup pour le transmettre à Auth0 lors de l'authentification.

// Lors du signup — enregistrer le consentement initial
// Via paramètre dans le state de l'authorize request

// Frontend : encoder le consentement dans le state
const consentData = {
  consent_v: "2.3",
  marketing: true,
  analytics: false,
  third_party: false,
  email_notifications: true,
  timestamp: new Date().toISOString(),
  ip: userIP  // Côté serveur
};

const state = btoa(JSON.stringify({
  csrf_token: generateCSRF(),
  consent: consentData
}));

window.location.href = `https://${AUTH0_DOMAIN}/authorize?` + new URLSearchParams({
  client_id: CLIENT_ID,
  redirect_uri: CALLBACK_URL,
  response_type: "code",
  scope: "openid profile email",
  state: state,
  screen_hint: "signup"
});

Cette action côté serveur (Action Post-Registration) récupère puis stocke le consentement à la fois dans Auth0 pour un accès rapide et dans votre base d'audit externe pour la conformité RGPD.

// Auth0 Action : Post-Registration
exports.onExecutePostUserRegistration = async (event) => {
  // Décoder le state pour récupérer le consentement
  let consentData = null;

  try {
    const state = JSON.parse(atob(event.request.query?.state || "{}"));
    consentData = state.consent;
  } catch (e) {
    console.error("Failed to parse consent state");
  }

  if (consentData) {
    // 1. Mettre à jour user_metadata Auth0 (pour accès rapide)
    // Note: Dans Post-Registration, utiliser Management API
    const managementClient = new ManagementClient({
      domain: event.secrets.AUTH0_DOMAIN,
      clientId: event.secrets.MGMT_CLIENT_ID,
      clientSecret: event.secrets.MGMT_CLIENT_SECRET
    });

    await managementClient.updateUserMetadata(
      { id: event.user.user_id },
      {
        consent: {
          version: consentData.consent_v,
          marketing: consentData.marketing,
          analytics: consentData.analytics,
          third_party: consentData.third_party,
          email_notifications: consentData.email_notifications,
          recorded_at: new Date().toISOString()
        }
      }
    );

    // 2. Enregistrer dans votre système d'audit (source de vérité)
    await fetch(event.secrets.CONSENT_AUDIT_URL, {
      method: "POST",
      headers: {
        "Content-Type": "application/json",
        "Authorization": `Bearer ${event.secrets.CONSENT_API_KEY}`
      },
      body: JSON.stringify({
        user_id: event.user.user_id,
        email: event.user.email,
        action: "consent_given",
        consent_version: consentData.consent_v,
        preferences: {
          marketing: consentData.marketing,
          analytics: consentData.analytics,
          third_party: consentData.third_party,
          email_notifications: consentData.email_notifications
        },
        metadata: {
          ip_address: event.request.ip,
          user_agent: event.request.user_agent,
          signup_method: event.user.identities?.[0]?.provider,
          recorded_at: new Date().toISOString()
        }
      })
    });
  }
};

Ce code automatise la traçabilité du consentement dès l’inscription, assurant conformité et facilité d’audit.

Versioning des politiques de confidentialité

Avant chaque authentification, ce code vérifie que l'utilisateur a accepté la dernière version des CGU ou de la politique de confidentialité. En cas de changement de version, il redirige l'utilisateur pour obtenir à nouveau son consentement.

// Auth0 Action : Post-Login
// Vérifier si l'utilisateur a accepté la version actuelle des CGU
exports.onExecutePostLogin = async (event, api) => {
  const CURRENT_POLICY_VERSION = "3.1";
  const CURRENT_PRIVACY_VERSION = "2.3";

  const userConsentVersion = event.user.user_metadata?.consent?.version;

  // Si l'utilisateur n'a pas accepté la version courante
  if (userConsentVersion !== CURRENT_POLICY_VERSION) {
    // Rediriger vers la page de mise à jour du consentement
    // Via redirect rule
    api.redirect.sendUserTo("https://votre-app.com/update-consent", {
      query: {
        session_token: api.redirect.encodeToken({
          expiresInSeconds: 300,
          payload: {
            user_id: event.user.user_id,
            required_version: CURRENT_POLICY_VERSION,
            current_version: userConsentVersion || "none"
          }
        })
      }
    });
  }
};

// Auth0 Action : onContinuePostLogin (après redirect)
exports.onContinuePostLogin = async (event, api) => {
  const token = api.redirect.validateToken({
    secret: event.secrets.REDIRECT_SECRET,
    tokenParameterName: "session_token"
  });

  const newConsent = event.request.query?.new_consent;

  if (!newConsent || newConsent === "refused") {
    api.access.deny("Policy acceptance required to continue");
    return;
  }

  // Mettre à jour le consentement
  api.user.setUserMetadata("consent", {
    version: token.payload.required_version,
    updated_at: new Date().toISOString(),
    previous_version: token.payload.current_version
  });
};

Ce mécanisme garantit que l'utilisateur est toujours en accord avec la politique la plus récente avant d’accéder à l’application.

Retrait du consentement (Opt-out)

Cette fonction permet à un utilisateur de mettre à jour ou retirer son consentement depuis une page profil, en assurant la mise à jour côté Auth0, dans votre registre d'audit, et en répercutant les changements vers les systèmes tiers.

// Page "Mes préférences" — mettre à jour le consentement
async function updateConsent(userId: string, preferences: ConsentPreferences) {
  const mgmtToken = await getManagementToken();

  // 1. Mettre à jour Auth0
  await fetch(`https://${AUTH0_DOMAIN}/api/v2/users/${userId}`, {
    method: "PATCH",
    headers: {
      "Authorization": `Bearer ${mgmtToken}`,
      "Content-Type": "application/json"
    },
    body: JSON.stringify({
      user_metadata: {
        consent: {
          ...preferences,
          updated_at: new Date().toISOString(),
          action: "consent_updated"
        }
      }
    })
  });

  // 2. Enregistrer dans votre système d'audit
  await auditDb.insert({
    user_id: userId,
    action: "consent_updated",
    previous: oldPreferences,
    new: preferences,
    timestamp: new Date().toISOString(),
    source: "user_preference_center"
  });

  // 3. Déclencher les suppressions si nécessaire
  if (!preferences.analytics) {
    await analyticsService.deleteUserData(userId);
  }

  if (!preferences.marketing) {
    await emailService.unsubscribe(userId);
  }
}

Cette routine offre à l’utilisateur la possibilité de retirer tout ou partie de ses consentements, ce qui est clé pour la conformité RGPD.

Dashboard consentement (pour votre équipe)

Voici un exemple d’API backend permettant à un administrateur de visualiser l’état et l’historique du consentement pour un utilisateur, combinant les informations d’Auth0 et de votre base d’audit.

# API pour consulter le consentement d'un utilisateur
@app.get("/admin/consent/{user_id}")
async def get_user_consent(user_id: str, admin: Admin = Depends(require_admin)):
    """
    Vue administrateur du consentement utilisateur.
    Utile pour les demandes de droit d'accès RGPD.
    """

    # Auth0 : préférences actuelles
    auth0_user = await auth0_client.get_user(user_id)
    consent_metadata = auth0_user.get("user_metadata", {}).get("consent", {})

    # Votre DB : historique complet
    consent_history = await db.query(
        "SELECT * FROM consent_audit WHERE user_id = ? ORDER BY timestamp DESC",
        [user_id]
    )

    return {
        "user_id": user_id,
        "current_consent": consent_metadata,
        "history": consent_history,
        "legal_basis": {
            "authentication": "legitimate_interest",
            "marketing": "consent" if consent_metadata.get("marketing") else "not_applicable",
            "analytics": "consent" if consent_metadata.get("analytics") else "not_applicable"
        }
    }

Cette API facilite les réponses aux demandes RGPD en centralisant l’information consentement.

Tableau de conformité consentement

Ce tableau récapitule comment chaque exigence RGPD est couverte par l’implémentation proposée avec Auth0 et votre base d’audit.

| Exigence RGPD | Implémentation | Stockage | |---|---|---| | Consentement explicite | Checkbox explicite au signup | user_metadata + audit DB | | Granularité | Préférences séparées | user_metadata.consent.* | | Versioning | Numéro version stocké | consent.version | | Révocable | Page préférences | PATCH user_metadata | | Preuve | Audit DB avec IP/UA/timestamp | Audit DB (source de vérité) | | Portabilité | Export user_metadata | /api/users/{id}/export |

Auth0.Expert implémente des systèmes de gestion du consentement RGPD complets, de la conception à la certification.


Autres articles