Aller au contenu principal

Rôles et permissions

Un rôle dans Liberty est un nom + une liste de chaînes de permissions. Les utilisateurs reçoivent des rôles ; les rôles accordent ou refusent ce que les utilisateurs peuvent faire.

L'onglet Paramètres → Accès → Rôles est l'endroit où les construire. La page cache chaque détail des chaînes de permissions derrière un PermissionPicker — on ne tape pas sql:crm:customers_get ; on sélectionne Requête → customers → customers_get dans des listes déroulantes et le picker génère la chaîne.


L'onglet Rôles

Paramètres · Accès👤 Utilisateurs🛡 Rôles+ Ajouter un rôleadminÉquivalent superutilisateur complet — baseline générique.Accès completanalystAccès complet, sauf les opérations destructives.3 règlesreaderLecture seule sur l'application crm.2 règlesCliquer sur une ligne pour ouvrir l'éditeur de rôle.

Chaque carte montre l'identifiant du rôle, sa description et un décompte des règles d'autorisation / de refus (ou une pastille Accès complet quand la baseline est * sans restriction supplémentaire).


L'éditeur de rôle

Cliquer sur une ligne de rôle pour ouvrir l'éditeur. Il comporte trois parties :

SectionNotes
Nom du rôleEn lecture seule après création. Renommer demande de supprimer et de recréer avec le nouveau nom (pas de renommage transversal pour les rôles — les références chez les utilisateurs se mettent à jour automatiquement puisque les utilisateurs portent les noms de rôles, pas les identifiants).
DescriptionTexte libre. Affichée sur la carte.
PermissionsLe PermissionPicker — baseline + règles d'autorisation / de refus.

Le PermissionPicker — anatomie

Éditeur de rôle · analystBASELINE⊘ Aucun accès✓ Accès complettout, moins les refus ci-dessousRÈGLES!sql:crm:customers_delete!menu:crm:admin!ai:chatAJOUTER UNE RÈGLE✓ Autoriser⊘ RefuserMenu ▾Sélectionnez un menu…+ Ajouter

La baseline

Deux boutons, mutuellement exclusifs :

BaselineListe des permissionsSémantique
Aucun accèsdémarre videRien n'est autorisé en dehors de ce qui est ajouté via des règles Autoriser. Le bon défaut pour les rôles moindre privilège.
Accès completdémarre avec ["*"]Tout est autorisé en dehors de ce qui est retiré via des règles Refuser. Le bon défaut pour les rôles proches du superutilisateur.

L'indication sous l'interrupteur lit soit « rien, plus les autorisations ci-dessous » soit « tout, moins les refus ci-dessous » selon le choix.

La liste de règles

Chaque règle est une pastille colorée :

Couleur de pastilleSignification
VertUne règle d'autorisation — sql:crm:customers_get, menu:crm:pipeline.
RougeUne règle de refus — les mêmes formes mais préfixées ! en stockage (!sql:crm:customers_delete).

Le ✕ de chaque pastille supprime la règle. La liste en haut du Picker est triée par ordre d'ajout.

Ajouter une règle

Trois contrôles sous les pastilles :

ContrôleCe qu'il fait
Effet (Autoriser / Refuser)Interrupteur deux boutons. Autoriser ajoute la pastille sans préfixe ! ; Refuser l'ajoute avec !.
TypeListe déroulante — Menu / Tableau de bord / Connecteur (toutes les requêtes) / Requête / Endpoint API / Assistant IA. Pilote les éléments disponibles dans la liste suivante.
ÉlémentUne recherche-sélection alimentée selon le Type. Pour Menu il liste chaque élément de menu de chaque application ; pour Connecteur il liste les connecteurs SQL ; pour Requête il liste chaque requête nommée ; pour Tableau de bord il liste chaque identifiant de tableau de bord ; pour Endpoint API il liste les endpoints de chaque connecteur API ; pour Assistant IA il y a une entrée unique.
+ AjouterRésout l'élément choisi en un ou plusieurs motifs de permissions, préfixe ! si Refuser, ajoute à la liste de règles.

Le picker prend en charge la composition des motifs afin d'éviter d'avoir à se rappeler la syntaxe sql:<c>:<q>. On raisonne en termes d'« autoriser ce menu » ou de « refuser cette requête » ; le stockage ressemble à menu:crm:reports ou !sql:crm:customers_delete.

Les règles de menu ont une expansion particulière

Quand on autorise une règle Menu, le picker l'étend en plusieurs motifs de permissions :

  • menu:<app>:<id> — pour que l'élément de menu apparaisse dans la navigation.
  • menu:<app>:<descendant_id> — pour chaque feuille descendante (afin que les sous-menus apparaissent).
  • sql:<connector>:<target> ou api:<connector>:<target> — pour la requête / le endpoint sous-jacent de chaque feuille descendante, afin que les écrans / endpoints fonctionnent réellement.

Une règle Autoriser → Menu → Pipeline accorde donc à l'utilisateur tout le dossier Pipeline et chaque écran qu'il contient, d'un seul geste. La même expansion s'applique sur Refuser — refuser Menu → Admin cache le dossier et refuse chaque écran qu'il contient.

Sans cette expansion, il faudrait ajouter une autorisation pour le menu et une autorisation séparée pour chaque requête sous-jacente — une corvée manuelle source d'erreurs. Le picker s'en charge.


