Auth0 + Hasura GraphQL : permissions déclaratives avec JWT

Intégrer Auth0 avec Hasura pour des permissions GraphQL déclaratives basées sur les JWT claims. Rôles, row-level security et column permissions.

Par Auth0.Expert · 2025-04-28 · 10 min de lecture

Hasura GraphQL JWT

Auth0 + Hasura GraphQL : guide complet

TL;DR

Hasura lit les claims JWT pour appliquer des permissions au niveau des lignes et colonnes de votre base de données. En configurant Auth0 pour injecter les bons claims, vous obtenez une sécurité déclarative sans écrire de code d'autorisation.

---

Architecture

Ce schéma illustre comment Auth0, Hasura et PostgreSQL s'enchaînent pour appliquer les permissions à chaque requête utilisateur.

Browser → Auth0 → JWT avec X-Hasura claims
                ↓
Browser → GraphQL Query + Bearer JWT → Hasura
                ↓
Hasura lit X-Hasura-Role et applique les permissions
                ↓
PostgreSQL — seulement les lignes autorisées

---

Configurer Auth0 pour Hasura

Ce bloc de code ajoute automatiquement les claims attendus par Hasura dans le JWT émis après chaque connexion, afin d'attribuer les rôles et informations utilisateur nécessaires.

// Action Post Login : injecter les claims Hasura
exports.onExecutePostLogin = async (event, api) => {
  const roles = event.authorization?.roles || [];
  const primaryRole = roles[0] || 'user'; // Hasura utilise 1 rôle par requête

  // Claims requis par Hasura
  api.accessToken.setCustomClaim('https://hasura.io/jwt/claims', {
    'x-hasura-default-role': primaryRole,
    'x-hasura-allowed-roles': roles.length > 0 ? roles : ['user'],
    'x-hasura-user-id': event.user.user_id,
    'x-hasura-org-id': event.user.app_metadata?.org_id || '',
    'x-hasura-team-id': event.user.app_metadata?.team_id || '',
  });
};

Ce code configure dynamiquement les claims Hasura pour chaque session utilisateur, en fonction des rôles et métadonnées dans Auth0.

---

Configurer Hasura : JWT Secret

Cette configuration YAML permet à Hasura de vérifier la signature des JWT émis par Auth0 et de lire les claims personnalisés pour l'autorisation.

# docker-compose.yml
services:
  hasura:
    image: hasura/graphql-engine:v2.36.0
    environment:
      HASURA_GRAPHQL_JWT_SECRET: |
        {
          "type": "RS256",
          "jwks_uri": "https://YOUR_DOMAIN.auth0.com/.well-known/jwks.json",
          "claims_namespace": "https://hasura.io/jwt/claims",
          "claims_format": "json"
        }
      HASURA_GRAPHQL_ADMIN_SECRET: "your-admin-secret"

---

Permissions par rôle dans Hasura

Dans cette section, nous définissons des permissions dans Hasura pour restreindre ou ouvrir l'accès aux données selon le rôle de l'utilisateur.

Row-level security : users ne voient que leurs données

Voici comment restreindre un rôle "user" à ses propres données grâce à une politique de filtrage basée sur son identifiant.

// Permissions pour le rôle "user" sur la table "posts"
{
  "role": "user",
  "permission": {
    "columns": ["id", "title", "content", "created_at"],
    "filter": {
      "author_id": {
        "_eq": "X-Hasura-User-Id"
      }
    }
  }
}

Rôle "admin" : accès total

Pour accorder un accès illimité à un rôle "admin", on retire les filtres et expose toutes les colonnes.

{
  "role": "admin",
  "permission": {
    "columns": "*",
    "filter": {}
  }
}

Rôle "org-member" : données de l'organisation

Ce modèle applique une restriction pour qu'un membre d'organisation n'accède qu'aux informations de sa propre organisation.

{
  "role": "org-member",
  "permission": {
    "columns": ["id", "name", "status"],
    "filter": {
      "organization_id": {
        "_eq": "X-Hasura-Org-Id"
      }
    }
  }
}

---

Requête GraphQL authentifiée

Ce morceau de code montre comment configurer Apollo Client pour inclure automatiquement le JWT Auth0 dans l'en-tête Authorization lors des requêtes GraphQL.

// Apollo Client avec Auth0
import { ApolloClient, InMemoryCache, createHttpLink } from '@apollo/client';
import { setContext } from '@apollo/client/link/context';
import { useAuth0 } from '@auth0/auth0-react';

function useApolloClient() {
  const { getAccessTokenSilently } = useAuth0();

  const authLink = setContext(async (_, { headers }) => {
    const token = await getAccessTokenSilently({
      authorizationParams: { audience: 'https://api.yourapp.com' },
    });
    return {
      headers: {
        ...headers,
        authorization: `Bearer ${token}`,
      },
    };
  });

  const httpLink = createHttpLink({
    uri: 'https://your-hasura.hasura.app/v1/graphql',
  });

  return new ApolloClient({
    link: authLink.concat(httpLink),
    cache: new InMemoryCache(),
  });
}

Ce composant React prépare un ApolloClient capable d'envoyer vos requêtes à Hasura avec un JWT valide à chaque appel.

---

Hasura Remote Schema : Auth0 Management API

Cette section explique comment exposer des opérations Auth0 en GraphQL via un schéma distant intégré à Hasura.

// Express.js : schema GraphQL pour les opérations Auth0
const { buildSchema } = require('graphql');

const schema = buildSchema(`
  type Query {
    me: User
    userProfile(id: ID!): User
  }

  type Mutation {
    updateProfile(name: String, picture: String): User
    changePassword(new_password: String!): Boolean
  }

  type User {
    id: ID
    email: String
    name: String
    picture: String
    roles: [String]
    plan: String
  }
`);

const resolvers = {
  me: async (args, context) => {
    const userId = context.headers['x-hasura-user-id'];
    return await auth0.getUser(userId);
  },
};

Ce schéma expose directement des opérations Auth0 en GraphQL, ce qui permet des intégrations avancées côté client et serveur.

---

Permissions ABAC (Attribute-Based)

Ici, on montre comment enrichir le JWT avec des attributs personnalisés pour gérer des permissions ABAC flexibles dans Hasura.

// Action Auth0 : claims ABAC dynamiques
exports.onExecutePostLogin = async (event, api) => {
  const user = event.user;
  const now = new Date();

  api.accessToken.setCustomClaim('https://hasura.io/jwt/claims', {
    'x-hasura-default-role': determineRole(user),
    'x-hasura-allowed-roles': getAllowedRoles(user),
    'x-hasura-user-id': user.user_id,
    // ABAC attributes
    'x-hasura-department': user.user_metadata?.department || '',
    'x-hasura-region': event.request.geoip?.country_code || '',
    'x-hasura-subscription-tier': user.app_metadata?.plan || 'free',
    'x-hasura-is-verified': user.email_verified ? 'true' : 'false',
  });
};

Ce bloc fournit tous les attributs nécessaires pour la création de politiques d'accès avancées côté Hasura, tenant compte du contexte utilisateur.

---

> ⚡ Auth0 + Hasura : nos équipes configurent votre stack Auth0/Hasura/PostgreSQL avec des permissions déclaratives et zero-config en 3 jours ouvrés.

📧 [email protected]


Autres articles