Retour au Blog
Blog/Architecture

Concevoir un Système RBAC Granulaire et Bloquer les Accès lors d'Abonnements Expirés

Comment implémenter des autorisations collaborateurs fines, verrouiller la création de documents à l'expiration du compte principal et monétiser le module en option payante.

Akram Hafaiedh
Akram Hafaiedh
Développeur Full Stack
2026-03-065 min de lecture
// SYSTEM ARCHITECTURE PATTERN
PRODUCTION VERIFIED
TECHNICAL CASE STUDY

Concevoir un Système RBAC Granulaire et Bloquer les Accès lors d'Abonnements Expirés

LARAVELREDISMULTI-TENANT

Gestion des Droits (RBAC) & Verrouillage d'Abonnement Multi-Utilisateurs

Dans les applications SaaS B2B (comme les ERP ou plateformes de facturation), le propriétaire d'un compte invite régulièrement des sous-utilisateurs (appelés Collaborateurs) pour gérer les opérations quotidiennes. La délégation d'accès pose deux défis techniques majeurs :

1. Découpage Granulaire des Autorisations : Les collaborateurs ne doivent pas posséder des droits administrateur globaux. Un responsable de stock doit pouvoir créer des articles sans avoir l'autorisation de supprimer des factures ou modifier la fiscalité.

2. Verrouillage en Cascade à l'Expiration de l'Abonnement : Lorsque l'abonnement du compte principal expire, la création de documents (ventes, dépenses, factures) doit être bloquée instantanément pour l'ensemble des collaborateurs liés, empêchant toute contournement.

Voici comment nous avons conçu un pipeline de contrôle d'accès basé sur les rôles (RBAC) et transformé la gestion des collaborateurs en une option d'abonnement payante.


1. Conception d'Autorisations Granulaires par Module

Plutôt que d'assigner des rôles globaux rigides (admin, staff), créez un schéma d'autorisations explicites associant des actions clés (invoices.create, invoices.delete, expenses.view) à des rôles personnalisés par le propriétaire.

php
class=class="text-emerald-500 dark:text-emerald-400 font-medium">"text-slate-500 italic">// app/Services/PermissionService.php
namespace App\Services;

use App\Models\User;

class PermissionService
{
    public static function canUserPerform(User $user, string $permission): bool
    {
        class=class="text-emerald-500 dark:text-emerald-400 font-medium">"text-slate-500 italic">// 1. Le propriétaire du compte dispose de tous les accès
        if ($user->is_workspace_owner) {
            return true;
        }

        class=class="text-emerald-500 dark:text-emerald-400 font-medium">"text-slate-500 italic">// 2. Récupère les autorisations du rôle collaborateur
        $permissions = $user->role ? $user->role->permissions->pluck('name')->toArray() : [];

        return in_array($permission, $permissions);
    }
}

Appliquez ensuite ces règles de manière transparente via un middleware Laravel :

php
class=class="text-emerald-500 dark:text-emerald-400 font-medium">"text-slate-500 italic">// app/Http/Middleware/CheckModulePermission.php
namespace App\Http\Middleware;

use Closure;
use Illuminate\Http\Request;
use App\Services\PermissionService;

class CheckModulePermission
{
    public function handle(Request $request, Closure $next, string $permission)
    {
        $user = $request->user();

        if (!PermissionService::canUserPerform($user, $permission)) {
            return response()->json([
                'error' => 'Vous ne disposez pas des autorisations requises pour exécuter cette action.'
            ], 403);
        }

        return $next($request);
    }
}

2. Verrouillage en Cascade de l'Abonnement Expiré

Une faille de sécurité classique survient lorsque les vérifications d'expiration ne ciblent que l'utilisateur directement connecté. Si un collaborateur se connecte, son statut individuel peut apparaître actif, lui permettant de créer des ventes ou dépenses alors que l'abonnement du compte propriétaire est expiré.

Pour corriger cette faille, vérifiez systématiquement le statut d'abonnement du compte propriétaire principal lors de chaque tentative de création :

php
class=class="text-emerald-500 dark:text-emerald-400 font-medium">"text-slate-500 italic">// app/Http/Middleware/EnsureActiveSubscription.php
namespace App\Http\Middleware;

use Closure;
use Illuminate\Http\Request;

class EnsureActiveSubscription
{
    public function handle(Request $request, Closure $next)
    {
        $user = $request->user();
        
        class=class="text-emerald-500 dark:text-emerald-400 font-medium">"text-slate-500 italic">// Résolution du compte propriétaire principal (tenant principal)
        $owner = $user->is_workspace_owner ? $user : $user->workspaceOwner;

        if (!$owner || !$owner->hasActiveSubscription()) {
            return response()->json([
                'error' => 'Abonnement expiré. Veuillez contacter l'administrateur du compte pour renouveler l'offre.',
                'code' => 'SUBSCRIPTION_EXPIRED'
            ], 402);
        }

        return $next($request);
    }
}

3. Monétiser le Module Collaborateurs en Option Payante

Après la sécurisation du système RBAC et du verrouillage des abonnements, l'équipe a identifié que la collaboration multi-utilisateurs représentait une valeur à fort impact pour les entreprises en croissance.

Plutôt que d'inclure la gestion des collaborateurs dans les forfaits de base, la fonctionnalité a été configurée comme un module d'extension payant (Add-On) :

php
class=class="text-emerald-500 dark:text-emerald-400 font-medium">"text-slate-500 italic">// app/Models/Workspace.php
namespace App\Models;

use Illuminate\Database\Eloquent\Model;

class Workspace extends Model
{
    public function canAddCollaborators(): bool
    {
        class=class="text-emerald-500 dark:text-emerald-400 font-medium">"text-slate-500 italic">// Vérifie si le compte possède l'option Collaborateurs ou un forfait Entreprise
        return $this->hasAddon('collaborators_module') || $this->plan_tier === 'enterprise';
    }

    public function maxCollaboratorLimit(): int
    {
        if (!$this->canAddCollaborators()) {
            return 0; class=class="text-emerald-500 dark:text-emerald-400 font-medium">"text-slate-500 italic">// Plan gratuit / standard sans option
        }

        return $this->addon_seats ?? 5;
    }
}

En combinant contrôle d'accès granulaire, verrouillage global du tenant et monétisation par fonctionnalités, vous transformez la gestion des autorisations en un module sécurisé et générateur de valeur.

Engineering Collaboration

Building a High-Scale SaaS or Complex System?

Let’s discuss your architecture, full-stack development, or system modernization needs.

Articles Similaires

// BACKEND & PIPELINE ENGINEERING
PRODUCTION VERIFIED
TECHNICAL CASE STUDY

Éliminer les Requêtes N+1 et Optimiser l'Indexation Multi-Locataires sous Forte Charge SaaS

PHP 8.3QUEUESPARALLEL WORKERS
Backend
2026-03-30•Backend

Éliminer les Requêtes N+1 et Optimiser l'Indexation Multi-Locataires sous Forte Charge SaaS

Read Article
// BACKEND & PIPELINE ENGINEERING
PRODUCTION VERIFIED
TECHNICAL CASE STUDY

Exportation de Données Massives : Éviter les Surcharges Mémoire avec Laravel & Vue 3

PHP 8.3QUEUESPARALLEL WORKERS
Backend
2026-03-25•Backend

Exportation de Données Massives : Éviter les Surcharges Mémoire avec Laravel & Vue 3

Read Article