ITSkillsCenter
Business Digital

Permissions row-level Hasura : filtrer les données par utilisateur connecté — tutoriel 2026

12 دقائق للقراءة

📍 Article principal : Hasura DDN + PostgreSQL pour PME. Ce tutoriel détaille la mise en place de permissions row-level par utilisateur connecté, garantissant que chaque client ne voit que ses propres données.

L’erreur la plus coûteuse en backend GraphQL pour une PME : exposer accidentellement les données d’un client à un autre. Un bug de filtrage manquant peut entraîner une fuite massive de commandes, factures, données personnelles, et déclencher une crise réputationnelle dont la PME ne se relève parfois pas. Hasura propose un moteur de permissions row-level extrêmement puissant qui filtre déclarativement les données accessibles à chaque rôle utilisateur. Bien configuré, ce moteur élimine totalement la classe de bugs d’autorisation manquante. Ce tutoriel passe en revue chaque mécanisme : configuration JWT custom claims, X-Hasura-User-Id, règles de permissions avec _and/_or, audit des permissions, tests automatisés.

Prérequis

  • Instance Hasura GraphQL Engine v2 fonctionnelle (voir tutoriel installation Coolify)
  • Service d’authentification émettant des JWT (Keycloak, Auth0, Supabase Auth, ou service maison)
  • Modèle de base avec au moins une table métier liée à un identifiant utilisateur
  • Notions JWT et claims
  • Niveau : avancé
  • Temps estimé : 4 à 5 heures

Étape 1 — Comprendre les rôles et X-Hasura-User-Id

Le moteur de permissions Hasura repose sur deux concepts. Le rôle identifie une catégorie d’utilisateur — anonymous (visiteur non connecté), user (client connecté standard), commercial (commercial avec accès élargi), admin (administrateur). Chaque rôle reçoit ses propres règles de permissions sur chaque table. Le session variable identifie l’utilisateur précis dans une session — typiquement X-Hasura-User-Id qui contient l’UUID de l’utilisateur connecté, plus d’autres variables custom comme X-Hasura-Org-Id, X-Hasura-Customer-Tier.

Ces variables proviennent du JWT validé par Hasura. Quand un client envoie une requête avec un Bearer token, Hasura décode le JWT, vérifie sa signature avec la clé partagée, lit les claims dans le namespace https://hasura.io/jwt/claims, et utilise ces claims comme variables de session pour évaluer les permissions. Cette mécanique élégante centralise toute la logique d’autorisation dans Hasura, le frontend et le service d’auth ne se préoccupent plus du contrôle d’accès aux données.

Étape 2 — Configurer le service d’auth pour émettre les bons claims

Quel que soit le service d’auth utilisé (Keycloak, Auth0, custom Node), il doit émettre des JWT contenant un namespace Hasura avec les claims attendus. Le format minimal :

{
  "sub": "user-uuid",
  "iat": 1714400000,
  "exp": 1714403600,
  "https://hasura.io/jwt/claims": {
    "x-hasura-allowed-roles": ["user", "commercial"],
    "x-hasura-default-role": "user",
    "x-hasura-user-id": "user-uuid",
    "x-hasura-org-id": "org-uuid"
  }
}

Le client peut basculer entre ses rôles autorisés en ajoutant un header X-Hasura-Role: commercial à sa requête. Hasura valide que ce rôle figure dans la liste autorisée par le JWT — cette double validation (allowed-roles + header) empêche un client malveillant de se faire passer pour admin en modifiant son header.

Pour Keycloak, configurer un Mapper de type Script qui injecte ces claims à chaque émission de token. Pour Auth0, utiliser une Rule ou Action qui ajoute le namespace. Pour un service custom Node, signer le JWT avec la lib jsonwebtoken en incluant le namespace dans le payload. La discipline : tester chaque format avec jwt.io avant de le brancher sur Hasura — un namespace mal positionné se traduit par des permissions silencieusement ignorées.

Étape 3 — Définir des permissions row-level basiques

Prenons le cas d’une table orders qui contient des commandes avec une colonne customer_id liée à la table customers. La règle de sécurité minimale : un utilisateur connecté ne doit voir que ses propres commandes. Dans la console Hasura, aller dans Data → orders → Permissions, cliquer sur le rôle user, configurer SELECT avec le filtre :

{
  "customer_id": {
    "_eq": "X-Hasura-User-Id"
  }
}

Ce filtre traduit en SQL ajoute automatiquement WHERE customer_id = $1 à toute requête du rôle user sur cette table. Aucun moyen de contournement côté client — la requête GraphQL la plus malveillante reçoit toujours uniquement les lignes appartenant à l’utilisateur authentifié. Sélectionner aussi quelles colonnes sont visibles pour ce rôle : typiquement id, customer_id, total_xof, status, created_at mais pas internal_notes ni cost_xof qui restent réservés au rôle commercial.

Étape 4 — Permissions composées avec _and / _or

