Contrôle d'accès — Modèle & Cascade
Les 2 vecteurs de droits Wakastart : adminLevel et appRights (droits resource.action), et la vérification de features activées.
Contrôle d'accès — Modèle & Cascade
Le contrôle d'accès est double : le backend bloque toujours (source d'autorité), le frontend masque (UX). Ne faites jamais confiance au frontend seul pour sécuriser une action.
Concepts clés
- adminLevel : niveau hiérarchique, détermine la portée des opérations CRUD.
- appRights : droits fins sur des ressources spécifiques (
users.create,infra.deploy…), dérivés des profils. Le claim JWT correspondant s'appelleroles(formatresource.action) ; côté/me, ils apparaissent sousprofile.rights(tableau d'objets{code, name, description, category}, pas un simple tableau de strings). - features : activation en cascade App ∧ Network ∧ Customer. Si une feature est désactivée à n'importe quel niveau, elle est indisponible.
- Profile : ensemble de
AppRightassigné à un utilisateur. Un utilisateur peut avoir plusieurs profils.
Un ancien 3ᵉ vecteur,
wakaRoles(rôles métier transversaux type CONFIG/EXPLOIT/DPO/AUDIT/BILLING/CYBER), a été décommissionné côté plateforme. Les vérifications de droits reposent désormais uniquement suradminLevelet les codesresource.actionissus des profils — ignorez toute mention dewakaRolesdans du code ou de la documentation plus ancienne.
Les 2 vecteurs de droits
1. adminLevel — portée hiérarchique
Contrôle qui peut voir et modifier quoi selon la position dans la hiérarchie multi-tenant.
textWakaAdmin → Tout (plateforme complète, tous les Partners) OwnerAdmin → Tout (propriétaire du Partner) AppsAdmin → Applications + Profils + Droits (dans son Network) NetworkAdmin → Réseaux + Customers + Apps (dans son Network) CustomerAdmin → Customers + Users + Teams (dans son Customer) User → Son propre profil uniquement None → Aucun accès admin
Règle de hiérarchie : un NetworkAdmin possède implicitement les droits de CustomerAdmin et User. La vérification côté backend utilise une comparaison ordinale.
2. appRights — droits applicatifs fins
Droits de type {resource}.{action} accumulés depuis les profils de l'utilisateur.
Format : resource.action ou resource.sub-resource.action
Exemples :
textpartners.read users.create infra.deploy partners.write users.update infra.services.scale apps.read users.delete audit.read apps.create teams.read billing.manage apps.delete teams.members.add api-keys.read profiles.read teams.members.remove api-keys.create profiles.assign invitations.create api-keys.revoke profiles.rights.write invitations.read media.upload
Cascade de features
Une feature doit être activée à trois niveaux pour être disponible :
Chargement du diagramme…
Le payload /me n'expose pas de champ features précalculé. Vérifiez l'activation d'une feature via l'endpoint dédié : GET /api/config/app-features/check/{customerWid}/{featureCode}.
Exemple concret :
typescript// Si la feature "invitations" est désactivée à un niveau quelconque → masquer tout le module const { data } = await api.get(`/api/config/app-features/check/${customerWid}/invitations`); const hasInvitations = data.enabled;
Vérification combinée via /token/authorize
Pour des vérifications complexes (admin level + rôle + droit) en un seul appel :
httpPOST /api/token/authorize x-api-key: sk_live_... Content-Type: application/json { "token": "eyJ...", "checks": { "adminLevel": { "requiredLevel": "CustomerAdmin" }, "roles": { "roles": ["audit.read", "billing.manage"], "mode": "any" }, "appRights": { "rights": ["users.create", "users.update"], "mode": "all" } } }
json{ "authorized": true, "details": { "adminLevel": { "hasLevel": true, "actualLevel": "NetworkAdmin" }, "roles": { "hasRoles": true, "matchedRoles": ["audit.read"] }, "appRights": { "hasRights": true, "missingRights": [] } } }
Bonnes pratiques
- Principe du moindre privilège : n'accordez que les droits strictement nécessaires dans les profils.
- Backend = autorité : vérifiez toujours les droits côté serveur. Le frontend ne fait que masquer.
- Granularité fine : préférez
users.createàusers.*— les wildcards n'existent pas dans le modèle. - Features en premier : avant de vérifier un droit, vérifiez si la feature est activée.
Pièges classiques
- Confondre trois concepts voisins :
adminLevel(ADMIN,TEAM,INVITE,USER,EXTERN,NONE) est la portée administrative sur la hiérarchie ;teamLevel(ADMIN,MANAGER,MEMBER,CONTRIBUTOR,VIEWER,NONE) est le rôle au sein d'une équipe précise —MEMBERappartient àteamLevel, pas àadminLevel. appRightsvide = aucun accès : un utilisateur sans profil assigné aappRights: []et ne voit rien.- Feature désactivée → 403 : si
GET /api/config/app-features/check/{customerWid}/{featureCode}renvoieenabled: falseet que votre code appelle quand même l'API, vous obtiendrez un403 Feature désactivée. - Droits cumulatifs : si l'utilisateur a deux profils, ses
appRightssont l'union des deux.
Aller plus loin
- Implémentation guards & hooks : code complet frontend et backend
- Feature flags et cascade : AppFeature, NetworkAppFeature, CustomerAppFeature
- Contexte utilisateur /me : source des droits