La idea en 30 segundos
Multi-Tenant es un enfoque arquitectónico en el que un sistema de agentes atiende a muchos clientes, pero cada tenant (cliente individual) está aislado.
El aislamiento no debe existir solo en los datos. Es necesario en toda la cadena:
- contexto de Runtime;
- memoria y caché;
- accesos a herramientas;
- límites de presupuesto y rate limits;
- auditoría y trace.
Cuándo se necesita: cuando un servicio trabaja para muchos clientes, equipos o workspaces en infraestructura compartida.
Un LLM no debe determinar por sí solo el contexto tenant. El tenant debe resolverse por auth o routing, y el sistema debe aplicarlo de forma obligatoria en cada paso.
Problema
Sin aislamiento multi-tenant claro, el sistema funciona, pero los riesgos se vuelven críticos rápidamente.
Los agentes LLM aumentan el riesgo de fugas cross-tenant, porque una sola solicitud puede leer memoria, llamar herramientas y escribir datos en varios sistemas.
Fallos típicos:
- el contexto de un tenant aparece en la respuesta de otro;
- un tool call se ejecuta con credentials de otro tenant;
- memoria o caché se mezclan entre clientes;
- un tenant consume todo el presupuesto compartido (noisy neighbor);
- la auditoría no permite demostrar quién inició la acción.
En producción, esto significa fugas de datos, incidentes de seguridad y compliance complejo.
Solución
Agregar Multi-Tenant como frontera explícita de aislamiento (tenant boundary) entre Agent Runtime y todos los estados/acciones del sistema.
Esta frontera define:
- cómo se identifica el tenant;
- qué recursos están disponibles para ese tenant;
- qué límites se aplican específicamente a ese tenant;
- cómo se registra el contexto tenant en logs y traces.
Analogía: como cajas de seguridad en un banco.
El edificio es uno, pero solo el propietario accede a su caja.
Multi-Tenant permite igualmente una plataforma compartida sin mezclar acceso ni datos.
Cómo funciona Multi-Tenant
Multi-Tenant es una capa gobernada entre la solicitud de entrada y la ejecución de acciones que aísla de forma obligatoria cada ejecución por tenant_id.
Resumen del flujo completo: Identify → Isolate → Authorize → Execute → Audit
Identify
El sistema resuelve el tenant mediante auth token, org mapping o reglas de routing.
Isolate
Runtime, memoria, caché y contexto de presupuesto se vinculan a un tenant_id específico.
Authorize
La capa de policy verifica role, tenant scopes, allowlist y límites por tenant.
Execute
Las llamadas de herramientas se ejecutan solo con tenant-scoped credentials y recursos de ese tenant.
Audit
Cada paso crítico se registra con tenant_id, actor_id, reason_code, outcome.
Este ciclo permite escalar un servicio para muchos clientes sin mezcla cross-tenant.
En código se ve así
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"}
# Todo el contexto está ligado de forma estricta al 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
Cómo se ve durante la ejecución
Solicitud: "Actualiza el estado del pedido #918 y envía confirmación al cliente"
Step 1
Auth + Routing: resuelve tenant_id = tenant_acme
Multi-Tenant Boundary: establece contexto tenant y límites por tenant
Step 2
Agent Runtime: forma action
Policy: verifica role + tenant scopes + allowlist
Tool Execution: ejecuta la acción solo con credentials de tenant_acme
Step 3
Audit: guarda tenant_id, actor_id, action, outcome, reason_code
Runtime: devuelve resultado sin mezclar con otros clientes
Multi-Tenant no cambia la lógica del agente. La hace predecible y segura para un entorno multi-cliente.
Cuándo encaja y cuándo no
Multi-Tenant se necesita donde un sistema atiende a muchos clientes o equipos con accesos distintos.
Encaja
| Situación | Por qué Multi-Tenant encaja | |
|---|---|---|
| ✅ | Un servicio de agentes atiende a muchos clientes | La tenant boundary evita fugas cross-tenant de datos y accesos. |
| ✅ | Se necesitan distintos presupuestos, cuotas y policy rules para distintos tenants | Los límites por tenant protegen el sistema del efecto noisy-neighbor. |
| ✅ | Se requiere auditoría para seguridad y compliance | Logs y trace registran acciones con vinculación clara al tenant. |
No encaja
| Situación | Por qué Multi-Tenant no encaja | |
|---|---|---|
| ❌ | El sistema atiende solo a un cliente sin planes de escalar | Toda la envoltura multi-tenant puede ser complejidad innecesaria al inicio. |
| ❌ | Los datos y accesos ya están aislados físicamente por instalaciones separadas | En ese caso, una arquitectura single-tenant por instalación suele ser suficiente. |
En un escenario simple single-tenant, a veces basta un contexto básico:
result = runtime.run(request=request, tenant_id="default")
Problemas y fallos típicos
| Problema | Qué ocurre | Cómo prevenirlo |
|---|---|---|
| Credential bleed | Un tool call usa claves de otro tenant | Tenant-scoped credentials + prohibir clientes globales |
| Cache / memory bleed | La caché o memoria devuelve datos de otro tenant | Namespace key con tenant_id, aislamiento del store y casos de prueba de fuga |
| Noisy neighbor | Un tenant consume presupuesto compartido y degrada el servicio para otros | Per-tenant budgets, rate limits, cuotas y prioridades |
| Suplantación de contexto tenant | El sistema acepta tenant_id desde prompt o payload sin validar auth | El tenant se resuelve solo desde auth/routing, no desde el texto de solicitud al modelo |
| Auditoría incompleta | No se puede demostrar qué tenant inició una acción riesgosa | Campos obligatorios de auditoría: tenant_id, actor_id, action, reason_code, outcome |
| Operaciones de escritura repetidas | Un retry duplica una escritura o un cobro dentro del tenant | Idempotency keys y deduplicación para acciones de mutación |
La mayoría de incidentes multi-tenant no aparece en el modelo, sino en una frontera débil entre contexto y ejecución.
Cómo se combina con otros patrones
Multi-Tenant es una capa arquitectónica transversal que refuerza la seguridad y estabilidad de todo el sistema.
- Agent Runtime — Runtime ejecuta pasos, y Multi-Tenant define límites de contexto tenant en cada paso.
- Tool Execution Layer — cada
tool_calldebe ejecutarse con accesos tenant-scoped. - Memory Layer — memoria y caché deben aislarse por
tenant_id. - Policy Boundaries — policy rules se aplican considerando tenant, role y scopes.
- Orchestration Topologies — en flujos multi-agent, el contexto tenant debe pasar por todas las ramas.
- Hybrid Workflow Agent — los commits de workflow deben mantenerse dentro de recursos del tenant específico.
- Human-in-the-Loop Architecture — los pasos de approval también deben tener auditoría y accesos ligados al tenant.
- Containerizing Agents — los contenedores dan entorno estable, pero el aislamiento tenant lo garantiza específicamente la frontera Multi-Tenant.
En otras palabras:
- Multi-Tenant define de quién es esta acción y de quién es este contexto
- Otras capas arquitectónicas definen cómo se ejecuta esa acción
En resumen
Multi-Tenant:
- aísla datos, accesos y estado entre clientes
- aplica límites de presupuesto por tenant y rate limits
- vincula de forma obligatoria los tool calls a tenant-scoped credentials
- hace transparente la auditoría mediante tenant_id + reason_code
FAQ
Q: ¿Es suficiente con agregar tenant_id a la solicitud?
A: No. tenant_id debe aplicarse de forma obligatoria en Runtime, policy, tools, memoria, caché y auditoría.
Q: ¿Dónde ocurren con más frecuencia las fugas cross-tenant?
A: Normalmente en cachés, memoria y clientes globales para APIs externas.
Q: ¿Cómo migrar de forma segura de single-tenant a multi-tenant?
A: Empieza con tenant_id en auth/routing, luego aísla memoria/caché/tools, añade límites por tenant y auditoría, y solo entonces migra datos por fases.
Q: ¿Qué importa primero: presupuestos por tenant o policy por tenant?
A: Ambos importan. Policy protege accesos; presupuestos protegen contra noisy-neighbor y explosión de costos.
Que Sigue
La arquitectura multi-tenant empieza con aislamiento, pero no termina ahi. El siguiente paso es ver como mantener estabilidad bajo carga real:
- Memory Layer - como construir memoria tenant-scoped sin fugas entre clientes.
- Containerizing Agents - como asegurar ejecucion reproducible para cada tenant.
- Policy Boundaries - como separar permisos, roles y acciones riesgosas.
- Production Stack - como juntar todo en un modelo de produccion gestionado.