Pourquoi ce module
Un prototype qui marche chez un client ne tient pas chez dix. Ce module couvre ce qui sépare la démonstration de la production d'entreprise : l'isolation des clients, l'authentification, la limitation de débit, la conformité, et le bouton d'arrêt.
Ce sont des questions que posent les architectes et les RSSI, pas les utilisateurs — et ce sont elles qui décident si le projet passe en production.
Objectifs pédagogiques
- Comparer les modèles de tenancy et leurs compromis
- Justifier où s'applique un filtre d'isolation et pourquoi pas ailleurs
- Concevoir un système de jetons machine et justifier chaque choix
- Dimensionner une limitation de débit sur la bonne ressource
- Décrire un kill switch et ce qu'il doit couper
- Situer les exigences de conformité qui pèsent sur l'architecture
Plan détaillé
- Les modèles de tenancy
- Où s'applique le filtre d'isolation
- Authentification machine
- Limitation de débit
- Kill switch et réversibilité
- Conformité et souveraineté
- Les questions que pose une équipe sécurité
- Glossaire du module
1. Les modèles de tenancy
Chargement du schéma…
| Modèle | Isolation | Coût | Quand |
|---|---|---|---|
| Silo | Maximale — rien n'est partagé | Élevé, croît linéairement | Exigence réglementaire, données très sensibles |
| Pool | Logique — un filtre dans les requêtes | Faible | Le cas courant en SaaS |
| Bridge | Données isolées, code partagé | Intermédiaire | Compromis fréquent chez les grands comptes |
🎯 Le point qui compte en entretien. « En pool, l'isolation repose entièrement sur la correction du code. Un
WHERE tenant_idoublié une seule fois dans une seule requête, et c'est une fuite inter-clients. C'est pour ça qu'on ne la laisse pas à la discipline : on la met dans une couche que le code métier ne peut pas contourner, et on la verrouille par un test. »
2. Où s'applique le filtre d'isolation
Question précise, réponse précise — et c'est une erreur qu'on voit en production.
Chargement du schéma…
Le filtre s'applique dans la définition de la portée, donc avant la fusion. Filtrer après laisserait fuiter une métadonnée : le simple fait que des documents d'un autre tenant aient occupé des rangs dans le classement modifie le résultat visible. Un attaquant peut en déduire l'existence, et parfois la nature, de documents auxquels il n'a pas accès.
💡 Une fuite de métadonnée reste une fuite. C'est la phrase à retenir. On ne juge pas une isolation sur ce qu'elle laisse lire, mais sur ce qu'elle laisse déduire.
Et la vérification ? On ne se fie pas à la relecture. On monte deux jetons, deux organisations, le même serveur, et on pose la même question sur le même équipement :
| Jeton | Liste d'équipements | Recherche documentaire |
|---|---|---|
| Client propriétaire du corpus | 3 équipements, 484 passages | 2 passages du manuel |
| Autre client | « aucun équipement indexé » | 0 passage |
C'est un test d'isolation, pas un test fonctionnel — et c'est ce genre de preuve qu'un RSSI demande.
3. Authentification machine
Un agent n'a pas de navigateur, donc pas de session de connexion. Il porte un jeton.
Les choix de conception à savoir justifier, chacun ayant une raison précise :
| Choix | Raison |
|---|---|
| La base ne stocke que le SHA-256 du jeton | Une fuite de la base ne donne aucun accès. Contrepartie : un jeton perdu ne se récupère pas, il se réémet |
| Le jeton n'est affiché qu'une fois, à l'émission | Conséquence directe du point précédent |
expires_at non nul, obligatoire | Un jeton machine sans échéance finit dans un dépôt Git et n'expire jamais |
| Révocation effective au premier appel suivant | La vérification lit la base à chaque requête, donc pas de redémarrage ni de cache à invalider |
| Des scopes, même avec un seul usage aujourd'hui | Un futur outil d'écriture n'obligera pas à réémettre tous les jetons existants |
⚠️ Le partage des responsabilités avec le SDK. Les SDK MCP sont explicites : le gestionnaire de requêtes est strictement passe-plat, il ne remplit jamais l'information d'authentification depuis les en-têtes et ne vérifie aucun jeton lui-même. La vérification incombe au serveur, en amont. Croire que le SDK authentifie est une erreur de lecture qui laisse un serveur ouvert.
4. Limitation de débit
La question à se poser en premier n'est pas « quelle limite ? » mais « qu'est-ce qu'on protège ? »
🎯 Le raisonnement complet. « Ce qu'on protège n'est pas la machine : la base encaisse sans peine ce qu'un agent peut demander. On protège le quota du fournisseur d'embeddings, qui est partagé entre tous les clients — même projet pour toute l'installation. »
Ce déplacement de la question entraîne trois conséquences, et les énoncer fait la différence :
1. Deux compteurs, pas un.
| Portée | Rôle |
|---|---|
| Par jeton | Un client compromis ou en boucle ne pénalise que lui |
| Global | Dix clients sages, chacun sous sa limite, épuiseraient quand même le quota commun |
2. Une limitation par coût, pas par appel. Tous les appels ne se valent pas : une recherche consomme un embedding, une simple lecture ne touche que la base. Les compter pareil obligerait à caler la limite sur le plus cher, donc à brider inutilement les appels bon marché.
3. Les compteurs vivent en base, pas en mémoire. Un compteur par processus donnerait deux fois la limite derrière un répartiteur de charge, et repartirait de zéro à chaque redémarrage. L'incrément doit être atomique, en un seul aller-retour.
Deux règles de comportement, contre-intuitives et excellentes en entretien :
Un appel refusé consomme son propre jeton de compteur. Sinon la boucle qu'on veut arrêter obtiendrait un quota gratuit de refus et tournerait indéfiniment.
Si les compteurs sont indisponibles, l'appel passe. Une limitation qui coupe le service quand la base hoquette est pire que le problème qu'elle traite — et si la base est injoignable, la recherche échoue de toute façon.
5. Kill switch et réversibilité
Tout grand compte demande : « comment on l'arrête ? » La réponse doit être précise.
Chargement du schéma…
Les propriétés attendues : granularité (par tenant et par fonctionnalité, pas seulement global), effet sans redéploiement, et surtout testé. Un interrupteur jamais actionné est un interrupteur dont on ignore l'état.
La question de suivi est toujours la même : « et le système continue de fonctionner en mode dégradé, ou il s'arrête ? » Les deux réponses sont défendables, mais il faut avoir choisi et documenté : sur un RAG documentaire, revenir à la recherche sans génération est souvent plus utile qu'une page d'erreur.
6. Conformité et souveraineté
Ce qui pèse réellement sur l'architecture, dans l'ordre où ça se pose :
| Exigence | Effet sur l'architecture |
|---|---|
| Localisation des données | Choix de région, parfois du fournisseur ; peut interdire une API hors zone |
| Pas d'entraînement sur nos données | Exige une garantie contractuelle du fournisseur, à obtenir avant de promettre |
| Journal d'audit | Qui a demandé quoi, quand, avec quelle autorité effective — à concevoir dès le départ |
| Droit à l'effacement (RGPD) | Effacer une donnée d'un index vectoriel n'est pas trivial : prévoir la ré-indexation ciblée |
| On-premise | Change tout : modèle auto-hébergé, pas d'API externe, performances différentes |
| AI Act (UE) | Selon la classification du système, obligations de transparence et de documentation |
💡 Le réflexe FDE. Ces exigences ne se découvrent pas à la mise en production — elles se posent en discovery (module F8). Un système conçu sans savoir que les données ne peuvent pas sortir de l'Union est un système à refaire. La question « où vivent vos données, et qu'est-ce qui a le droit d'en sortir ? » fait partie du premier entretien client, pas du dernier.
7. Les questions que pose une équipe sécurité
7.1 Le triptyque du RSSI
Trois questions reviennent, et un FDE crédible y répond avant qu'on les pose :
- « Qui possède le harnais d'évaluation quand votre ingénieur repart ? »
- « Les accès de l'agent se distinguent-ils de ceux d'un humain ? »
- « Le client peut-il couper en 5 minutes, seul ? »
La première est la plus aiguë, parce qu'elle décide de tout le reste : sans le harnais, l'équipe cliente ne peut ni vérifier une modification, ni détecter une dégradation. Un système transféré sans son instrument de mesure est un système qu'on ne peut plus faire évoluer sans risque.
7.2 L'agent doit avoir sa propre identité
Donner à un agent les identifiants d'un cadre senior — parce que c'est plus simple, parce qu'il a déjà tous les accès — est une faille déguisée en confort.
Donner à l'agent sa propre identité de service, au périmètre minimal. Et l'attribution compte autant que le périmètre : après incident, il faut pouvoir distinguer l'agent de l'humain dans les journaux.
Un agent qui agit sous l'identité d'une personne rend toute enquête impossible — et expose cette personne à répondre d'actions qu'elle n'a pas faites.
7.3 SHA-256 sans sel : jusqu'où l'argument tient
On stocke le SHA-256 d'un jeton d'API sans sel par jeton, et c'est correct — parce qu'un jeton machine est aléatoire et à forte entropie : il n'existe pas de dictionnaire à précalculer, donc le sel n'apporte rien.
Le raisonnement ne se transpose pas aux mots de passe choisis par un humain, à faible entropie, qui exigent une fonction de dérivation lente et salée (bcrypt, argon2).
Savoir où l'argument s'arrête est l'essentiel. Un candidat qui généralise « le hachage sans sel, c'est bien » donne une mauvaise réponse ; celui qui pose la frontière donne la bonne.
7.4 Le message d'authentification indifférencié
Un échec d'authentification renvoie un message unique, jamais « jeton expiré » vs « jeton inconnu ».
Fuite d'oracle classique. Distinguer les deux permet à un attaquant de savoir qu'un jeton a existé. Même raisonnement que ne pas distinguer « mauvais mot de passe » de « utilisateur inconnu » sur un formulaire de connexion.
7.5 Le titulaire change d'employeur
Le jeton est valide, la personne n'est plus dans l'organisation. Que doit imposer la requête d'autorisation ?
Vérifier l'appartenance dans la même requête SQL que la résolution du jeton. Cela supprime toute fenêtre où un identifiant d'organisation serait lu avant que sa validité soit établie.
La formulation à retenir : un changement d'employeur invalide l'accès, il ne le fige pas. Un jeton résolu en deux temps laisse un intervalle exploitable.
7.6 Le cache de jeton : un arbitrage, pas une optimisation
Mettre en cache les lookups de jeton 60 secondes pour soulager la base :
Ce que vous avez cédé : la révocation prend désormais effet en 60 secondes, pas au premier appel suivant. C'est peut-être un arbitrage acceptable — mais c'en est un, et une équipe sécurité en demandera le chiffre.
« La révocation prend effet au premier appel suivant » est une propriété qu'il faut pouvoir énoncer précisément. Dès qu'on cache, elle change, et il faut le dire spontanément.
7.7 Pourquoi le député confus est de la même classe qu'une SSRF
C'est le rapprochement qui fait comprendre le problème à un architecte :
En SSRF, le serveur va chercher une URL choisie par l'attaquant. Ici, le modèle appelle un outil avec des arguments influencés par le corpus. Même forme, même correctif : la frontière de privilège ne doit pas dériver d'une entrée atteignable par l'attaquant.
C'est la reformulation générale de l'invariant du module F3 — et elle a l'avantage de parler à quelqu'un qui ne connaît rien aux LLM mais tout à la sécurité applicative.
8. Trois mises en situation
8.1 Déploiement en cloud privé, du premier rendez-vous à la production
On ne répond pas oui ou non. On recadre la question : pas « est-ce qu'on peut aller dans le cloud », mais « quelles parties doivent vraiment rester dedans ».
- Cartographier ce qui doit réellement rester à l'intérieur. Souvent, ce n'est pas tout : les embeddings de documents publics constructeur n'ont pas le même statut que les données d'exploitation.
- Rencontrer les détenteurs du veto tôt — RSSI, DPO, équipe plateforme — et pas au comité de validation final.
- Expliquer pourquoi le moment du veto change son coût : un RSSI consulté en semaine 2 pose ses conditions ; le même en semaine 12 découvre un fait accompli et bloque.
- Éléments techniques concrets : contrôle d'egress, résidence des données, identité de service dédiée.
- Pilote étroit, résultat mesuré sous 30 jours.
- Coupe-circuit répété par le client lui-même avant la mise en production — pas démontré par vous, actionné par eux.
🎯 La relance : « leur équipe plateforme a six semaines de délai pour toute nouveauté. » — Alors la demande d'infrastructure part en semaine 1, avant même le cadrage fonctionnel, et le pilote se conçoit sur ce qui existe déjà. Le délai n'est pas un obstacle, c'est une contrainte d'ordonnancement — à condition de la découvrir tôt.
8.2 Le périmètre d'un test d'intrusion sur un système IA
On accueille le test, et on oriente le périmètre — un pentest mal cadré teste le spectaculaire et rate le structurel.
Dans le périmètre, par ordre d'importance :
- Injection indirecte via le corpus — le vecteur principal (cf. F5)
- Isolation entre tenants, y compris les chemins influencés par le modèle
- Surface d'outils : arguments hostiles, valeurs hors domaine
- Existence d'un canal d'exfiltration — que peut émettre l'agent ?
- Disponibilité des filtres eux-mêmes — ReDoS sur les détecteurs
À déprioriser, en le disant : le jailbreak spectacle — faire dire une grossièreté au modèle. C'est visible, ça fait un bon rapport, et ça ne correspond à aucun risque métier dans un RAG documentaire.
🎯 La relance qui compte : « ils ne trouvent rien. Est-ce que ça veut dire que c'est sûr ? » — Non. Ça veut dire que ce périmètre-là, testé par ces gens-là, à cette date-là, n'a rien donné. Un pentest est un échantillon, pas une preuve. La réponse honnête cite ce qui n'a pas été testé.
8.3 Deux tenants qui sont des concurrents directs
Ce qui change n'est pas l'invariant — c'est la conséquence.
On passe du meilleur effort au démontrable. Une fuite entre deux clients quelconques est un incident ; entre deux concurrents directs, c'est un contentieux.
Concrètement, le même invariant imposé à plus d'une couche :
- Filtrage avant récupération, et imposé au niveau de la base — pas seulement dans le code applicatif
- Tout nouveau chemin de requête doit échouer en fermé : absence de tenant résolu = refus, jamais « tous »
- Test sur les schémas publiés pour protéger l'invariant dans la durée (cf. F3)
- Traces séparées par tenant — y compris le stockage d'observabilité
💡 Le point de maturité : énoncer le risque résiduel au lieu de prétendre à zéro. « Voici les trois couches, voici ce qui les vérifie, et voici le scénario qui les traverserait toutes — il suppose X et Y simultanément, et voici comment on le détecterait. » Un fournisseur qui promet zéro risque est un fournisseur qui n'a pas cherché.
La relance : « un tenant exige une infrastructure physiquement séparée. Raisonnable ? » — Oui, c'est le modèle silo (§ 1). Ce n'est pas une défiance envers votre code, c'est une exigence dont le coût est connu. On chiffre et on laisse arbitrer.
9. Glossaire du module
| Terme (EN) | Terme (FR) | Définition |
|---|---|---|
| Tenancy | Modèle locatif | Façon dont plusieurs clients partagent un système |
| Silo / Pool / Bridge | — | Isolation totale / partagée / mixte |
| Tenant isolation | Isolation des clients | Garantie qu'un client n'accède qu'à ses données |
| Metadata leak | Fuite de métadonnée | Divulgation de l'existence d'une donnée sans son contenu |
| Bearer token | Jeton porteur | Jeton d'authentification porté par la requête |
| Scope | Portée, périmètre | Ensemble des droits attachés à un jeton |
| Revocation | Révocation | Invalidation d'un jeton avant son échéance |
| Rate limiting | Limitation de débit | Plafonnement du nombre d'appels par période |
| Fixed / sliding window | Fenêtre fixe / glissante | Deux façons de compter ; la fixe autorise 2× la limite à cheval sur une frontière |
| Fail open / fail closed | Défaillance ouverte / fermée | Laisser passer ou bloquer quand le contrôle est indisponible |
| Kill switch | Coupe-circuit | Arrêt immédiat, granulaire, sans redéploiement |
| Graceful degradation | Dégradation maîtrisée | Continuer en mode réduit plutôt que s'arrêter |
| Data residency | Localisation des données | Contrainte sur le lieu de stockage et de traitement |
| Audit trail | Journal d'audit | Trace opposable de qui a fait quoi, quand |
| SSRF | — | Server-Side Request Forgery ; même classe que le député confus |
| Service identity | Identité de service | Identité propre à l'agent, distincte de celle d'un humain |
| Oracle leak | Fuite d'oracle | Message d'erreur différencié révélant l'existence d'une ressource |
| KDF | Fonction de dérivation de clé | bcrypt/argon2 ; requise pour les secrets à faible entropie, pas pour un jeton aléatoire |
Atelier (75 min)
- Le filtre au bon endroit (20 min) — expliquez pourquoi filtrer après la fusion est une faille, en aboutissant à « une fuite de métadonnée reste une fuite ». En anglais.
- Les cinq choix de jetons (20 min) — justifiez chacun. Puis la relance : « pourquoi ne pas stocker le jeton en clair pour pouvoir le réafficher ? »
- Qu'est-ce qu'on protège (20 min) — déroulez le raisonnement complet de la limitation de débit, jusqu'aux deux règles contre-intuitives.
- Le kill switch (15 min) — décrivez le vôtre, avec sa granularité, et répondez à « mode dégradé ou arrêt ? »
Pour aller plus loin
- 🎯 Parcours : F6 — Observabilité & coût ← → F8 — Discovery client
- 📚 Approfondissement : M1 — AI Act EU + RGPD et M7 — MCP OAuth
- 🛠 Entraînement : thème
deployment_enterprisede la banquefransys-fde— 12 QCM