Rôles et Permissions (RBAC)
Auris implémente le contrôle d’accès basé sur les rôles (RBAC) avec un modèle de résolution des permissions à trois états : les permissions peuvent être explicitement ALLOW (autorisées), explicitement DENY (refusées) ou INHERIT (héritées du défaut du rôle). Les surcharges au niveau utilisateur ont la priorité sur les permissions au niveau rôle, permettant des exceptions granulaires sans créer de rôles dédiés.
Format des Permissions
Toutes les permissions dans Auris suivent le pattern action:ressource :
manage:users view:invoices create:tickets
edit:roles approve:expenses delete:documents
assign:tickets sign:interventions export:reportsLe composant action décrit ce que la permission active. Actions courantes : view, create, edit, delete, manage, approve, assign, export, sign, generate.
Le composant ressource décrit l’entité ou la fonctionnalité accédée. Les ressources correspondent aux modules de ton application.
Il existe une permission spéciale — admin:all — qui accorde un accès illimité à toutes les ressources. Elle est assignée au rôle Administrateur par défaut.
Créer des Rôles
Via la Console
- Va dans Console → Rôles → Créer un Rôle
- Saisis un nom (ex.
Responsable Facturation), une description optionnelle et choisis une couleur pour le badge du rôle - Le rôle est créé sans permissions. Configure-les dans la page de détail du rôle.
Via l’API
/api/rolesRequires: manage:rolesCrée un nouveau rôle. Corps : { name: string, description?: string, color?: string }.
// Utilisant le Management Client d'Auris
const management = await createManagementClient({ ... })
const role = await management.roles.create({
name: 'Responsable Facturation',
description: 'Peut créer et visualiser les factures mais pas les supprimer',
color: '#3b82f6',
})Configurer les Permissions
Catégories de Permissions
L’éditeur de permissions dans la Console organise les permissions en 10 catégories :
| Catégorie | Exemples de Permissions |
|---|---|
| Documents | view:invoices, create:quotes, approve:expenses, sign:interventions |
| Utilisateurs | view:users, manage:users, import:users, export:users |
| Rôles | view:roles, manage:roles, assign:roles |
| Applications | view:applications, manage:applications, manage:api_keys |
| Organisations | view:organizations, manage:organizations, manage:sso_connections |
| Sécurité | view:audit_logs, manage:attack_protection, view:sessions |
| Facturation | view:billing, manage:subscriptions |
| Intégrations | view:integrations, manage:webhooks, manage:automations |
| Infrastructure | view:monitoring, manage:devices, manage:firewalls |
| Support | view:tickets, create:tickets, assign:tickets, manage:sla |
Définir les Permissions sur un Rôle
Dans la Console, chaque permission dispose d’un toggle à trois positions dans la page de détail du rôle :
- ALLOW — La permission est accordée aux utilisateurs avec ce rôle
- DENY — La permission est explicitement refusée, écrasant tout ALLOW hérité d’autres rôles
- INHERIT — Le rôle n’accorde ni ne refuse cette permission (défaut)
Un utilisateur obtient une permission si au moins un de ses rôles la définit sur ALLOW et aucun de ses rôles ne la définit sur DENY.
Via l’API
/api/roles/:id/permissionsRequires: manage:rolesMet à jour les permissions d’un rôle. Corps : { permissions: { [permission: string]: 'ALLOW' | 'DENY' | 'INHERIT' } }.
Assigner des Rôles aux Utilisateurs
Les rôles s’assignent aux utilisateurs dans la Console (Utilisateurs → [Utilisateur] → onglet Rôles) ou via l’API :
/api/users/:id/rolesRequires: manage:usersAssigne un ou plusieurs rôles à un utilisateur. Corps : { roleIds: string[] }.
/api/users/:id/roles/:roleIdRequires: manage:usersRetire un rôle d’un utilisateur.
Les utilisateurs peuvent avoir plusieurs rôles. Les permissions de tous les rôles sont fusionnées. Si un rôle a DENY pour une permission, cela écrase le ALLOW des autres rôles.
Surcharges de Permissions au Niveau Utilisateur
Les utilisateurs individuels peuvent avoir des permissions définies directement, indépendamment de leurs rôles. Les surcharges utilisateur ont la priorité sur toutes les permissions des rôles :
- Un ALLOW au niveau utilisateur accorde la permission même si aucun rôle ne la concède
- Un DENY au niveau utilisateur bloque la permission même si un rôle accorde ALLOW
Console : Utilisateurs → [Utilisateur] → onglet Permissions → Ajouter une Surcharge
/api/users/:id/permission-overridesRequires: manage:usersDéfinit une surcharge de permission pour un utilisateur spécifique. Corps : { permission: string, effect: 'ALLOW' | 'DENY' }.
Vérifier les Permissions
Côté Serveur (Route API)
Utilise le helper requirePermission() pour appliquer les permissions dans les routes API :
Next.js Route Handler
// app/api/invoices/route.ts
import { requirePermission } from '@auris/nextjs/server'
const config = {
domain: process.env.NEXT_PUBLIC_AURIS_DOMAIN!,
clientId: process.env.NEXT_PUBLIC_AURIS_CLIENT_ID!,
}
export const GET = requirePermission('view:invoices', config, async (req, { session }) => {
// Atteint seulement si l'utilisateur a la permission view:invoices
const invoices = await getInvoices(session.user.id)
return Response.json(invoices)
})
export const POST = requirePermission('create:invoices', config, async (req, { session }) => {
const body = await req.json()
const invoice = await createInvoice(body, session.user.id)
return Response.json(invoice, { status: 201 })
})Côté Client (Composants React)
React Hook
import { useCheckPermission, usePermissions } from '@auris/react'
// Vérifie une seule permission
function InvoiceActions() {
const { allowed: canCreate, isLoading } = useCheckPermission('create:invoices')
const { allowed: canDelete } = useCheckPermission('delete:invoices')
if (isLoading) return null
return (
<div>
{canCreate && <button>Nouvelle Facture</button>}
{canDelete && <button>Supprimer la Sélection</button>}
</div>
)
}
// Vérifie plusieurs permissions simultanément
function DashboardNav() {
const { has, hasAll, hasAny } = usePermissions([
'view:invoices',
'view:quotes',
'manage:users',
'view:billing',
])
return (
<nav>
{has('view:invoices') && <a href="/invoices">Factures</a>}
{has('view:quotes') && <a href="/quotes">Devis</a>}
{has('manage:users') && <a href="/users">Utilisateurs</a>}
{has('view:billing') && <a href="/billing">Facturation</a>}
{hasAll(['view:invoices', 'view:quotes']) && <a href="/documents">Tous les Documents</a>}
{hasAny(['manage:users', 'manage:roles']) && <a href="/fr/admin">Admin</a>}
</nav>
)
}API des Permissions
/api/roles/checkVérifie une ou plusieurs permissions pour l’utilisateur authentifié. Corps : { permissions: string[] } ou { permission: string }. Retourne un tableau d’objets { permission, allowed }.
/api/rolesRequires: view:rolesListe tous les rôles du tenant, incluant les compteurs de permissions et d’utilisateurs.
/api/roles/:idRequires: view:rolesObtient un rôle spécifique incluant son ensemble complet de permissions.
/api/roles/:idRequires: manage:rolesSupprime un rôle. Les utilisateurs qui avaient ce rôle perdent immédiatement les permissions associées.
Ordre de Résolution des Permissions
Quand Auris résout si un utilisateur a une permission spécifique, il suit cet ordre de priorité :
- DENY au niveau utilisateur — Si présent, la permission est refusée. Aucune évaluation supplémentaire.
- ALLOW au niveau utilisateur — Si présent (et aucun DENY), la permission est accordée.
- Permissions des rôles — Si au moins un rôle a ALLOW et aucun rôle n’a DENY, la permission est accordée.
- Refus implicite — Si aucune règle n’accorde la permission, elle est refusée.
DENY surcharge utilisateur → REFUSÉ (s'arrête ici)
ALLOW surcharge utilisateur → ACCORDÉ (s'arrête ici)
DENY de n'importe quel rôle → REFUSÉ (s'arrête ici)
ALLOW de n'importe quel rôle → ACCORDÉ
Aucune correspondance → REFUSÉPermissions Scopées par Application
Les permissions peuvent optionnellement être scopées pour une application spécifique. Quand un applicationId est inclus dans la vérification d’une permission, Auris évalue les permissions dans le contexte de cette application — utile pour les tenants multi-applications où les rôles peuvent différer par application.
const result = await fetch('/api/roles/check', {
method: 'POST',
headers: { Authorization: `Bearer ${accessToken}`, 'Content-Type': 'application/json' },
body: JSON.stringify({
permissions: ['view:invoices', 'create:invoices'],
applicationId: 'app-id-pour-app-facturation',
}),
})Guides Associés
- Autorisation Fine-Grained (FGA) — Contrôle d’accès au niveau objet au-delà des rôles
- Claims JWT Personnalisés — Intègre les données de rôles et permissions dans les access tokens
- Credentials M2M Client — Autorisation pour les appels serveur à serveur