Comment implémenter l’authentification et l’autorisation pour un assistant IA dans votre ERP/CRM (OIDC + RBAC, exemple Node.js)

Ce guide technique explique pas à pas comment sécuriser l’accès à un assistant IA intégré à un ERP/CRM : flux OpenID Connect (OIDC) pour l’authentification, et RBAC (rôles & permissions) pour contrôler les capacités de l’assistant. Public : CTO, lead dev, ingénieur backend. Exemple concret en Node.js + Express, avec vérification JWT via JWKS et gestion multitenant.

Pourquoi c’est important

  • Un assistant IA peut accéder à des données sensibles (clients, factures). L’authentification garantit l’identité ; l’autorisation contrôle ce que chaque utilisateur/tenant peut faire.
  • Mauvaise implémentation = fuite de données, usages non autorisés, coûts LLM hors contrôle.
  • OIDC + RBAC est une combinaison standard, compatible avec Keycloak, Auth0, Azure AD, etc.

Architecture cible (résumé)

  1. Clients (web/mobile) obtiennent un token OIDC (ID + access token) après SSO.
  2. Le backend (API ERP/assistant) valide le token via JWKS (issuer + audience).
  3. Middleware extrait claims : user_id, roles, tenant_id, scopes.
  4. RBAC applique règles métiers : ex. "sales" peut consulter, "admin" peut exécuter actions sensibles.
  5. Logs et métriques d’accès + quotas par tenant pour appels LLM.

Étape 1 — Choisir le modèle multitenant d’auth

Deux approches courantes :

  • Un fournisseur d’identité central (un issuer) qui contient tous les utilisateurs et inclut claim tenant_id dans le token. Simple à gérer côté API.
  • Un issuer par tenant (chaque client a son IdP). Plus isolé mais nécessite mapping dynamique des issuers et configuration JWKS par tenant.

Choisissez la première si vous voulez une intégration centralisée ; la seconde si vous avez des contraintes fortes d’isolation réglementaire.

Étape 2 — Flux OIDC essentiel

  1. Client redirige l’utilisateur vers l’IdP (Auth code flow).
  2. IdP renvoie code → client échange contre tokens (ID + access token).
  3. Client appelle API en mettant l’access token dans Authorization: Bearer <token>.
  4. API vérifie signature via JWKS, valide issuer/audience/exp, extrait claims.

Pour la spécification OIDC : OpenID Connect (spec).

Étape 3 — Exemple Node.js / Express : vérification JWT via JWKS

Exemple minimal (CommonJS) — installer : npm i express jsonwebtoken jwks-rsa.

// auth-middleware.js
const express = require('express');
const jwt = require('jsonwebtoken');
const jwksClient = require('jwks-rsa');

const jwksUri = process.env.JWKS_URI; // ex: https://idp.example.com/.well-known/jwks.json
const issuer = process.env.ISSUER;
const audience = process.env.AUDIENCE;

const client = jwksClient({ jwksUri, cache: true, cacheMaxEntries: 5, cacheMaxAge: 3600000 });

function getKey(header, callback) {
  client.getSigningKey(header.kid, (err, key) => {
    if (err) return callback(err);
    const pubKey = key.getPublicKey();
    callback(null, pubKey);
  });
}

async function verifyToken(req, res, next) {
  try {
    const auth = req.headers.authorization || '';
    const token = auth.split(' ')[1];
    if (!token) return res.status(401).json({ error: 'token-missing' });

    jwt.verify(token, getKey, { issuer, audience }, (err, decoded) => {
      if (err) return res.status(401).json({ error: 'invalid-token', details: err.message });
      req.user = decoded; // claims: sub, roles, tenant_id, scope, exp...
      next();
    });
  } catch (e) {
    next(e);
  }
}

module.exports = { verifyToken };

Étape 4 — RBAC : modèle simple et middleware

Modèle : map roles → permissions (action strings). Le token contient généralement un champ roles ou realm_access.roles.

// rbac.js
const rolePermissions = {
  admin: ['assistant:use', 'assistant:train', 'data:export'],
  manager: ['assistant:use', 'report:view'],
  sales: ['assistant:use']
};

function requirePermission(permission) {
  return (req, res, next) => {
    const roles = req.user?.roles || req.user?.realm_access?.roles || [];
    const perms = new Set(roles.flatMap(r => rolePermissions[r] || []));
    if (perms.has(permission)) return next();
    return res.status(403).json({ error: 'forbidden' });
  };
}

module.exports = { requirePermission };

Exemple d’usage :

app.post('/assistant/query', verifyToken, requirePermission('assistant:use'), async (req, res) => {
  // vérifier tenant match
  const tokenTenant = req.user.tenant_id;
  const resourceTenant = req.body.tenant_id || req.params.tenant;
  if (tokenTenant !== resourceTenant) return res.status(403).json({ error: 'tenant-mismatch' });

  // appel LLM, logging, etc.
});

Étape 5 — Cas pratiques et erreurs fréquentes

ProblèmeSymptômesSolution
Token non valide 401, message signature invalid Vérifier JWKS_URI, issuer et audience ; valider le kid présent dans l’en-tête du JWT
Expiration / clock skew token expired Autoriser skew serveur (p.ex. 60s) ou synchroniser NTP ; implémenter refresh token côté client
Tenant mismatch 403 lors d’accès inter-tenant Inclure claim tenant_id dans le token ou prévoir mapping issuers → tenant

Bonnes pratiques perf & sécurité

  • Cachez les clés JWKS (headers cache-control et côté client lib) pour réduire latence.
  • Validez issuer + audience + exp + nbf + iat ; n’acceptez pas de tokens scannés.
  • Ne stockez pas d’informations sensibles dans les claims. Stockez uniquement les IDs et récupérez données sensibles côté backend.
  • Utilisez HTTPS partout ; forcez HSTS et CSP côté frontend.
  • Tracez les appels de l’assistant : user, tenant, prompt, coût LLM estimé. Cela permet facturation/alerte.
  • Prévoyez des quotas et throttling par tenant pour les appels LLM (ex: 1000 requêtes/jour) afin d’éviter les abus.
  • Rotation des clés et plans de secours : mettez en place une procédure pour rotation et révocation des tokens.

Surveillance et observabilité

Exposez métriques : nombre de tokens validés, erreurs 401/403, latence JWT verify, consommation LLM par tenant. Intégrez alerting sur hausse anormale d’appels ou erreurs d’authentification.

Extensions utiles

  • Scopes dynamiques pour limiter l’accès à certaines fonctions de l’assistant (ex. scope=assistant.write pour actions modifiant les données).
  • Claims personnalisés pour feature flags par utilisateur (ex. beta_assistant:true).
  • Mapping roles → policies stocké dans la DB si les règles sont dynamiques (pratique pour grands clients).

Ressources

  • Spec OIDC : openid.net.
  • Pour déployer un IdP open source : consultez la documentation officielle de Keycloak (exemples de configuration JWKS et clients OIDC). Keycloak docs.

Liens internes

Conclusion : une authentification OIDC solide combinée à un RBAC bien conçu protège vos données et permet d’exposer en toute confiance des fonctionnalités IA dans votre ERP/CRM. L’essentiel : valider signatures + claims, vérifier le matching tenant, et appliquer des permissions fines côté API.

Besoin d’un audit ou d’une intégration sécurisée pour votre assistant IA ? Contactez-nous ou obtenez un devis.