Aller au contenu

Authentification et autorisations

Toutes les plateformes de l'écosystème utilisent un même modèle d'authentification. Cette page explique ce modèle et donne des indications pratiques aux relying parties (RP) qui s'y raccordent.

Vue d'ensemble du modèle

sequenceDiagram
    participant U as Utilisateur
    participant RP as Application RP
    participant SSO as Gerege SSO
    participant EID as eID Mongolia
    participant P as Téléphone

    U->>RP: Clique sur « Se connecter »
    RP->>SSO: Authorization request (code + PKCE)
    SSO->>EID: Démarrage de l'authentification eID
    EID->>P: QR / deep link / push
    P-->>EID: Validation par PIN1
    EID-->>SSO: Citoyen identifié
    SSO-->>RP: Authorization code
    RP->>SSO: code + code_verifier → jetons
    SSO-->>RP: access + refresh + id_token
    RP->>SSO: /userinfo
    SSO-->>RP: Informations utilisateur

Principe central : le RP n'accède jamais directement à l'eID. Tout passe par le SSO.

Méthodes de connexion

Méthode Type Remarque
eID Principale QR code · deep link mobile · push par numéro d'état civil
Google Secondaire La première liaison exige une vérification par eID

Ce qui n'existe pas : mots de passe, connexion par e-mail/OTP, connexion par OTP SMS.

C'est un choix délibéré. Un mot de passe qui n'existe pas ne peut ni fuiter, ni être réutilisé, ni être hameçonné.

Où une plateforme authentifie — AUTH_MODE

Une plateforme de l'écosystème peut jouer l'un de deux rôles :

  • Service d'identité — elle authentifie les utilisateurs elle-même. La carte de connexion (eID QR / numéro de registre · Google) s'affiche sur sa propre page d'accueil et sur /login.
  • Partie utilisatrice (RP) — elle délègue la connexion à un SSO amont. Le bouton « Se connecter » redirige vers le SSO, l'utilisateur s'y authentifie puis revient.

Ce n'est pas une différence de code, mais une configuration. C'est le paramètre AUTH_MODE du backend qui décide :

Valeur Surface de connexion
provider La carte de connexion s'affiche sur cette plateforme
client Redirection vers le SSO amont (SSO_ISSUER)

S'il n'est pas défini, le mode est déduit de la présence de SSO_CLIENT_ID.

Le frontend lit son mode depuis le point d'accès public GET /api/v1/site/auth — sans authentification et sans secret dans la réponse :

{ "mode": "client", "sso_issuer": "https://sso.gerege.mn", "provider": false }

Être issuer est une question DISTINCTE

AUTH_MODE répond à « où se connectent les utilisateurs de cette plateforme ». Le fait que la plateforme soit elle-même issuer pour d'autres applications est décidé séparément par OAUTH_ISSUER. Les deux peuvent être actifs simultanément — une configuration en chaîne où la plateforme émet des jetons pour d'autres tout en envoyant ses propres utilisateurs vers un IdP amont.

Résultat pratique : un service SSO et une plateforme qui le consomme exécutent le même code. La même image Docker démarre dans l'un ou l'autre rôle selon son environnement. Voir Code partagé.

PIN1 et PIN2

PIN1 PIN2
Certificat Authentication Signing
Objet Se connecter Signer
Conséquence juridique Aucune Oui — non-répudiation

Se connecter ≠ signer

Se connecter avec le PIN1 ne signifie pas que l'utilisateur a donné son accord à quoi que ce soit. Pour les actes aux conséquences juridiques (contrat, attribution de droits, engagement financier), une signature distincte par PIN2 est obligatoire.

Caractéristiques techniques OIDC

Élément Valeur
Flux Authorization code + PKCE (S256)
Access token Opaque
id_token JWT, RS256
Refresh token Rotatif, avec détection de réutilisation
Machine à machine client_credentials
Discovery /.well-known/openid-configuration
UserInfo /userinfo

Rotation du refresh token

À chaque usage d'un refresh token, un nouveau est émis et l'ancien devient invalide. Si l'ancien jeton est rejoué, c'est un signe de vol : toute la chaîne est alors invalidée.

Le RP doit donc enregistrer le nouveau jeton dès le rafraîchissement. Conserver l'ancien fera tomber toutes les sessions au rafraîchissement suivant.

Session et déconnexion

  • La session est une paire JWT access + refresh.
  • La déconnexion invalide à la fois le refresh et l'access (deny-list d'access).
  • Après déconnexion, l'utilisateur revient sur le domaine d'où il est parti.

Étapes pour devenir RP

1. Enregistrer l'application

Créez un client dans la console de Gerege SSO. Vous obtiendrez : client_id, client_secret.

À préparer pour l'enregistrement :

  • Les redirect URI (pour tous les environnements — dev / staging / prod)
  • Le post-logout redirect URI
  • Les scopes demandés
  • Le nom et le logo de l'application (ils apparaîtront sur l'écran de consentement)

2. Lire le discovery

GET https://sso.gerege.mn/.well-known/openid-configuration

Ne codez pas en dur les endpoints — lisez-les ici.

3. Authorization request

Implémentez le flux authorization code + PKCE (S256). Utilisez impérativement state et nonce.

4. Échanger le jeton

Code + code_verifieraccess_token, refresh_token, id_token.

5. Valider l'id_token

À vérifier impérativement :

  • [ ] Signature RS256 — avec la clé obtenue depuis le JWKS
  • [ ] iss correspond à l'issuer du discovery
  • [ ] aud est bien votre client_id
  • [ ] exp n'est pas dépassé
  • [ ] nonce correspond à celui que vous avez envoyé

6. Informations utilisateur

Récupérez-les depuis l'endpoint /userinfo.

Erreurs fréquentes

Le redirect URI doit correspondre exactement

Caractère par caractère : le / final, http contre https, le port et le sous-chemin comptent tous. C'est l'erreur d'intégration la plus fréquente.

Liste de contrôle lors d'un changement de domaine

Lors d'un changement de domaine ou de marque, mettez à jour les trois éléments en même temps. En oublier un fait échouer l'authentification silencieusement :

  • [ ] La liste des redirect URI dans le SSO
  • [ ] Les SAN du certificat TLS
  • [ ] Les adresses issuer / endpoint dans la configuration du RP

PKCE ne se saute pas

PKCE s'applique même aux clients confidentiels. Le surcoût est faible, la protection est réelle.

Modèle d'autorisation

Une fois l'authentification faite, le contrôle des droits commence. La hiérarchie standard de l'écosystème :

superadmin (1) → admin (2) → manager (3) → user (4)

Voir Conventions communes pour le détail.

Au niveau de l'organisation : l'appartenance est protégée par la RLS de Postgres — un utilisateur ne voit que les données de l'organisation dont il relève. Il s'agit d'une restriction au niveau de la base de données, et non d'un contrôle dans le code applicatif.

L'attribution des droits manager requiert une validation par PIN2 — voir Conventions communes.