Ordre de résolution

Quand le framework vérifie une permission, il parcourt cet ordre :

  1. Vérification superutilisateur — si l'utilisateur a is_superuser = true, tout est autorisé (règles de refus ignorées).
  2. Refus explicite — si un !<motif> parmi les permissions cumulées des rôles de l'utilisateur correspond, rejet.
  3. Autorisation explicite — si un motif non préfixé ! correspond, autorisation.
  4. Refus par défaut — sinon, rejet.

L'ordre compte. Une liste de permissions ["*", "!sql:crm:customers_delete"] :

  • sql:crm:customers_get → correspond à * (autorisation), aucun refus ne correspond → autorisé.
  • sql:crm:customers_delete → correspond à * (autorisation) et correspond à !sql:crm:customers_delete (refus) → le refus l'emporte → rejeté.
  • sql:reporting:* → correspond à * (autorisation), aucun refus ne correspond → autorisé.

Syntaxe des motifs — la grammaire complète

Les chaînes de permissions utilisent des globs segmentés par deux-points :

OpérateurSignificationExemple
<mot>Segment littéral.sql, crm, customers_get.
* (segment unique)Correspond à un segment.sql:*:customers_get correspond à sql:crm:customers_get et sql:reporting:customers_get.
* (en fin)Correspond au reste.sql:crm:* correspond à tout sql:crm:<n'importe quoi>.
!<motif>Refus.!sql:crm:customers_delete.
* (seul)Caractère générique pour tout.La baseline Accès complet.
!*Refuser tout.Rare ; en pratique un coupe-circuit.

Les surfaces complètes :

MotifAccorde
sql:<connector>:<query>Exécuter une requête SQL.
sql:<connector>:*Exécuter toutes les requêtes SQL sur un connecteur.
sql:*Exécuter toutes les requêtes SQL partout.
api:<connector>:<endpoint>Appeler un endpoint API.
api:<connector>:*Appeler chaque endpoint sur un connecteur.
menu:<app>:<id>Voir un élément de menu (dossier ou feuille).
menu:<app>:*Voir chaque élément de menu d'une application.
dashboard:<id>Ouvrir un tableau de bord.
ai:chatUtiliser l'assistant IA.
*Tout.

Recettes de rôles standard

RôleBaselineRègles
SuperutilisateurAccès complet(vide) — équivalent à activer is_superuser sur l'utilisateur.
Lecteur sur l'application CRMAucun accèsAutoriser → Menu → CRM (qui s'étend en menu:crm:* + sql:crm:* pour les requêtes de lecture).
Utilisateur avancé CRM sauf suppressionAccès completRefuser → Requête → customers_delete, deals_delete, activities_delete.
Accès IA uniquementAucun accèsAutoriser → Assistant IA. L'utilisateur se connecte et obtient la surface de chat IA mais ni menu ni écrans.
Responsable des rapportsAucun accèsAutoriser → Menu → Reports + Autoriser → Tableau de bord → revenue_overview / pipeline_health / etc.
Admin sans l'IAAccès completRefuser → Assistant IA. Tout le reste autorisé.

Le Permissions Picker traite chaque cas via la même cascade Autoriser / Refuser / Type / Élément.


Comment se composent les permissions effectives d'un utilisateur

Un utilisateur peut avoir plusieurs rôles. Le framework concatène les listes de permissions de chaque rôle — le refus l'emporte aussi entre rôles.

Exemple : Alice a à la fois analyst et reporter :

  • analyst.permissions = ["*", "!sql:crm:customers_delete"]
  • reporter.permissions = ["sql:reporting:*", "menu:reporting:*"]

Les permissions effectives d'Alice :

  • sql:crm:customers_get → autorisé par * dans analyst.
  • sql:crm:customers_delete → refusé par le !sql:crm:customers_delete d'analyst même si * l'autoriserait.
  • sql:reporting:monthly_revenue → autorisé à la fois par * (analyst) et par sql:reporting:* (reporter) — redondant mais sans conséquence.

Aucun rôle ne peut « passer outre » le refus d'un autre rôle — le refus est définitif sur l'ensemble des rôles de l'utilisateur.


Pièges courants

ErreurSymptômeCorrection
Autoriser un Menu sans réaliser qu'il accorde les requêtes sous-jacentes.Un utilisateur a plus d'accès SQL qu'attendu.Utiliser Autoriser → Requête pour un contrôle fin ; réserver Autoriser → Menu pour « accorder toute la section ».
Baseline Accès complet + quelques règles d'autorisation.Les autorisations sont redondantes (la baseline les accorde déjà).Choisir soit Accès complet (et refuser les exceptions), soit Aucun accès (et autoriser les spécificités). Pas les deux.
!sql:crm:* en pensant qu'il passera outre une autorisation héritée.Le refus fonctionne — mais l'utilisateur n'a aucun accès SQL sur crm même quand d'autres rôles l'accordent.Les refus sont absolus. À utiliser délibérément.
Renommer un rôle en modifiant le nom.Le nom est en lecture seule après création.Supprimer le rôle et le recréer avec le nouveau nom. Réattribuer les utilisateurs.
Oublier que les changements de JWT sont décalés.Un utilisateur reçoit un nouveau rôle mais ne le voit pas pendant une heure.L'utilisateur se déconnecte puis se reconnecte, ou attend le TTL du jeton d'accès.

Suite