Les règles métier réelles dépassent souvent le simple filtre par utilisateur. Exemples typiques : un client peut voir ses commandes ET les commandes partagées avec lui (cas du compte famille), un commercial voit les commandes de ses clients assignés ET de son équipe, un manager voit toutes les commandes de son organisation. Ces logiques composées s’expriment avec les opérateurs _and et _or de Hasura.

{
  "_or": [
    { "customer_id": { "_eq": "X-Hasura-User-Id" } },
    { "shared_with": { "user_id": { "_eq": "X-Hasura-User-Id" } } }
  ]
}

Cette règle autorise l’accès à une commande si l’utilisateur connecté est le propriétaire OU si la commande est partagée avec lui via une table de jonction shared_with. Hasura traduit cela en SQL avec un EXISTS ou un OR-JOIN selon le contexte, performance optimale dans les deux cas. La syntaxe JSON reste lisible même pour des règles plus complexes — un développeur qui revient sur le code six mois plus tard comprend immédiatement la logique de sécurité.

Étape 5 — Permissions sur INSERT, UPDATE, DELETE

Les permissions ne se limitent pas aux SELECT. Pour les mutations, Hasura propose des règles distinctes. Sur INSERT, configurer Pre-insert check qui valide les données avant l’insertion. Exemple typique : un utilisateur ne peut créer une commande que si le customer_id dans le payload correspond à son propre user_id : {"customer_id": {"_eq": "X-Hasura-User-Id"}}. Cette règle empêche un utilisateur malveillant de créer une commande au nom d’un autre utilisateur.

Sur UPDATE, configurer un filtre similaire et limiter quelles colonnes peuvent être modifiées par chaque rôle. Un utilisateur peut typiquement modifier l’adresse de livraison de ses commandes en statut pending, mais pas le total ni le statut. Un commercial peut modifier les notes internes mais pas le customer_id. Cette granularité fine donne le contrôle exact attendu sans ouvrir des portes dérobées.

Sur DELETE, la pratique recommandée pour la majorité des PME : désactiver totalement DELETE pour les rôles utilisateurs et utiliser des soft-delete via une colonne deleted_at. Hasura permet aussi cela en filtrant SELECT/UPDATE pour exclure automatiquement les lignes avec deleted_at IS NOT NULL. Cette approche conserve toute l’historique pour audit tout en masquant les données effacées au quotidien.

Étape 6 — Tests automatisés des permissions

Les permissions de sécurité méritent une couverture de tests automatisés. Sans cela, une modification bien intentionnée peut casser silencieusement l’isolation entre utilisateurs et créer une faille critique. Mettre en place une suite de tests avec deux utilisateurs fictifs alice et bob, créer des données pour chacun, exécuter des requêtes GraphQL avec leurs JWT respectifs, valider que chacun ne voit que ses propres données.

Le format des tests : un script Python ou Node qui se connecte à Hasura avec le JWT d’alice, exécute une query orders { customer_id }, vérifie que toutes les lignes retournées ont customer_id = alice.id. Tester aussi les mutations : alice essaie d’insérer une commande avec customer_id = bob.id — la requête doit échouer avec une erreur de permissions. Tester les cas limites : rôle anonymous, rôle inexistant, JWT expiré, JWT signé avec mauvaise clé. Ces tests s’exécutent dans la CI à chaque modification du schéma ou des permissions, bloquent le déploiement en cas de régression.

Étape 7 — Audit trail des accès sensibles

Pour les données sensibles (santé, légal, finance), conserver un journal d’accès qui trace qui a consulté quoi et quand. Hasura ne fournit pas cette fonctionnalité nativement mais elle s’implémente facilement avec les Event Triggers ou un proxy logging. Le proxy le plus simple : un endpoint Node devant Hasura qui logge chaque requête (user_id, opération, timestamp, IP) avant de la transmettre à Hasura. Les logs partent vers Loki ou Elasticsearch, requêtables pour répondre à un contrôle ou une demande d’enquête.

Pour les données extrêmement sensibles, déclencher un Event Trigger sur les SELECT n’est pas idéal (Hasura ne supporte pas cela directement) — préférer les notifications post-fait via Postgres NOTIFY couplées à un consommateur dédié, ou un audit table en append-only renseignée par les Actions custom qui encapsulent les requêtes sensibles. Cette double protection (permissions row-level + audit trail) constitue le standard de sécurité en production pour les services réglementés.

Patterns multi-tenants pour SaaS

Pour les PME qui développent un SaaS avec plusieurs organisations clientes hébergées sur la même base, les permissions Hasura supportent élégamment l’isolation multi-tenants. Ajouter une colonne org_id à toutes les tables métier, propager X-Hasura-Org-Id dans le JWT, configurer chaque permission avec {"org_id": {"_eq": "X-Hasura-Org-Id"}}. Cette discipline simple garantit qu’un utilisateur d’une organisation ne voit jamais les données d’une autre, même en cas de bug applicatif côté frontend.

