RBAC vs "permission-based" — ce que c'est, et pourquoi ce n'est pas la même chose¶
Document écrit à la demande de Bernard le 2026-07-11, pour être lu calmement, en amont du chantier d'alignement du frontend sur le design RBAC d'origine (voir ProjetESM/debug/20260711_1130_journal-matrice-permissions-rbac).
1. RBAC : un nom générique, pas une seule implémentation¶
RBAC = Role-Based Access Control = "l'accès à une fonctionnalité dépend du rôle de l'utilisateur qui la demande". C'est un principe, pas une recette figée. Le modèle de référence (norme NIST) décrit trois niveaux, pas deux :
Utilisateur → Rôle → Permission
- Un rôle est une étiquette portée par l'utilisateur (
PSYCHOLOGUE,MEAL_NATIONAL,ADMIN...). - Une permission est une capacité précise et nommée (
ENFANT_CREER,ETUDE_VALIDER,RAPPORT_EXPORTER...). - Le rôle n'est qu'un regroupement de permissions. Le contrôle d'accès réel se fait toujours sur la permission, jamais directement sur le nom du rôle.
Deux systèmes peuvent tous les deux se réclamer "RBAC" tout en étant très différents, selon qu'ils implémentent les trois niveaux ou qu'ils sautent le dernier.
D'où vient ce modèle à trois niveaux ? Du NIST (National Institute of Standards and Technology), l'agence fédérale américaine de normalisation — l'équivalent d'un institut de standards national, un peu comme l'AFNOR en France. Le NIST a formalisé ce modèle RBAC à trois niveaux dans les années 1990 pour la sécurité informatique, et c'est devenu depuis la référence standard reprise par la plupart des frameworks et de la littérature sur le contrôle d'accès. Ce n'est donc pas une préférence arbitraire : le modèle "permission-based" du backend est l'implémentation standard et reconnue du RBAC, tandis que le modèle actuel du frontend en est une version simplifiée qui saute le dernier niveau.
2. Les deux variantes, telles qu'elles existent aujourd'hui dans ProjetESM¶
Variante A — contrôle par rôle direct (ce que fait le frontend actuellement)¶
Utilisateur → Rôle → (contrôle direct sur le nom du rôle)
Le code pose la question : "Le rôle de cet utilisateur est-il dans cette liste ?"
// FrontEnd/src/app/Router.tsx
const ROLES_COORD_ET_ADMIN = ['MEAL_COMMUNAL', 'MEAL_NATIONAL', 'CHARGE_PROJET', ...];
if (!ROLES_COORD_ET_ADMIN.includes(user.role)) { /* accès refusé */ }
C'est un RBAC "à deux niveaux" — techniquement une forme dégradée du modèle, parfois appelée role-based au sens strict. La règle d'accès est écrite dans le code, une fois par endroit où elle est nécessaire.
Variante B — contrôle par permission (ce que fait le backend actuellement)¶
Utilisateur → Rôle → Permission → (contrôle sur la permission)
Le code pose une question différente : "Cet utilisateur a-t-il la permission
ENFANT_CREER ?" — peu importe son rôle, peu importe comment il l'a obtenue.
// BackEnd — déclaration de route
{ path: '/', method: 'POST', handler: 'creer', permission: 'ENFANT_CREER' }
// Middleware — vérifie uniquement la permission
const codes = req.utilisateur.permissionCodes; // chargé depuis la table ProfilPermission
if (!codes.includes('ENFANT_CREER')) { /* 403 */ }
Le lien "quel rôle a quelle permission" est une donnée en base (table
ProfilPermission), pas une règle écrite dans le code. C'est le modèle NIST complet :
c'est ça, le "vrai" RBAC à trois niveaux — le terme "permission-based" n'est qu'une façon
d'insister sur le fait que le contrôle porte sur la permission, pas sur le rôle.
3. Pourquoi la différence n'est pas cosmétique¶
| Variante A — rôle direct (frontend actuel) | Variante B — permission (backend actuel) | |
|---|---|---|
| Où vit la règle "qui a le droit de faire quoi" | Dans le code (tableaux ROLES_*) |
En base de données (table ProfilPermission) |
| Pour changer un droit | Éditer le code, redéployer | Modifier une ligne en base (via l'écran admin /administration/permissions, qui existe déjà) |
| Ajouter un nouveau rôle demain | Il faut retrouver et modifier chaque endroit du code qui liste des rôles (9 fichiers aujourd'hui) | Il suffit de créer le rôle et de lui assigner des permissions en base — aucun code à toucher |
| Risque d'oubli | Élevé — c'est exactement ce qui a produit le bug BAILLEUR (un rôle absent d'une liste parmi 9) | Faible — une seule table à tenir à jour |
| Ce que ça veut dire concrètement pour toi | Un écran d'admin "Gestion des permissions" qui ne sert à rien côté UI : changer une permission en base ne change jamais ce que l'utilisateur voit | Le même écran admin devient réellement utile : changer une permission en base change immédiatement ce que l'utilisateur voit, sans redéploiement |
Le point le plus concret : ton backend a déjà un écran /administration/permissions pour
éditer, profil par profil, quelles permissions sont accordées. Aujourd'hui, cet écran
n'a aucun effet visible côté interface — il change des droits d'accès à l'API, mais
l'interface continue de décider quoi afficher en regardant uniquement le rôle, câblé en
dur dans le code. Aligner le frontend sur le modèle permission (variante B) rend cet
écran enfin utile pour ce à quoi il est destiné.
4. Ce qui est prévu pour le chantier d'alignement¶
- Le frontend recevra la liste des permissions de l'utilisateur connecté
(
permissionCodes[]), comme le fait déjà le backend en interne. - Un mécanisme unique (
usePermission('CODE')) remplacera les ~9 tableauxROLES_*dupliqués dans le code frontend (Router.tsx,Sidebar.tsx, pages Enfants/ Formations/Mobilisation/Pilotage,ValidationActions.tsx...). - Chaque contrôle d'accès frontend (route protégée, entrée de menu, bouton d'action)
sera câblé sur la permission réellement vérifiée par la route backend
correspondante — pas sur une permission supposée par déduction du nom du module
(l'audit backend a montré des cas où ce n'est pas la même chose, ex. le module
Insertion est en réalité gouverné par
ACTEUR_CREER, pas parINSERTION_CREER). - Le scope "toutes les communes" (permission
ACCES_TOUTES_COMMUNES) sera corrigé côté backend pour être réellement lu et appliqué partout, avant d'être mirroré côté frontend — inclus dans ce même chantier, à la demande de Bernard (2026-07-11), pour ne pas refléter fidèlement un mécanisme backend lui-même incohérent.
Le document [ProjetESM/architecture/systeme-rbac-permissions](<../architecture/systeme-rbac-permissions.md>) sera mis à jour à
l'issue du chantier pour refléter l'état réel une fois l'alignement terminé.
Liens connexes¶
- ProjetESM/architecture/systeme-rbac-permissions — conception RBAC d'origine (2026-06-14)
- ProjetESM/debug/20260711_1130_journal-matrice-permissions-rbac — journal en direct de l'audit et du chantier d'alignement
- ProjetESM/index — index du projet