Multi-Tenant : Isoler les agents entre clients

Une couche architecturale gouvernée d'isolation des données tenant : contexte séparé, scoped credentials, limites par tenant et audit sans fuites cross-tenant.
Sur cette page
  1. L'idée en 30 secondes
  2. Problème
  3. Solution
  4. Comment fonctionne Multi-Tenant
  5. Dans le code, cela ressemble à ceci
  6. À quoi cela ressemble pendant l'exécution
  7. Quand c'est adapté et quand ça ne l'est pas
  8. Adapté
  9. Non adapté
  10. Problèmes et pannes typiques
  11. Comment cela se combine avec d'autres patterns
  12. En bref
  13. FAQ
  14. Et Ensuite

L'idée en 30 secondes

Multi-Tenant est une approche architecturale où un système d'agents sert de nombreux clients, mais chaque tenant (client individuel) est isolé.

L'isolation ne doit pas exister seulement dans les données. Elle est nécessaire sur toute la chaîne :

  • contexte Runtime ;
  • mémoire et cache ;
  • accès aux outils ;
  • limites de budget et rate limits ;
  • audit et trace.

Quand c'est nécessaire : quand un service fonctionne pour de nombreux clients, équipes ou workspaces dans une infrastructure partagée.

Un LLM ne doit pas déterminer seul le contexte tenant. Le tenant doit être résolu via auth ou routing, et le système doit l'appliquer de façon obligatoire à chaque étape.


Problème

Sans isolation multi-tenant claire, le système fonctionne, mais les risques deviennent vite critiques.

Les agents LLM augmentent le risque de fuites cross-tenant, car une seule requête peut lire la mémoire, appeler des outils et écrire des données dans plusieurs systèmes.

Pannes typiques :

  • le contexte d'un tenant apparaît dans la réponse d'un autre ;
  • un tool call s'exécute avec les credentials d'un autre tenant ;
  • mémoire ou cache sont mélangés entre clients ;
  • un tenant consomme tout le budget partagé (noisy neighbor) ;
  • l'audit ne permet pas de prouver qui a initié l'action.

En production, cela signifie fuites de données, incidents de sécurité et compliance complexe.

Solution

Ajouter Multi-Tenant comme frontière explicite d'isolation (tenant boundary) entre Agent Runtime et tous les états/actions du système.

Cette frontière définit :

  • comment le tenant est identifié ;
  • quelles ressources sont disponibles pour ce tenant ;
  • quelles limites s'appliquent spécifiquement à ce tenant ;
  • comment le contexte tenant est enregistré dans les logs et traces.

Analogie : comme des coffres-forts dans une banque.

Le bâtiment est unique, mais seul le propriétaire accède à son coffre.

Multi-Tenant permet de la même façon une plateforme partagée sans mélange des accès et des données.

Comment fonctionne Multi-Tenant

Multi-Tenant est une couche gouvernée entre la requête entrante et l'exécution des actions, qui isole de façon forcée chaque run par tenant_id.

Diagram
Vue d'ensemble du flux complet : Identify → Isolate → Authorize → Execute → Audit

Identify
Le système résout le tenant via auth token, org mapping ou règles de routing.

Isolate
Runtime, mémoire, cache et contexte budget sont liés à un tenant_id spécifique.

Authorize
La couche policy vérifie role, tenant scopes, allowlist et limites par tenant.

Execute
Les appels d'outils s'exécutent uniquement avec tenant-scoped credentials et les ressources de ce tenant.

Audit
Chaque étape critique est loggée avec tenant_id, actor_id, reason_code, outcome.

Ce cycle permet de scaler un service pour de nombreux clients sans mélange cross-tenant.

Dans le code, cela ressemble à ceci

