authentification et isolation des données pour un assistant IA multitenant dans un SaaS : guide technique pour CTO et lead dev
07/06/2026
authentification et isolation des données pour un assistant IA multitenant dans un SaaS
Pour qui : CTO et lead dev d’un SaaS qui veut intégrer un assistant IA accessible par plusieurs clients (tenants) sans risquer de fuites de données. Objectif : à la fin vous saurez concevoir l’authentification, la propagation du contexte tenant jusqu’à la base de données, et appliquer l’isolation (RLS ou schéma dédié) avec exemples concrets en Node.js + PostgreSQL.
Pourquoi c’est critique
Un assistant IA peut manipuler des données sensibles (commandes, factures, notes client). Dans un environnement multitenant, une erreur d’isolation ou d’authentification suffit à exposer des données d’un client à un autre. Les deux piliers à garantir sont :
- authentification et identité (qui est l'utilisateur / quel tenant) ;
- isolation des données (même si un token est compromis, limiter l blast radius).
Vue d’ensemble de la solution
- Authentifier l’utilisateur / service (OAuth2 / OpenID Connect recommandé).
- Émettre un JWT contenant l'ID du tenant et rôles (sub, tenant_id, roles).
- Au service API, valider le token, extraire tenant_id et appliquer RBAC.
- Propager le tenant_id au niveau de la session DB (SET / set_config) ou utiliser une connexion dédiée par tenant.
- Activer Row Level Security (RLS) sur les tables critiques ou choisir schema-per-tenant si besoin d’isolement physique.
1) Authentification : bonnes pratiques
- Utilisez OAuth2 / OpenID Connect plutôt qu’un JWT maison. Voir la doc OpenID Connect pour les bonnes pratiques : https://openid.net/connect/.
- Faites signer les tokens par un provider de confiance (Auth0, Keycloak, provider interne). Ne stockez jamais la clé signing dans le code.
- Incluez dans le JWT au minimum : sub (user id), tenant_id, exp, scopes/roles.
- Séparez les tokens utilisateur (user-level) et service-to-service (machine tokens) et appliquez des scopes restreints pour les appels à l’IA (ex : read:customer_data uniquement si nécessaire).
2) Exemple : middleware Node.js pour valider JWT et extraire tenant
// middleware.js (Express)
const jwt = require('jsonwebtoken'); // ou jose
const jwksClient = require('jwks-rsa'); // si JWKS
module.exports = function (req, res, next) {
const auth = req.headers.authorization;
if (!auth) return res.status(401).end();
const token = auth.split(' ')[1];
try {
// valider signature, issuer, aud selon votre provider
const payload = jwt.verify(token, PUBLIC_KEY_OR_VERIFIER_OPTIONS);
// contrôles supplémentaires
if (!payload.tenant_id) return res.status(403).send('tenant missing');
// attacher le contexte request
req.tenant = { id: payload.tenant_id, roles: payload.roles || [] };
req.user = { id: payload.sub };
next();
} catch (err) {
return res.status(401).send('invalid token');
}
};
Commentaire : remplacez jwt.verify par une vérification via JWKS si vous utilisez un provider OIDC. Faites des checks extra : issuer, audience, exp, et la présence du champ tenant_id.
3) Propagation du contexte tenant jusqu’à PostgreSQL
Deux approches communes :
- Shared schema + tenant_id sur chaque table + Row Level Security (RLS) — simple à déployer et scale horizontalement.
- Schema-per-tenant ou base-per-tenant — plus isolant, préférable pour clients très sensibles ou exigences réglementaires.
Exemple pratique : shared schema + RLS. Au moment d’exécuter une requête, on définit la variable de session PostgreSQL. Avec node-postgres :
// db-tenant.js
async function withTenantClient(pool, tenantId, work) {
const client = await pool.connect();
try {
// définir la variable de session utilisée par les policies RLS
await client.query("SELECT set_config('app.current_tenant', $1, true)", [String(tenantId)]);
return await work(client);
} finally {
client.release();
}
}
Ensuite, toutes les requêtes SQL s'exécutent avec cette variable session et RLS s'applique.
4) Exemple SQL : activer RLS et créer une policy
Exemple minimal — adaptez aux noms de table et types :
-- activer RLS
ALTER TABLE invoices ENABLE ROW LEVEL SECURITY;
-- policy qui autorise l'accès si tenant_id correspond à la variable session
CREATE POLICY invoices_tenant_isolation
ON invoices
USING (tenant_id = current_setting('app.current_tenant', true)::int);
Note : la fonction current_setting(name, true) retourne NULL si la variable n'existe pas, évitez d'exécuter des requêtes sans contexte tenant. Pour plus de détails sur RLS : PostgreSQL Row Level Security.
5) Pièges fréquents et solutions
- Session pooling (PgBouncer) et variables session : si vous utilisez PgBouncer en mode transaction pooling, les variables session sont réinitialisées entre transactions. Solution : utiliser session pooling ou définir la variable à chaque transaction. Voir la doc PgBouncer si applicable.
- Caching global sans tenant key (Redis, CDN) : incluez le tenant_id dans la clé de cache pour éviter de servir des réponses cross-tenant.
- Endpoints d’administration mal protégés : séparez les endpoints admin et appliquez RBAC stricte (vérifier role admin + tenant scope).
- Logs et traces : masquez ou redigez les données sensibles dans les logs ; n’écrivez pas de contenus clients bruts (prompts, réponses) sans consentement et policies.
- Tests d’intrusion : faites des tests de fuite de données (scénarios unitaires où user A tente d’accéder aux données de user B).
6) Performance et observabilité
Points à mesurer :
- latence d’authentification (token validation) ;
- délai pour set_config avant la requête DB ;
- impact RLS sur les plans d’exécution : vérifiez vos index sur tenant_id ;
- taux d’erreurs 403/401 et causes (token expired, tenant missing, policy reject).
Conseils :
- indexez tenant_id dans vos tables chaudes ;
- profiler les requêtes EXPLAIN ANALYZE sur les requêtes multi-tenant ;
- monitorer le pool de connexions pour éviter la saturation si vous créez beaucoup de sessions par tenant.
7) Sécurité complémentaire : chiffrement, minimisation et gouvernance
- chiffrez les données sensibles au repos et chiffrez les communications (TLS) entre services ;
- minimisez les scopes : l’assistant IA ne doit demander que les données strictement nécessaires ;
- auditez les accès et conservez journaux d’accès non modifiables (WORM) pour les opérations sensibles ;
- documentez la gouvernance des prompts et la rétention des données générées par l’IA.
8) Checklist de déploiement (rapide)
- Choisir modèle d’isolement : shared schema + RLS ou schema/base par tenant.
- Implémenter provider OIDC/OAuth2 et claims tenant_id.
- Mise en place middleware JWT côté API puis propagation via set_config en DB.
- Activer RLS sur tables sensibles et écrire policies.
- Tester scénarios d’escalade : token absent, token manipulé, cache global, pooling DB.
- Mettre en place monitoring et alerting pour fuites potentielles.
Liens internes utiles
- services SaaS chez Novane — pour pensée architecture et scalabilité.
- services intelligence artificielle — pour intégration d’assistants IA en production.
- technologie PostgreSQL — pour approfondir l’adaptation DB.
Conclusion : sécuriser un assistant IA multitenant ne se réduit pas à valider un JWT. Il faut une chaîne complète : identité fiable, propagation du tenant au niveau DB, politiques RLS ou isolement physique, et instrumentation pour détecter les erreurs. Commencez par un proof-of-concept (un endpoint, RLS activé sur une table, tests d’accès croisés) puis industrialisez en mesurant l’impact sur la latence et le coût.
Besoin d’un audit technique ou d’un prototype pour votre assistant IA multitenant ? Contactez-nous pour en discuter.

