Vue d'ensemble de l'architecture

Tous les tenants partagent la même base de données Supabase. L'isolation est appliquée par les politiques Row-Level Security (RLS) — des règles au niveau de PostgreSQL qui filtrent chaque requête en fonction des claims JWT de l'utilisateur authentifié.

Quand un utilisateur se connecte, son JWT contient un claim workspace_id. Chaque politique RLS vérifie ce claim par rapport à une colonne workspace_id dans la table. Les utilisateurs ne peuvent littéralement pas interroger des données d'autres workspaces — la base de données l'applique, pas le code de l'application.

C'est une garantie forte pour les clients enterprise français qui réalisent des audits de sécurité : l'isolation des données est prouvable au niveau infra, pas juste au niveau logiciel.

Mettre en place la structure de workspace

Tables dont vous avez besoin :

1. workspaces (id, name, plan, created_at) 2. workspace_members (id, workspace_id, user_id, role, created_at) 3. Toutes vos tables métier (avec colonne workspace_id)

Quand un utilisateur s'inscrit, créez un workspace et un enregistrement workspace_members dans une fonction de base de données Supabase. Le workspace_id est injecté dans le JWT de l'utilisateur via un hook de claim personnalisé.

Cette structure vous permet aussi de gérer l'invitation de membres, la facturation par workspace, et les permissions granulaires — tous les patterns d'un SaaS B2B mature.

Écrire les politiques RLS

Pour chaque table à portée de tenant, activez RLS et ajoutez des politiques pour SELECT, INSERT, UPDATE et DELETE. Chaque politique vérifie que le workspace_id de la ligne correspond au workspace_id extrait du JWT de l'utilisateur authentifié.

Cela applique l'isolation au niveau de la base de données — peu importe ce que fait votre frontend ou votre API. Même si un bug dans votre code WeWeb envoie une requête sans filtre de tenant, PostgreSQL n'retournera que les lignes appartenant au workspace de l'utilisateur.

C'est la différence entre la sécurité par convention et la sécurité par construction — un argument solide lors des négociations avec des grandes entreprises françaises.

Contrôle d'accès basé sur les rôles

Au sein d'un workspace, différents utilisateurs ont des permissions différentes (owner, admin, member). Stockez cela dans workspace_members.role.

Pour le RBAC au niveau des données, utilisez des fonctions Supabase dans vos politiques RLS. Une fonction get_user_role() peut retourner le rôle de l'utilisateur courant dans son workspace, et vous pouvez l'utiliser dans les conditions de politique pour des opérations comme la suppression ou la modification de paramètres critiques.

Combinez le RBAC dans les politiques RLS pour la sécurité des données avec des contrôles de rôle dans WeWeb pour l'UI — afficher/masquer des éléments de menu et des boutons selon le rôle. La sécurité réelle est dans RLS, l'UI est juste l'expérience utilisateur.

Connecter tout ça dans WeWeb

Dans WeWeb, configurez votre source de données Supabase avec le token de l'utilisateur authentifié. WeWeb transmet le JWT automatiquement avec chaque requête.

Pour la navigation et l'UI de votre application, lisez le rôle depuis une variable globale (remplie depuis la table workspace_members à la connexion). Affichez/masquez les éléments de menu, les boutons et des sections entières en fonction du rôle — c'est uniquement de la présentation, la vraie sécurité est dans RLS.

Ne codez jamais en dur des IDs de tenant dans WeWeb. Tout filtrage de données doit venir du JWT de l'utilisateur authentifié — Supabase s'occupe du reste. C'est un pattern que nous appliquons systématiquement sur tous nos projets SaaS.