AgentChat
← Todos los artículos
Seguridad·10 min de lectura

Cómo ofrecer a cada usuario de una aplicación SaaS un agente de IA seguro y consciente del inquilino

Usa encabezados por chat y tu capa de autorización existente para mantener aisladas las acciones del agente por usuario, espacio de trabajo o inquilino.

Este caso práctico integra AgentChat en un SaaS de gestión de proyectos multiinquilino llamado ProjectDesk. Todos los clientes utilizan las mismas API de proyectos y tareas, pero la usuaria Alice solo puede actuar en workspace_a y el usuario Bob solo en workspace_b. Reutilizaremos un único documento de API y crearemos dos sesiones con diferentes encabezados de solicitud de solo escritura.

El límite de seguridad no es un prompt que pida al modelo permanecer dentro de un espacio de trabajo. ProjectDesk autentica y autoriza cada solicitud de herramienta HTTP. AgentChat selecciona las operaciones e inyecta la credencial de sesión correcta; ProjectDesk decide si cada operación está permitida.

Paso 1: hacer que la API de negocio tenga en cuenta al inquilino

GET /v1/projects?status=active
→ { "items": [{ "project_id": "proj_12", "name": "Website launch", "role": "editor" }] }

POST /v1/projects/proj_12/tasks
{ "title": "Review launch checklist", "due_at": "2026-08-28" }
→ { "task_id": "task_91", "project_id": "proj_12", "status": "open" }

ProjectDesk verifica el token de tipo bearer, deriva la identidad del usuario, confirma su pertenencia al espacio de trabajo indicado por X-Workspace-ID y añade ese espacio de trabajo a cada consulta de la base de datos. Un ID de proyecto por sí solo nunca omite el filtro de inquilino. Los permisos de lectura y escritura se comprueban por separado.

Paso 2: registrar un documento reutilizable de ProjectDesk

POST $AGENTCHAT_SITE_URL/api/api-documents
Authorization: Bearer ac_live_AGENTCHAT_KEY
Content-Type: application/json

{
  "title": "ProjectDesk Projects and Tasks",
  "description": "List authorized projects and create tasks inside them.",
  "content": "# ProjectDesk API\nBase URL: https://projects.example.com/v1\n\nGET /projects?status=active returns only projects visible to the authenticated workspace member. Response items contain project_id, name, and role.\n\nPOST /projects/{project_id}/tasks body: title required, due_at optional ISO date. Create only after resolving a project through GET /projects. Response contains task_id, project_id, and status.\n\n401 means the session credential is missing or expired. 403 means the current member lacks permission. On either response, do not retry and tell the user that the chat credential or role must be updated."
}

Este documento describe una capacidad, no una identidad. ProjectDesk guarda una sola vez el UUID del documento devuelto y lo adjunta a los chats de cada inquilino. El documento no incluye ningún ID de inquilino, token de usuario ni secreto.

Paso 3: crear la sesión de AgentChat de Alice

POST $AGENTCHAT_SITE_URL/api/agent/sessions
Authorization: Bearer ac_live_AGENTCHAT_KEY
Content-Type: application/json

{
  "title": "ProjectDesk assistant — Alice",
  "llm_config_id": "llm_config_uuid",
  "api_document_ids": ["projectdesk_document_uuid"],
  "system_prompt": "Help the current member manage projects. Never infer access from names; rely on API results.",
  "max_turns": 10,
  "host_headers": [
    { "host": "projects.example.com", "header_key": "Authorization", "header_value": "Bearer alice_short_lived_token" },
    { "host": "projects.example.com", "header_key": "X-Workspace-ID", "header_value": "workspace_a" }
  ]
}

La respuesta de la sesión incluye la configuración habitual, pero nunca devuelve header_value. AgentChat puede inyectar el token de Alice en una solicitud HTTP coincidente, mientras que el modelo no puede ver ni el token ni el encabezado de autorización almacenado.

Paso 4: crear la sesión de Bob a partir del mismo documento

POST $AGENTCHAT_SITE_URL/api/agent/sessions
Authorization: Bearer ac_live_AGENTCHAT_KEY
Content-Type: application/json

{
  "title": "ProjectDesk assistant — Bob",
  "llm_config_id": "llm_config_uuid",
  "api_document_ids": ["projectdesk_document_uuid"],
  "system_prompt": "Help the current member manage projects. Never infer access from names; rely on API results.",
  "max_turns": 10,
  "host_headers": [
    { "host": "projects.example.com", "header_key": "Authorization", "header_value": "Bearer bob_short_lived_token" },
    { "host": "projects.example.com", "header_key": "X-Workspace-ID", "header_value": "workspace_b" }
  ]
}

El contrato de la API y la configuración del modelo se pueden compartir, mientras que los encabezados de sesión identifican al autor de la llamada en cada conversación. Esto evita generar documentos duplicados para cada cliente y mantiene la rotación de credenciales independiente de la documentación de capacidades.

Paso 5: ejecuta la misma instrucción en ambas sesiones

POST /api/agent/sessions/alice_session_uuid/chat
{ "message": "Create a task called Review launch checklist in the Website launch project, due August 28." }

