RBAC avec Auth0 : rôles, permissions et contrôle d'accès granulaire

Implémenter le Role-Based Access Control (RBAC) dans Auth0 : définir des rôles, assigner des permissions, valider les scopes côté API et gérer les hiérarchies.

Par Auth0.Expert · 2025-03-15 · 12 min de lecture

RBAC Permissions Autorisation

RBAC avec Auth0 : guide complet

TL;DR

Auth0 RBAC permet de définir des rôles (admin, editor, viewer) et des permissions (read:posts, write:posts) au niveau du tenant, et de les injecter automatiquement dans les access tokens.

---

Architecture RBAC Auth0

Ce schéma illustre comment les rôles et permissions sont structurés au sein d'un tenant Auth0, et comment ils sont attribués aux utilisateurs.

Tenant
├── Roles
│   ├── admin
│   │   ├── Permission: read:users
│   │   ├── Permission: write:users
│   │   └── Permission: delete:users
│   ├── editor
│   │   ├── Permission: read:posts
│   │   └── Permission: write:posts
│   └── viewer
│       └── Permission: read:posts
└── Users
    ├── alice → [admin]
    ├── bob   → [editor, viewer]
    └── carol → [viewer]

---

Créer rôles et permissions via l'API

Ces appels permettent de créer des permissions, des rôles, d’assigner des permissions à des rôles et de lier des rôles à des utilisateurs dans Auth0.

# Créer une permission sur le Resource Server
curl -X PATCH   "https://YOUR_DOMAIN.auth0.com/api/v2/resource-servers/API_ID"   -H "Authorization: Bearer $MGMT_TOKEN"   -H "Content-Type: application/json"   -d '{
    "scopes": [
      {"value": "read:posts", "description": "Lire les articles"},
      {"value": "write:posts", "description": "Créer et modifier les articles"},
      {"value": "delete:posts", "description": "Supprimer des articles"},
      {"value": "read:users", "description": "Voir les utilisateurs"},
      {"value": "write:users", "description": "Gérer les utilisateurs"}
    ]
  }'

# Créer un rôle
curl -X POST "https://YOUR_DOMAIN.auth0.com/api/v2/roles"   -H "Authorization: Bearer $MGMT_TOKEN"   -H "Content-Type: application/json"   -d '{"name": "editor", "description": "Peut lire et écrire des articles"}'

# Assigner des permissions au rôle
curl -X POST "https://YOUR_DOMAIN.auth0.com/api/v2/roles/ROLE_ID/permissions"   -H "Authorization: Bearer $MGMT_TOKEN"   -H "Content-Type: application/json"   -d '{
    "permissions": [
      {"resource_server_identifier": "https://api.yourapp.com", "permission_name": "read:posts"},
      {"resource_server_identifier": "https://api.yourapp.com", "permission_name": "write:posts"}
    ]
  }'

# Assigner le rôle à un utilisateur
curl -X POST "https://YOUR_DOMAIN.auth0.com/api/v2/users/USER_ID/roles"   -H "Authorization: Bearer $MGMT_TOKEN"   -H "Content-Type: application/json"   -d '{"roles": ["ROLE_ID"]}'

Ce script automatise l’administration des rôles et permissions dans Auth0 pour gérer facilement l’accès aux ressources.

---

Injecter les permissions dans le token

Pour que les permissions soient présentes dans les access tokens JWT, il faut activer l’option côté gestion Auth0 ou utiliser une Action de login personnalisée.

Dashboard → APIs → votre API → Settings → RBAC Settings :

{
  "enforce_policies": true,
  "token_dialect": "access_token_authz"
}

Vous pouvez également utiliser une Action pour ajouter finement les rôles et permissions dans les claims du token lors de la connexion.

exports.onExecutePostLogin = async (event, api) => {
  const roles = event.authorization?.roles || [];
  const permissions = event.authorization?.permissions || [];

  api.accessToken.setCustomClaim('https://myapp.com/roles', roles);
  api.accessToken.setCustomClaim('https://myapp.com/permissions', permissions);
};

Ce code ajoute les listes de rôles et permissions dans le token pour que l’API puisse les consommer facilement.

---

Validation RBAC côté API

Voici comment votre backend peut vérifier qu’un utilisateur dispose bien de la permission nécessaire à l’exécution d’une route.

from functools import wraps
from fastapi import HTTPException, Depends

def require_permission(permission: str):
    """Décorateur qui vérifie une permission dans le token."""
    def decorator(func):
        @wraps(func)
        async def wrapper(*args, payload=Depends(get_current_user), **kwargs):
            # Permissions dans le claim standard "permissions"
            token_permissions = payload.get('permissions', [])
            # Ou dans un claim custom
            custom_permissions = payload.get('https://myapp.com/permissions', [])
            all_perms = set(token_permissions + custom_permissions)

            if permission not in all_perms:
                raise HTTPException(
                    status_code=403,
                    detail=f"Permission manquante: {permission}"
                )
            return await func(*args, payload=payload, **kwargs)
        return wrapper
    return decorator

# Utilisation
@app.get("/posts")
@require_permission("read:posts")
async def list_posts(payload=Depends(get_current_user)):
    return {"posts": [...]}

@app.post("/posts")
@require_permission("write:posts")
async def create_post(data: PostCreate, payload=Depends(get_current_user)):
    return {"id": "new_post_id"}

Ce décorateur FastAPI assure qu’un appel d’API n’est effectué que si l’utilisateur possède la permission requise.

---

RBAC Dynamique : permissions basées sur les données

Dans certains cas, il est utile de compléter l’approche RBAC classique par des contrôles au niveau des données de l’application, par exemple, pour donner accès à ses propres ressources uniquement.

@app.get("/posts/{post_id}")
async def get_post(post_id: str, payload=Depends(get_current_user)):
    post = await db.posts.find_one({"id": post_id})

    if not post:
        raise HTTPException(404)

    # Admin peut tout voir
    if "read:all_posts" in payload.get("permissions", []):
        return post

    # Author peut voir ses propres posts
    if post["author_id"] == payload["sub"]:
        return post

    # Post public
    if post["visibility"] == "public":
        return post

    raise HTTPException(403, "Accès interdit")

Cette logique Python permet d’adapter la validation d’accès en fonction du contexte métier (par exemple, propriétaire, admin, public...).

---

Hiérarchie de rôles

Lorsque vous souhaitez des droits implicites avec héritage entre rôles, vous pouvez simuler une hiérarchie lors de la génération du token.

exports.onExecutePostLogin = async (event, api) => {
  const ROLE_HIERARCHY = {
    'super-admin': ['admin', 'editor', 'viewer'],
    'admin': ['editor', 'viewer'],
    'editor': ['viewer'],
  };

  const userRoles = event.authorization?.roles || [];
  const effectiveRoles = new Set(userRoles);

  for (const role of userRoles) {
    const inherited = ROLE_HIERARCHY[role] || [];
    inherited.forEach(r => effectiveRoles.add(r));
  }

  api.accessToken.setCustomClaim(
    'https://myapp.com/effective_roles',
    [...effectiveRoles]
  );
};

Ce code ajoute dynamiquement tous les rôles hérités dans le token, permettant une gestion flexible des droits d’accès.

---

> 🏗️ Implémentation RBAC sur mesure : nous concevons votre modèle de permissions (RBAC, ABAC ou hybride) adapté à votre domaine métier.

📧 [email protected]


Autres articles