RBAC & scopes
Modèle RBAC
Section intitulée « Modèle RBAC »Logmis utilise un RBAC (Role-Based Access Control) avec deny-overrides et vérification de scope par préfixe d’OrgPath.
L’organisation est représentée comme un arbre de codes séparés par / :
/UAT-GROUP ← racine groupe/UAT-GROUP/UAT-LE ← entité légale/UAT-GROUP/UAT-LE/UAT-HOTEL ← établissement hôtel/UAT-GROUP/UAT-LE/UAT-CAMP ← établissement campingUn rôle assigné à /UAT-GROUP couvre tous les sous-chemins (préfixe). Un rôle assigné à /UAT-GROUP/UAT-LE/UAT-HOTEL ne couvre que l’hôtel.
home_scope (ADR-00D82)
Section intitulée « home_scope (ADR-00D82) »Chaque utilisateur a un home_scope OrgPath fixé à la création, borné au scope du créateur. Il ne peut pas être élargi après création.
Toute opération de gestion d’utilisateur (assign/revoke rôle, liste, détail, désactivation) exige que l’acteur couvre le home_scope de l’utilisateur cible (préfixe OrgPath, inclusif). En dehors du périmètre : 403/404.
Un rôle assigné ne peut pas sortir l’utilisateur de son home_scope (le scope du rôle doit être ⊆ home_scope).
Rôles builtin
Section intitulée « Rôles builtin »| Code | Permissions principales |
|---|---|
receptionist | Réservations CRUD, check-in/out, folio lecture, board arrivées/départs |
housekeeper | Board HK, tâches ménage, statuts unités |
manager | Dashboard, rapports, réservations (lecture étendue), tarifs, allotments |
maintenance-technician | Work-orders, asset maintenance, compteurs |
accountant | Folio complet, FEC, fiscal, settlement |
tenant-admin | Administration tenant, users/rôles (dans son home_scope) |
director | Mêmes permissions que tenant-admin — rôle à sémantique métier (direction d’un groupe d’établissements), scopé sur un sous-arbre OrgPath couvrant 1..N établissements |
Les rôles builtin sont seedés via seedBuiltinRoles (idempotent). Ils ne peuvent pas être supprimés.
Rôle director — scoping multi-établissements (ADR-00D86)
Section intitulée « Rôle director — scoping multi-établissements (ADR-00D86) »Un directeur supervise plusieurs établissements d’un même groupe. Son périmètre est défini par le scope de l’assignation dans role_assignments (OrgPath, ex. /UAT-GROUP), pas par l’appartenance à la racine tenant. La matrice de permissions est identique à tenant-admin en V1.0.
Différences sémantiques avec tenant-admin :
tenant-admin | director | |
|---|---|---|
| Scope typique | Racine tenant / | Sous-arbre org (ex. /UAT-GROUP) |
| Sémantique | Administration de l’abonnement SaaS | Direction opérationnelle d’un groupe d’établissements |
| MFA | Exigée | Exigée (même niveau de sensibilité) |
Le ScopeAuthorizer (ADR-00D82) applique au rôle director les mêmes gardes qu’aux autres rôles : toute opération de gestion (org.manage, apikey.manage) est bornée au périmètre de l’acteur. Un directeur scopé /grp-a ne peut pas créer une org-unit sous /grp-b, ni émettre une clé API avec un orgScope plus large que son propre scope.
PermissionResolver
Section intitulée « PermissionResolver »PermissionResolver.resolve( assignments: RoleAssignment[], requiredPermission: Permission, resourceScope: OrgPath,): boolean- Deny-overrides : si un rôle deny couvre la ressource, l’accès est refusé même si un autre rôle l’autorise
- Scope check : le scope du rôle doit être un préfixe (ou égal) au scope de la ressource
Assign / Revoke (HTTP, ADR-00D82)
Section intitulée « Assign / Revoke (HTTP, ADR-00D82) »# Assigner un rôlePOST /v1/users/:userId/roles{ "roleCode": "receptionist", "scope": "/UAT-GROUP/UAT-LE/UAT-HOTEL" }
# RévoquerDELETE /v1/users/:userId/roles/:roleCodeGardes :
- L’acteur JWT doit avoir la permission
users:assign-role - Le scope du rôle à assigner doit être ⊆
home_scopede l’utilisateur cible - L’acteur doit couvrir le
home_scopede l’utilisateur cible (préfixe OrgPath)
Cache Redis
Section intitulée « Cache Redis »Les permissions effectives sont cachées dans Redis avec un TTL configurable. La permission-epoch est incrémentée à chaque assign/revoke, invalide le cache.
Séparation tenant / control-plane
Section intitulée « Séparation tenant / control-plane »| Surface | Guard | Pool DB | Rôles |
|---|---|---|---|
/v1/users (tenant) | AuthGuard + RBAC | pms_app | Rôles builtin tenant |
/admin/* (control-plane) | PlatformAdminGuard | pms_control_plane | Opérateurs Osmozis uniquement |
Un opérateur Logmis n’a aucun accès aux données tenant via /v1/. Un utilisateur tenant n’a aucun accès au control-plane.
Scopes RBAC dans les tokens JWT
Section intitulée « Scopes RBAC dans les tokens JWT »Le JWT porte :
sub— userIdtid— tenantIdscope— home_scope OrgPath de l’utilisateur
Le scope du JWT est utilisé par le ScopeAuthorizer pour le re-check IDOR sur chaque requête.
Anti-élévation
Section intitulée « Anti-élévation »La création d’un utilisateur ne peut pas lui attribuer un home_scope plus large que celui du créateur. Exemple :
- Un manager avec scope
/UAT-GROUP/UAT-LE/UAT-HOTELne peut créer que des utilisateurs avec scope ⊆/UAT-GROUP/UAT-LE/UAT-HOTEL - Il ne peut pas créer un utilisateur avec scope
/UAT-GROUP(plus large)
Cette règle est vérifiée dans create-user.use-case.ts et dans le guard assign-role.