POST /api/agent/sessions/bob_session_uuid/chat
{ "message": "Create a task called Review launch checklist in the Website launch project, due August 28." }

Para Alice, http_request envía el token de Alice y workspace_a únicamente a projects.example.com. ProjectDesk devuelve los proyectos visibles para Alice; el agente resuelve el proyecto solicitado a partir de ese resultado y publica la tarea. La ejecución de Bob sigue el mismo plan, pero ProjectDesk filtra según workspace_b. Si Bob no puede ver ese proyecto, el agente no recibe ningún proyecto coincidente y no debe inventar ni reutilizar el ID de proyecto de Alice.

Cómo la coincidencia de hosts evita la filtración de credenciales

AgentChat inyecta un encabezado de sesión únicamente cuando el destino HTTP coincide con el nombre de host configurado y el puerto opcional. Las redirecciones se vuelven a comprobar en cada salto. Por lo tanto, una credencial para projects.example.com no se envía a files.example.net, a un host de imágenes ni a un destino de redirección inesperado.

Límite importante: La coincidencia del host limita adónde se envía un secreto. La API de ProjectDesk que lo recibe debe validar igualmente el token, la pertenencia al espacio de trabajo, la propiedad del recurso y el alcance de la operación.

Qué aspecto tiene un error de permisos

HTTP/1.1 403 Forbidden
Content-Type: application/json

{ "error": "insufficient_scope", "required_scope": "tasks:write" }

Las instrucciones de AgentChat consideran que los códigos 401 y 403 son problemas de configuración de credenciales. El agente debe detener la operación bloqueada e indicar al usuario qué permiso requiere atención. No debe solicitar el secreto en el chat, revelar los valores de encabezado almacenados ni reintentar repetidamente una denegación.

ProjectDesk debe mantener las respuestas de denegación útiles, pero no sensibles. Puede indicar el alcance requerido sin confirmar si existe un registro entre distintos tenants. Los registros de auditoría deben registrar el actor verificado y el recurso solicitado, mientras se redactan los tokens portadores y otros valores de las cabeceras.

Paso 6: consumir por separado el estado de AgentChat y el estado de ProjectDesk

GET /api/agent/sessions/alice_session_uuid/messages?after_id=&after_revision=0
GET /api/agent/sessions/alice_session_uuid/state

GET https://projects.example.com/v1/projects/proj_12/tasks

La interfaz de chat de ProjectDesk consulta periódicamente los mensajes de AgentChat y combina las revisiones del asistente durante el procesamiento. Cuando finaliza la ejecución, el panel del proyecto vuelve a cargar las tareas desde la API o la base de datos de ProjectDesk. La respuesta del asistente explica la acción, pero el registro de tarea guardado —no el texto— es el estado autoritativo del producto.

Usar sesiones separadas para niveles de privilegio separados

Un asistente de solo lectura puede adjuntar documentos de búsqueda y generación de informes con un token limitado a ámbitos de lectura. Un editor de proyectos puede adjuntar documentos para crear tareas con un token con permisos de escritura. Las operaciones de alto riesgo, como cambios en la facturación, la eliminación de cuentas o la publicación pública, deben utilizar una sesión más restringida o un endpoint del producto para aprobaciones pendientes.

En los flujos de aprobación, el agente crea una acción pendiente y devuelve su ID. ProjectDesk muestra al usuario el cambio exacto, registra la aprobación explícita y ejecuta la operación irreversible en su propio backend. La decisión final de autorización nunca depende de que el modelo interprete una frase de confirmación.

Pruebas de aislamiento en producción

  1. Usa la sesión de Alice para solicitar un ID de proyecto conocido de workspace_b y verifica que ProjectDesk no devuelva datos entre tenants.
  2. Ejecuta prompts idénticos para Alice y Bob y verifica que sus llamadas HTTP reciban resultados autorizados diferentes.
  3. Haz que cada token de sesión caduque, revócalo, omítelo y corrompélo, y verifica el comportamiento correcto de 401 en cada caso.
  4. Asigne a un miembro un ámbito de solo lectura y verifique que toda escritura de tareas devuelva 403 sin modificar la base de datos.
  5. Redirija una solicitud a otro nombre de host y verifique que AgentChat no reenvíe las credenciales configuradas.
  6. Inspeccione las respuestas de la API de sesión, los resultados de las herramientas, los registros de la aplicación y los mensajes de error para detectar filtraciones de secretos.
  7. Detenga y continúe una ejecución; después, verifique que el trabajo reanudado siga utilizando únicamente los encabezados y las vinculaciones de documentos de esa sesión.

El patrón reutilizable multiinquilino

Registre la capacidad empresarial una sola vez. Cree una sesión de AgentChat por cada conversación de usuario. Adjunte los UUID de los documentos pertinentes, inyecte credenciales de corta duración para el host exacto de la API y aplique la identidad y las políticas dentro de sus endpoints de SaaS. Después, deje que AgentChat gestione el razonamiento y el estado persistente de la conversación, mientras su propia base de datos sigue siendo la fuente de verdad.