Conventions communes¶
Les standards de fait qui reviennent dans tous les dépôts de l'écosystème. Ils ne sont pas issus d'une spécification formelle : ce sont les règles qui se sont stabilisées après avoir résolu plusieurs fois les mêmes problèmes réels. Une nouvelle plateforme doit les respecter dès le départ.
Identity casing¶
La règle : stocker en base tout texte d'identité en minuscules. La recherche est insensible à la casse. À l'affichage, on convertit vers la forme standard (numéros d'immatriculation en majuscules, noms en Title Case).
Champs exemptés — ceux-ci sont conservés tels quels :
| Champ | Pourquoi |
|---|---|
etsi_identifier |
Le format est fixé par une norme |
| DN du certificat | Il entre dans la signature cryptographique et ne doit pas être modifié |
Champs *_latin |
Translittération latine — garde sa forme d'origine |
document_number |
Numéro d'un document officiel |
| Valeurs de hachage | Chaque bit compte |
D'où vient cette règle
Un citoyen s'enregistrait sous АБ12345678 puis tentait de se connecter en
аб12345678 : le système y voyait une autre personne et un compte en
double apparaissait. Normaliser la casse au niveau du stockage supprime toute
cette classe de bogues.
Hiérarchie des rôles¶
Règles strictes :
| Rôle | Peut | NE PEUT PAS |
|---|---|---|
superadmin |
Ajouter/supprimer des comptes admin | — |
admin |
Accorder des droits manager | Gérer les comptes admin |
manager |
Les opérations quotidiennes | Ajouter des personnes |
user |
Ses propres actions | Accorder des droits |
Le super admin est un compte distinct, protégé par MFA. Il est créé via un assistant d'onboarding : allow-list d'invitations → Google → eID → OTP par e-mail → TOTP + codes de secours. Il est stocké dans sa propre table, indexé par l'identité Google.
Conséquence pratique : une même personne peut être à la fois admin eID et super admin Google — deux comptes distincts, deux connexions distinctes. Chaque connexion de super admin est protégée par MFA.
Les droits d'admin sont accordés par numéro d'immatriculation, sur un utilisateur enrôlé dans l'eID local.
Attribution de droits validée par signature¶
La règle : accorder à quelqu'un les droits manager dans une organisation
déclenche l'envoi d'un push eID SIGN à cette personne, et l'attribution ne
devient ACTIVE qu'après validation par PIN2.
Pourquoi : accorder des droits est un acte aux conséquences juridiques. Si un administrateur nomme quelqu'un responsable de façon unilatérale, l'intéressé pourra le nier par la suite. Une signature PIN2 apporte la non-répudiation — elle ferme la porte au « je n'ai jamais donné mon accord ».
Règles de callback¶
La règle : un callback n'est retourné que dans les parcours same-device. Dans tous les autres cas, on interroge la session (poll).
| Situation | Mécanisme |
|---|---|
| Utilisateur sur un seul appareil (deep link) | Callback |
| QR code — second appareil | Poll de session (long-poll) |
| Notification push | Poll de session |
La raison : dans un parcours démarré sur un autre appareil, un callback ne sait pas où revenir. Le polling fait du navigateur d'origine la source de vérité et garde le parcours sans ambiguïté.
Deep links tiers — transmis en paramètre de callback ; à la fin, l'application concernée est ramenée au premier plan.
Liaison avec Google¶
La règle : avant de lier un compte Google, l'utilisateur doit obligatoirement être vérifié par eID. La première liaison rattache le compte à une personne réelle ; ensuite, la connexion directe par Google est possible. La liaison peut être défaite.
La raison : n'importe qui peut créer un compte Google. Seul, il ne peut pas valoir identification d'un citoyen. Une fois rattaché par eID, ce compte Google désigne un citoyen précis.
RP ↔ rp_app¶
La règle : seul le RP est enregistré auprès de
l'eID. Les différentes applications ou
sous-systèmes rattachés à un même RP sont transmis via les champs
rp_app / rp_app_url.
Ainsi, les journaux et l'écran de l'utilisateur indiquent quelle application a émis la demande — sans enregistrer un RP par application ni disséminer des identifiants.
La déconnexion se termine sur le domaine d'origine¶
La règle : en se déconnectant, l'utilisateur revient sur le domaine d'où
il est parti ; il n'est pas renvoyé vers le /login du SSO.
Pourquoi : l'utilisateur se trouvait dans l'application du RP. Atterrir ensuite sur l'écran de connexion d'un domaine totalement inconnu est déroutant. La déconnexion doit s'achever dans l'application où elle a commencé.
Les identifiants ont une source unique¶
La règle : les clients OAuth et leurs secrets sont créés uniquement dans le SSO et n'y vivent que là. Aucun autre système ne les crée, ne les stocke ni ne les affiche.
Le Developer Portal est le cas d'école de cette règle : il fournit la marche à suivre pour enregistrer une application, mais ne crée pas de client — il renvoie seulement par lien profond vers la console SSO.
La documentation est du code¶
La règle : chaque dépôt possède son répertoire docs/ et son site MkDocs. La
documentation vit dans le même dépôt que le code et évolue avec lui dans la
même PR.
Couverture linguistique : au minimum MN + EN ; les dépôts principaux ajoutent ZH · RU. Voir Internationalisation pour le détail.
Clean Architecture — pas de back-import¶
La règle : handler → usecase → repository → domain. Les dépendances vont
dans un seul sens. Le cœur métier (domain, usecase) n'importe jamais
de framework web.
Vérification simple : si un fichier sous domain/ importe net/http ou chi,
la règle est enfreinte.
Liste de contrôle pour ajouter une plateforme¶
- [ ] L'authentification passe par le SSO en tant que RP OIDC — aucun système de mots de passe propre
- [ ] Hiérarchie de rôles
superadmin → admin → manager → user - [ ] Texte d'identité en minuscules en base, champs exemptés identifiés
- [ ] RLS Postgres activée + garde-fou d'applicabilité au démarrage
- [ ] Journal d'audit — chaîné par hachage
- [ ] En-têtes de sécurité, allow-list CORS et rate limits configurés
- [ ]
/metricset/swaggerfermés en production - [ ]
docs/+ un site MkDocs, MN/EN - [ ] CI : build + tests + contrôle strict de la documentation