PYTHON
class MultiTenantArchitecture:
    def __init__(self, auth, runtime, policy, tools, memory, budgets, audit):
        self.auth = auth
        self.runtime = runtime
        self.policy = policy
        self.tools = tools
        self.memory = memory
        self.budgets = budgets
        self.audit = audit

    def run(self, request, auth_token):
        identity = self.auth.resolve(auth_token) or {}
        tenant_id = identity.get("tenant_id")
        actor_id = identity.get("actor_id")
        if not tenant_id:
            return {"ok": False, "reason_code": "tenant_missing"}

        if not self.budgets.allowed(tenant_id=tenant_id):
            return {"ok": False, "reason_code": "tenant_budget_exceeded"}

        # Tout le contexte est strictement lié au tenant.
        state = self.runtime.start(request=request, tenant_id=tenant_id)
        memory_items = self.memory.retrieve(tenant_id=tenant_id, query=request["text"], top_k=4)
        action = self.runtime.decide(state=state, memory_items=memory_items)

        gate = self.policy.authorize(
            tenant_id=tenant_id,
            actor_id=actor_id,
            action=action,
        )
        if not gate["ok"]:
            self.audit.log(
                tenant_id=tenant_id,
                actor_id=actor_id,
                action=action.get("name"),
                outcome="denied",
                reason_code=gate.get("reason_code", "policy_denied"),
            )
            return {"ok": False, "reason_code": gate.get("reason_code", "policy_denied")}

        result = self.tools.execute(
            action=action,
            tenant_id=tenant_id,
            scopes=gate.get("scopes", []),
        )

        self.audit.log(
            tenant_id=tenant_id,
            actor_id=actor_id,
            action=action.get("name"),
            outcome="executed",
            reason_code=result.get("reason_code", "ok"),
        )
        return result

À quoi cela ressemble pendant l'exécution

TEXT
Requête : "Mets à jour le statut de la commande #918 et envoie une confirmation au client"

Step 1
Auth + Routing: résout tenant_id = tenant_acme
Multi-Tenant Boundary: définit le contexte tenant et les limites par tenant

Step 2
Agent Runtime: forme action
Policy: vérifie role + tenant scopes + allowlist
Tool Execution: exécute l'action uniquement avec les credentials de tenant_acme

Step 3
Audit: enregistre tenant_id, actor_id, action, outcome, reason_code
Runtime: renvoie le résultat sans mélange avec les autres clients

Multi-Tenant ne change pas la logique de l'agent. Il la rend prévisible et sûre pour un environnement multi-client.

Quand c'est adapté et quand ça ne l'est pas

Multi-Tenant est nécessaire là où un système sert de nombreux clients ou équipes avec des accès différents.

Adapté

SituationPourquoi Multi-Tenant est adapté
Un service d'agents sert de nombreux clientsLa tenant boundary empêche les fuites cross-tenant de données et d'accès.
Des budgets, quotas et policy rules différents sont nécessaires selon le tenantLes limites par tenant protègent le système contre l'effet noisy-neighbor.
Un audit est nécessaire pour la sécurité et la complianceLes logs et trace enregistrent les actions avec un lien clair au tenant.

Non adapté

SituationPourquoi Multi-Tenant n'est pas adapté
Le système sert un seul client sans plan de scalabilitéUn habillage multi-tenant complet peut être une complexité inutile au départ.
Les données et accès sont déjà isolés physiquement par installations séparéesDans ce cas, une architecture single-tenant par installation est souvent suffisante.

Dans un scénario simple single-tenant, un contexte de base suffit parfois :

PYTHON
result = runtime.run(request=request, tenant_id="default")

Problèmes et pannes typiques

ProblèmeCe qui se passeComment prévenir
Credential bleedUn tool call utilise les clés d'un autre tenantTenant-scoped credentials + interdiction des clients globaux
Cache / memory bleedLe cache ou la mémoire renvoie des données d'un autre tenantNamespace key avec tenant_id, isolation du store et cas de test de fuite
Noisy neighborUn tenant consomme le budget partagé et dégrade le service pour les autresPer-tenant budgets, rate limits, quotas et priorités
Usurpation du contexte tenantLe système accepte tenant_id depuis le prompt ou payload sans validation authLe tenant est résolu uniquement depuis auth/routing, pas depuis le texte de requête du modèle
Audit incompletImpossible de prouver quel tenant a initié une action risquéeChamps d'audit obligatoires : tenant_id, actor_id, action, reason_code, outcome
Opérations d'écriture répétéesUn retry duplique une écriture ou un débit dans le tenantIdempotency keys et déduplication pour les actions de mutation