Pour les SaaS avec besoin d’isolation forte (santé, finance), aller plus loin avec une base PostgreSQL par organisation et plusieurs sources Hasura connectées. Le surcoût opérationnel reste contenu mais la séparation physique des données rassure les clients exigeants. La transition entre architecture multi-tenants logique et physique se fait progressivement : démarrer en logique pour la simplicité, basculer en physique quand un client critique l’exige contractuellement.

Permissions calculées et fonctions PostgreSQL

Pour les règles métier complexes qui dépassent les opérateurs JSON de Hasura, écrire une fonction PostgreSQL qui retourne un boolean et l’utiliser dans les permissions via la syntaxe {"_exists": {"_table": {...}, "_where": {...}}}. Exemple : autoriser l’accès à une commande si l’utilisateur appartient à un groupe partagé avec le client de la commande, via une fonction user_can_access_order(user_id, order_id) returns boolean.

Cette extension fonctionnelle reste rare dans la pratique — 95 % des cas tiennent dans les opérateurs natifs Hasura. Mais quand le besoin existe, la possibilité de descendre en SQL custom évite de dégrader l’architecture en exposant trop de données et en filtrant côté frontend. Documenter chaque fonction de permissions dans un fichier de migration dédié, la traiter avec la même rigueur que le reste du schéma.

Erreurs fréquentes

ErreurCauseSolution
Permissions ignorées en mode admin secretHeader x-hasura-admin-secret bypasse toutes les permissionsNe jamais utiliser admin-secret côté client, uniquement pour les tâches de migration
JWT validé mais permissions videsNamespace claims absent ou mal formatéVérifier le format exact attendu, tester avec jwt.io
Rôle anonymous trop permissifPermissions oubliées sur des tables ajoutéesAudit régulier, principe du moindre privilège, allow-list des champs publics
Performance dégradée sur règles complexesEXISTS ou JOIN sur tables non indexéesAjouter les index suggérés par EXPLAIN ANALYZE

Adaptation au contexte ouest-africain

Pour les PME ouest-africaines qui gèrent des données réglementées (CDP Sénégal, ARTCI Côte d’Ivoire, AMRTP Mali), les permissions row-level Hasura constituent un atout conformité majeur. Le caractère déclaratif facilite la démonstration aux régulateurs : au lieu de fouiller dans des dizaines de fichiers de code, l’auditeur ouvre la console Hasura et voit immédiatement la matrice rôle × table × opération avec les filtres associés. Cette transparence simplifie radicalement les audits CDP ou ARTCI et démontre la maturité de la posture sécuritaire de la PME.

Ces deux disciplines de gouvernance — fonctions de permissions documentées et tests automatisés — constituent les piliers d’une posture sécuritaire mature qui distingue durablement les PME ouest-africaines qui scalent dans la confiance de celles qui accumulent silencieusement les risques jusqu’à l’incident inévitable. Une PME qui adopte ces pratiques dès le départ construit un actif de confiance auprès de ses clients qui se traduit directement en taux de conversion, en rétention et en valeur de marque sur la durée.

Évolution des permissions et déploiement zéro-downtime

Les besoins métier évoluent et avec eux les règles de permissions. Modifier une permission en production est une opération critique — une règle trop restrictive bloque les utilisateurs légitimes, une règle trop permissive expose des données. La pratique recommandée consiste à versionner toutes les modifications de permissions dans des fichiers de métadonnées Hasura (export JSON via la CLI), les faire passer par une pull request avec revue obligatoire de deux développeurs, déployer via la CI uniquement après tests automatisés validés.

Pour les modifications complexes qui changent la structure des règles (ajout d’une nouvelle dimension de permissions par exemple), prévoir une stratégie de déploiement progressif : déployer les nouvelles règles en mode shadow d’abord, observer pendant quelques jours qu’elles produisent les résultats attendus sans impacter l’existant, basculer définitivement après validation. Cette approche conservatrice évite les incidents catastrophiques et préserve la confiance opérationnelle de l’équipe.

La gouvernance des permissions est un sujet structurant qui mérite l’attention continue de toute l’équipe technique tout au long de la vie du produit.

Pour aller plus loin

🔝 Retour à l’article principal : Hasura DDN + PostgreSQL pour PME. Tutoriel précédent : déployer Hasura sur Coolify.

Documentation Hasura permissions : hasura.io/docs/2.0/auth/authorization. Pour pérenniser la posture sécuritaire, prévoir une revue trimestrielle de toutes les permissions par un développeur qui n’a pas écrit les règles initialement — un regard frais détecte fréquemment des failles silencieuses qu’un œil habitué laisse passer. Cette discipline simple constitue l’un des investissements les plus rentables d’une PME en croissance, prévenant des incidents de fuite de données dont le coût réputationnel et juridique peut atteindre plusieurs centaines de millions de XOF.

Besoin d'un site web ?

Confiez-nous la Création de Votre Site Web

Site vitrine, e-commerce ou application web — nous transformons votre vision en réalité digitale. Accompagnement personnalisé de A à Z.

À partir de 250.000 FCFA
Parlons de Votre Projet
Publicité