Comment ajouter un contrôle d'accès basé sur les rôles (RBAC) à votre application
Pour ajouter un contrôle d'accès basé sur les rôles, donnez à chaque utilisateur un ou plusieurs rôles (par exemple administrateur, éditeur, lecteur), définissez les actions que chaque rôle peut effectuer, et vérifiez ces permissions côté serveur pour chaque requête, et non uniquement en masquant des boutons. Vérifiez aussi que l'enregistrement consulté appartient au compte ou à l'équipe de l'utilisateur. Commencez par quelques rôles fixes dans votre base de données, et testez en essayant d'atteindre directement les données d'un autre utilisateur.
Authentification ou autorisation
Deux termes souvent confondus :
- Authentification : qui êtes-vous ? — la connexion. Voir comment ajouter une connexion à votre application.
- Autorisation : ce que vous avez le droit de faire ? — les pages, enregistrements et actions auxquels un utilisateur connecté peut accéder.
Le RBAC est la façon la plus courante de réaliser l'autorisation. C'est important : en septembre 2026, le contrôle d'accès défaillant (Broken Access Control) est n°1 dans le Top 10 OWASP 2025, la liste largement utilisée des risques de sécurité les plus graves pour les applications web. Les échecs typiques : des utilisateurs qui lisent les enregistrements d'autres utilisateurs en modifiant un identifiant dans l'URL, ou des utilisateurs ordinaires qui appellent des routes d'API réservées aux administrateurs.
Choisir un modèle
| Modèle | Fonctionnement | Idéal pour | Compromis |
|---|---|---|---|
| Une seule colonne de rôle | users.role = admin / member | Petites applications avec deux ou trois rôles | Devient confus lorsque les gens ont des rôles différents selon les endroits |
| Rôles + permissions | Les rôles correspondent à des permissions nommées (invoices.approve) ; le code vérifie les permissions | Applications dont les règles vont grandir | Plus de tables ; une liste de permissions à maintenir |
| Rôles par équipe (multi-locataire) | Une table d'appartenance : utilisateur + organisation + rôle | SaaS où les gens appartiennent à des équipes ou espaces de travail | Chaque requête doit être limitée à l'organisation |
| Basé sur des attributs ou des relations | Règles sur les attributs de l'enregistrement (« l'auteur peut modifier son propre article ») ou sur des relations (partagé avec) | Documents, partage, workflows complexes | Plus difficile à raisonner ; envisagez une bibliothèque ou un service dédié |
| Rôles du fournisseur d'authentification | Votre fournisseur de connexion stocke les rôles ou les appartenances aux organisations | Applications utilisant déjà un fournisseur d'authentification hébergé | Lié à ce fournisseur ; appliquez tout de même les règles sur votre serveur |
En pratique, la plupart des applications combinent deux éléments : des rôles pour le type d'actions qu'une personne peut effectuer, et la propriété pour les enregistrements sur lesquels elle peut agir. « Les éditeurs peuvent modifier les articles » est une règle de rôle ; « …les articles de leur propre espace de travail » est une règle de propriété. Vous avez besoin des deux.
Commencez plus simple que vous ne le pensez. Administrateur, membre et lecteur couvrent un nombre surprenant d'applications. Il est plus facile de séparer un rôle plus tard que de démêler dix rôles que personne ne comprend.
Concevoir les rôles avant d'écrire du code
Rédigez d'abord une table des permissions en langage clair. Elle sert à la fois de spécification pour l'IA et de plan de test :
| Action | Propriétaire | Administrateur | Membre | Lecteur |
|---|---|---|---|---|
| Voir les projets de l'équipe | ✓ | ✓ | ✓ | ✓ |
| Créer et modifier des projets | ✓ | ✓ | ✓ | |
| Supprimer des projets | ✓ | ✓ | ||
| Inviter et retirer des personnes | ✓ | ✓ | ||
| Modifier les rôles | ✓ | |||
| Facturation | ✓ |
Décidez aussi des cas limites : le dernier propriétaire peut-il quitter l'équipe ? Un administrateur peut-il retirer le propriétaire ? Que voit un utilisateur retiré ?
Étape par étape
1. Avoir d'abord une connexion fonctionnelle
Le RBAC repose sur l'authentification. Le serveur doit savoir de façon fiable qui fait chaque requête, à partir d'une session ou d'un jeton vérifié, jamais à partir d'un identifiant d'utilisateur envoyé par le navigateur dans le corps de la requête.
2. Stocker les rôles dans la base de données
Pour une application à une seule équipe, une colonne role sur les utilisateurs suffit. Pour les équipes, utilisez une table d'appartenances :
create table memberships (
user_id uuid references users(id),
organization_id uuid references organizations(id),
role text not null check (role in ('owner','admin','member','viewer')),
primary key (user_id, organization_id)
);
Ne laissez jamais les utilisateurs définir eux-mêmes leur rôle via une mise à jour de profil ordinaire. Les changements de rôle passent par un point de terminaison dédié, soumis à une vérification des permissions.
3. Vérifier les permissions côté serveur, à un seul endroit
Écrivez une fonction d'aide unique, par exemple can(user, 'projects.delete', project), et appelez-la dans chaque route d'API, chaque action serveur et chaque tâche en arrière-plan qui lit ou modifie des données. Une fonction centrale est plus facile à relire et à tester que des vérifications dispersées dans le code. Refusez par défaut : si aucune règle n'autorise une action, elle est refusée.
4. Limiter chaque requête
Chaque requête portant sur des données d'équipe doit inclure l'équipe : where organization_id = :currentOrg, et pas seulement where id = :id. C'est ce qui empêche quelqu'un de passer de /projects/123 à /projects/124 et de voir le projet d'une autre entreprise. Renvoyez « introuvable » plutôt que « interdit » pour les enregistrements d'autres équipes, afin de ne pas révéler leur existence.
5. Ajouter une protection au niveau de la base de données là où c'est nécessaire
La sécurité au niveau des lignes (RLS) de Postgres permet à la base de données de faire respecter les lignes que chaque utilisateur peut voir. Elle est indispensable si le navigateur communique directement avec la base de données (comme avec certains backends hébergés), et constitue une seconde couche utile pour les tables sensibles dans les autres cas.
6. Refléter les rôles dans l'interface
Masquez ou désactivez maintenant ce que les utilisateurs ne peuvent pas faire, afin que l'application reste claire. C'est uniquement pour l'ergonomie : ce sont les vérifications côté serveur qui protègent.
7. Journaliser les actions sensibles
Enregistrez qui a modifié des rôles, supprimé des données ou exporté des enregistrements, et quand. Un journal d'audit aide à répondre aux questions du support et à gérer les incidents.
8. Tester comme un attaquant
Connectez-vous avec chaque rôle et essayez chaque action de la table des permissions. Essayez ensuite ce qui ne devrait pas fonctionner : appeler des routes d'API d'administration en tant que lecteur, modifier les identifiants dans les URL et les requêtes, se retirer soi-même en tant que dernier propriétaire. Il vaut la peine d'écrire des tests automatisés pour la table des permissions une fois les règles stabilisées.
Requêtes qui fonctionnent
Ajoute un contrôle d'accès basé sur les rôles. Rôles par organisation : propriétaire, administrateur, membre, lecteur, stockés dans une table memberships. Les permissions sont dans ce tableau : [colle ton tableau]. Crée une seule fonction côté serveur can(user, action, resource), qui refuse par défaut, et utilise-la dans chaque route d'API. Limite chaque requête par organization_id. Masque dans l'interface les actions que l'utilisateur ne peut pas effectuer, mais ne te fie jamais à cela pour la sécurité.
Relis chaque route d'API et chaque fonction serveur de cette application. Pour chacune, liste les données qu'elle lit ou modifie, si elle vérifie que l'utilisateur est connecté, s'il vérifie son rôle, et si elle limite la requête à son organisation. Corrige celles qui n'ont pas de vérification, et montre-moi la liste.
Ajoute une page /admin réservée aux administrateurs où le propriétaire peut modifier les rôles des membres. Empêche de retirer ou de rétrograder le dernier propriétaire, journalise chaque changement de rôle avec son auteur et sa date, et assure-toi que le point de terminaison de changement de rôle rejette toute personne qui n'est pas propriétaire.
Erreurs courantes
- Vérifier les rôles uniquement dans l'interface. L'API reste ouverte à quiconque l'appelle.
- Faire confiance aux identifiants venant du client : un
userIdou unroledans le corps de la requête au lieu de la session. - Des requêtes non limitées qui récupèrent un enregistrement uniquement par son identifiant.
- Des rôles vérifiés sur les pages mais pas sur les routes d'API, les exports, les téléchargements de fichiers ou les webhooks.
- Un administrateur désigné par adresse e-mail codée en dur dans le code (
if email === 'me@...'), facile à oublier et difficile à modifier. - Trop de rôles trop tôt, que personne ne saura expliquer six mois plus tard.
- Sessions périmées : un utilisateur rétrogradé garde ses droits d'administrateur jusqu'à sa déconnexion. Vérifiez les rôles dans la base de données, ou rafraîchissez-les, pour les actions sensibles.
Liste de contrôle RBAC
- Table des permissions rédigée en langage clair, cas limites tranchés
- Le serveur identifie l'utilisateur à partir de la session, jamais à partir des données de la requête
- Rôles stockés dans la base de données ; les utilisateurs ne peuvent pas modifier les leurs
- Une seule vérification centrale des permissions, refus par défaut, utilisée dans chaque route
- Chaque requête limitée à l'organisation ou à la propriété de l'utilisateur
- Sécurité au niveau des lignes là où le navigateur peut atteindre la base de données
- L'interface masque ce que l'utilisateur ne peut pas faire (uniquement pour l'ergonomie)
- Actions sensibles journalisées
- Chaque rôle testé, y compris les appels directs à l'API et les identifiants modifiés
Le contrôle d'accès n'est qu'un point d'une liste plus longue ; la liste de contrôle de sécurité pour les applications créées avec l'IA couvre le reste. Si vous créez un outil pour votre propre personnel, comment créer un outil interne montre où placer les rôles.
Le RBAC sur Mythex
Mythex ne fournit pas de système intégré de connexion ou de rôles pour les utilisateurs de votre application. Vous choisissez une bibliothèque ou un fournisseur d'authentification et décrivez les rôles ; l'agent les intègre à votre code et à la base Postgres de votre projet (ajouter une connexion à votre application). Les rôles d'espace de travail de Mythex, comme Propriétaire et Membre, contrôlent qui peut modifier vos projets Mythex, et non qui peut utiliser l'application que vous publiez. Utilisez le mode Plan pour valider la table des permissions avant de construire, puis appliquez la requête de relecture ci-dessus et testez chaque rôle dans l'aperçu avant de publier. Les requêtes de sécurité de la documentation sont un bon complément.
Questions
Qu'est-ce que le contrôle d'accès basé sur les rôles ?
Le contrôle d'accès basé sur les rôles (RBAC) détermine ce que chaque utilisateur peut faire selon les rôles qu'il détient, par exemple administrateur, éditeur ou lecteur. Les permissions sont rattachées aux rôles et non aux personnes, si bien que modifier ce qu'une personne peut faire revient à modifier son rôle.
Quelle est la différence entre authentification et autorisation ?
L'authentification vérifie qui est une personne, généralement lorsqu'elle se connecte. L'autorisation décide ce que cette personne connectée a le droit de voir et de faire. Le RBAC est une façon de réaliser l'autorisation.
Masquer des boutons dans l'interface suffit-il à restreindre l'accès ?
Non. N'importe qui peut appeler directement votre API, donc masquer un bouton ne change que ce que les gens voient. Chaque requête qui lit ou modifie des données doit être vérifiée côté serveur, selon le rôle de l'utilisateur et la propriété de l'enregistrement.
Dois-je utiliser la sécurité au niveau des lignes de Postgres ?
La sécurité au niveau des lignes (row-level security) permet à la base de données elle-même de faire respecter les lignes que chaque utilisateur peut lire ou écrire, ce qui constitue un solide filet de sécurité, surtout lorsque l'interface communique directement avec la base. Elle ajoute de la complexité : beaucoup d'applications appliquent donc les permissions dans le code serveur et utilisent la sécurité au niveau des lignes comme couche supplémentaire pour les tables sensibles.