La plupart des incidents multi-tenant ne viennent pas du modèle, mais d'une frontière faible entre contexte et exécution.

Comment cela se combine avec d'autres patterns

Multi-Tenant est une couche architecturale transverse qui renforce la sécurité et la stabilité de tout le système.

  • Agent Runtime — Runtime exécute les étapes, et Multi-Tenant fixe des frontières de contexte tenant à chaque étape.
  • Tool Execution Layer — chaque tool_call doit s'exécuter avec des accès tenant-scoped.
  • Memory Layer — mémoire et cache doivent être isolés par tenant_id.
  • Policy Boundaries — policy rules s'appliquent en tenant compte de tenant, role et scopes.
  • Orchestration Topologies — dans les flows multi-agent, le contexte tenant doit passer dans toutes les branches.
  • Hybrid Workflow Agent — les commits workflow doivent rester dans les ressources du tenant spécifique.
  • Human-in-the-Loop Architecture — les étapes d'approval doivent aussi avoir audit et accès liés au tenant.
  • Containerizing Agents — les conteneurs donnent un environnement stable, mais l'isolation tenant est assurée spécifiquement par la frontière Multi-Tenant.

Autrement dit :

  • Multi-Tenant définit à qui appartient cette action et ce contexte
  • Les autres couches d'architecture définissent comment cette action est exécutée

En bref

En bref

Multi-Tenant:

  • isole les données, accès et state entre clients
  • applique des limites de budget par tenant et des rate limits
  • lie de façon obligatoire les tool calls à des tenant-scoped credentials
  • rend l'audit transparent via tenant_id + reason_code

FAQ

Q: Est-ce suffisant d'ajouter simplement tenant_id à la requête ?
A: Non. tenant_id doit être imposé à travers Runtime, policy, tools, mémoire, cache et audit.

Q: Où arrivent le plus souvent les fuites cross-tenant ?
A: Le plus souvent dans les caches, la mémoire et les clients globaux pour APIs externes.

Q: Comment migrer en sécurité de single-tenant vers multi-tenant ?
A: Commencer avec tenant_id dans auth/routing, puis isoler mémoire/cache/tools, ajouter limites par tenant et audit, et seulement ensuite migrer les données par étapes.

Q: Qu'est-ce qui est prioritaire : budgets par tenant ou policy par tenant ?
A: Les deux sont importants. Policy protège les accès, les budgets protègent contre noisy-neighbor et l'explosion des coûts.

Et Ensuite

L architecture multi-tenant commence par l isolation, mais ne s arrete pas la. Ensuite, regardez comment garder la stabilite sous charge reelle:

  • Memory Layer - comment construire une memoire tenant-scoped sans fuite entre clients.
  • Containerizing Agents - comment garantir une execution reproductible pour chaque tenant.
  • Policy Boundaries - comment separer permissions, roles et actions a risque.
  • Production Stack - comment assembler tout cela en modele production maitrise.
⏱️ 9 min de lectureMis à jour 8 mars 2026Difficulté: ★★★
Intégré : contrôle en productionOnceOnly
Ajoutez des garde-fous aux agents tool-calling
Livrez ce pattern avec de la gouvernance :
  • Budgets (steps / plafonds de coût)
  • Permissions outils (allowlist / blocklist)
  • Kill switch & arrêt incident
  • Idempotence & déduplication
  • Audit logs & traçabilité
Mention intégrée : OnceOnly est une couche de contrôle pour des systèmes d’agents en prod.

Auteur

Nick — ingénieur qui construit une infrastructure pour des agents IA en production.

Focus : patterns d’agents, modes de défaillance, contrôle du runtime et fiabilité des systèmes.

🔗 GitHub: https://github.com/mykolademyanov


Note éditoriale

Cette documentation est assistée par l’IA, avec une responsabilité éditoriale humaine pour l’exactitude, la clarté et la pertinence en production.

Le contenu s’appuie sur des défaillances réelles, des post-mortems et des incidents opérationnels dans des systèmes d’agents IA déployés.