# Cómo los almacenes de cookies de los agentes conservan sesiones que no pretendías

Los clientes HTTP hacen que las cookies parezcan inofensivas porque los navegadores nos han acostumbrado a ellas. Un agente autónomo cambia las consecuencias. Una respuesta que incluye `Set-Cookie` puede otorgar a la siguiente solicitud una autoridad que el agente nunca pidió, nunca mostró y puede conservar después de que cambie su credencial original.

Trata un almacén de cookies como un depósito de autenticación, no como un detalle de transporte. Si una API exige sesiones con cookies, asigna al almacén un propietario con nombre, una vida corta y un límite visible. Si no las exige, desactívalo. He visto demasiadas investigaciones de incidentes empezar con alguien insistiendo en que la solicitud no tenía credenciales, mientras el cliente enviaba silenciosamente una en el encabezado `Cookie`.

## Un encabezado Set-Cookie puede convertirse en una segunda credencial

Un servidor envía `Set-Cookie` en una respuesta; un cliente que tiene un almacén puede enviar ese valor más tarde en un encabezado `Cookie`. Cuando el valor identifica una sesión del lado del servidor, en la práctica es una credencial. Que llegue después de una solicitud autenticada no reduce su capacidad de autorizar la siguiente.

Esto sorprende a los equipos porque se centran en el secreto que proporcionaron deliberadamente: un token bearer, una contraseña de autenticación basic o una solicitud firmada. Revisan de dónde procede ese secreto y si llega al agente. Después, una biblioteca HTTP acepta una cookie de sesión sin una sola línea explícita de código de aplicación. La siguiente solicitud puede funcionar cuando desaparece el encabezado Authorization original.

La diferencia importante está entre inyectar una credencial y continuar una sesión. La inyección de credenciales adjunta un secreto conocido a una solicitud. La continuación de sesión permite que el servidor emita un secreto nuevo y pide al cliente que lo repita después. Ambos pueden autorizar trabajo. Solo uno suele verse en los argumentos de llamada de una herramienta.

RFC 6265 describe este intercambio como gestión de estado: el agente de usuario guarda la información de cookies de `Set-Cookie` y devuelve las cookies aplicables en `Cookie`. La redacción es deliberadamente amplia porque los navegadores web la necesitan. Un cliente de agente no debería heredar el hábito del navegador de conservar estado solo porque el protocolo HTTP lo permita.

Una cookie también cambia el significado de una rotación fallida de tokens. Supón que un agente llama a una API con un token, recibe `sid=...` y más tarde pierde acceso a ese token. Si la API acepta la cookie de sesión por sí sola, el agente aún tiene una vía de acceso a la cuenta. La rotación corrigió la credencial conocida, pero no terminó la sesión emitida. Es un asunto de gestión de sesiones del lado del servidor y de contención del lado del cliente. Debes abordar ambos.

## El cliente decide si existe estado oculto

`Set-Cookie` no hace nada por sí solo. Un cliente debe decidir conservarla. Esa decisión puede ocultarse en lugares sorprendentes: un cliente HTTP reutilizable, el gestor de cookies de una biblioteca, un contenedor de fetch, un entorno de pruebas o una implementación de redirecciones.

Algunos clientes comunes no conservan cookies a menos que les des un almacén. Otros las conservan cuando el código adjunta un gestor de cookies estándar. Un cliente compartido puede entonces convertir el almacén en compartido por accidente. No deduzcas el comportamiento a partir de la documentación de la API ni de que una llamada funcionara. Inspecciona cómo se construye el cliente y ejecuta una prueba.

Una prueba limpia usa un servidor que controlas o un endpoint de prueba inocuo. La primera respuesta debe establecer una cookie con un nombre claro y la segunda solicitud debe informar de los encabezados recibidos. El resultado debe responder dos preguntas distintas:

1. ¿El cliente conservó la cookie después de recibir `Set-Cookie`?
2. ¿El cliente envió esa cookie en una solicitud posterior apta?

Con curl, un archivo de cookies explícito hace visible el estado:

```
curl -i -c /tmp/agent-cookie-test.txt https://test.example/session/start
HTTP/1.1 200 OK
Set-Cookie: agent_probe=run-7f3; Path=/; Secure; HttpOnly

curl -i -b /tmp/agent-cookie-test.txt https://test.example/session/echo
HTTP/1.1 200 OK

{"received_cookie":"agent_probe=run-7f3"}
```

El archivo es la esencia del ejercicio. El primer comando no puede crear una sesión oculta a menos que algo conserve su respuesta. El segundo no puede repetir una sesión si no recibe el archivo. Si tus herramientas de agente dan al equivalente de ese archivo un hogar global de proceso sin nombre, has creado un límite de sesión que nadie puede analizar durante una revisión.

Repite la prueba con la ruta de ejecución exacta que usa tu agente, incluidos su contenedor de solicitudes y la configuración de redirecciones. Una prueba directa con curl demuestra cómo funciona curl, no tu herramienta. Registra si el almacén empieza vacío, dónde reside y qué lo borra.

## Reutilizar entre llamadas no es lo mismo que reutilizar entre ejecuciones

Unas cuantas llamadas dentro de una tarea pueden necesitar compartir una sesión. Reutilizar esa sesión en una tarea posterior es otra decisión. Unir esas dos duraciones es cómo una pequeña comodidad se convierte en autoridad persistente.

Usa tres límites al evaluar el comportamiento. Primero, pregunta si una sola solicitud necesita cookies. Segundo, pregunta si las llamadas relacionadas de un proceso del agente las necesitan. Tercero, pregunta si un proceso nuevo, una tarea reanudada, otra credencial u otra persona deberían heredarlas. Cada respuesta afirmativa necesita una razón explícita.

Un almacén en memoria que desaparece con el proceso es más fácil de contener que un archivo en un directorio de proyecto. Un archivo puede sobrevivir a un fallo, un reintento, un espacio de trabajo copiado o un cambio de quien ejecuta la tarea. También puede acabar en un archivo de soporte o en la salida del estado de control de versiones. `HttpOnly` no protege un archivo de cookies frente al cliente que lo escribió; solo limita el acceso desde scripts del navegador.

Prefiero un almacén nuevo para cada ejecución del agente incluso cuando el mismo modelo recibe un prompt de seguimiento. La continuidad conversacional del modelo no es motivo para conservar autoridad HTTP. Si el seguimiento realmente necesita la sesión, haz que el operador apruebe continuar la ejecución bajo el mismo límite con nombre, en lugar de permitir silenciosamente que la ejecución anterior deje una sesión utilizable.

Las llamadas simultáneas también necesitan su propia decisión. Un almacén compartido puede crear un comportamiento que depende del orden: la solicitud A recibe una cookie, la solicitud B empieza instantes después y B obtiene una sesión que nunca estableció. Reproducirlo resulta penoso. Da a las tareas simultáneas almacenes separados, salvo que la API exija una sesión coordinada y la tarea la posea explícitamente.

## El alcance de una cookie no coincide con la seguridad que la gente imagina

Los atributos de las cookies limitan la entrega, pero no vuelven inocua una sesión. Léelos como instrucciones de enrutamiento que el servidor da al cliente y después decide si tu cliente debe respetarlas siquiera.

Una cookie solo de host vuelve al host exacto que la emitió. Una cookie con `Domain=example.com` puede volver a subdominios aptos como `api.example.com` y `admin.example.com`. RFC 6265 también indica que un agente de usuario rechaza un valor Domain que no coincide por dominio con el host de origen, pero eso no resuelve el error habitual de confiar en todos los subdominios bajo un dominio corporativo amplio.

`Path=/billing` limita una cookie a solicitudes cuyas rutas coinciden con la ruta de la cookie. No impide que un servidor en otra ruta permitida acepte la misma cookie si la recibe por algún otro camino, ni sustituye las comprobaciones de autorización. No uses Path como límite de seguridad en conversaciones de diseño. Es una regla de envío del cliente.

`Secure` indica al cliente que envíe la cookie solo por transporte seguro. `HttpOnly` indica a un navegador que no la exponga mediante APIs de scripts. Ambos atributos son buenas prácticas, pero ninguno limita la conservación, el uso compartido entre tareas, las redirecciones ni la capacidad del agente de usar la cookie. `SameSite` rige principalmente el contexto de sitio en navegadores; un agente que no es navegador no debería usarlo como prueba de que el comportamiento entre sitios es seguro.

Hay otro error fácil: registrar encabezados sin procesar durante la depuración. Un filtro que elimina `Authorization` pero deja `Cookie` no ha ocultado la autenticación. Registra la presencia de una cookie, su nombre, el Domain y Path declarados, el tipo de caducidad y un identificador de correlación no reversible si lo necesitas. No registres su valor.

## Las redirecciones convierten las pruebas de cookies en pruebas de destino

Una redirección no es simplemente otra URL. Puede cambiar qué servidor ve la siguiente solicitud, si se conservan credenciales y qué respuesta puede establecer estado. Pruébala como un flujo propio.

Empieza con un endpoint que devuelva una redirección después de establecer una cookie. Después, prueba cada destino por separado: el mismo host, un subdominio permitido, un subdominio hermano y un host no relacionado. Observa tanto el `Cookie` saliente como el `Authorization` saliente. Las distintas pilas HTTP toman decisiones diferentes y un contenedor puede anular los valores predeterminados.

Un fixture útil produce un rastro breve como este:

```
request 1  GET https://api.example.test/start
response 1  302 Location: https://api.example.test/next
            Set-Cookie: probe=A; Path=/; Secure
request 2  GET https://api.example.test/next
            Cookie: probe=A
response 2  200
```

Después cambia solo el host de Location. Si `api.example.test` redirige a `reports.example.test`, una cookie solo de host no debería seguirla. Una cookie con alcance Domain podría hacerlo. Tu prueba debe indicar el resultado esperado antes de ejecutarse, porque un rastro que te sorprende es el objetivo, no una molestia que haya que tapar.

Rechaza las redirecciones entre orígenes cuando el contrato de la API no las requiera. Si debes seguirlas, compara los orígenes anterior y nuevo, elimina las credenciales de la solicitud según una regla explícita y deja que una respuesta nueva establezca cualquier estado de cookie nuevo. Nunca uses una política amplia de redirección automática suponiendo que el alcance de la cookie te salvará.

## Una prueba de sesión debe cruzar credenciales y procesos

La prueba que detecta el error costoso no es «solicitud uno, solicitud dos». Cruza los límites que tu modelo operativo afirma aplicar.

Crea un endpoint inocuo que emita una cookie solo después de recibir una etiqueta de credencial elegida. Haz que devuelva la etiqueta de sesión en cada solicitud autorizada. Después ejecuta esta secuencia:

1. Inicia la ejecución A con la credencial A y recibe `sid=A`.
2. Haz una segunda llamada sin la credencial A, pero con el mismo almacén.
3. Inicia la ejecución B con la credencial B y un almacén vacío.
4. Inicia la ejecución C sin credencial y con cualquier almacén persistente de la ejecución A.
5. Revoca la credencial A o invalida su sesión en el servidor de pruebas y vuelve a probar el almacén de la ejecución A.

La salida esperada es una decisión de política, no una respuesta universal. Una API basada en cookies puede permitir intencionadamente la segunda llamada dentro de la ejecución A. La ejecución B no debería ver el estado de A. La ejecución C debe fallar salvo que hayas aprobado explícitamente la persistencia. Después de la revocación, el servidor de pruebas debe rechazar la sesión antigua si tu modelo de amenazas dice que la rotación de tokens debe eliminar el acceso activo.

Escribe la expectativa junto a la prueba, en vez de enterrarla en la memoria de un desarrollador. Una tabla concisa en un comentario de prueba funciona:

```
run A, same jar, no bearer header: allowed only if session continuation is intended
run B, fresh jar, credential B: must identify as B
run C, persisted jar, no credential: rejected
run A after session invalidation: rejected
```

Esto revela una diferencia que los equipos suelen confundir: revocar una credencial inicial y revocar sesiones emitidas no son la misma operación. El responsable de la API debe invalidar las sesiones. El responsable de la herramienta de agente debe evitar conservarlas más allá de su vida aprobada. Ninguna parte puede suponer que la otra se ocupó de ello.

## Desactiva los almacenes implícitos salvo que la API necesite uno

El valor predeterminado sensato para una acción HTTP de agente es no almacenar cookies ni enviar automáticamente un encabezado `Cookie`. Una respuesta puede seguir conteniendo `Set-Cookie`; registra que ocurrió si tu diseño de auditoría lo permite y después descártala. La API debe usar su credencial normal de solicitud en la llamada siguiente.

Esta recomendación no es popular porque muchas API cercanas al mundo web funcionan tras un endpoint de inicio de sesión solo cuando el cliente conserva una cookie. La gente recurre a un almacén compartido porque hace que funcionen las demostraciones y las pruebas de integración. Es la solución equivocada cuando la API documentada admite tokens bearer u otro mecanismo limitado a cada solicitud. Estás conservando una autoridad invisible para compensar una ruta de integración que no deberías haber elegido.

Si la API de verdad exige cookies, convierte el almacén en una capacidad explícita. La persona que llama debe seleccionar un almacén vacío con nombre al inicio de la ejecución, la herramienta debe informar cuando la respuesta crea o reemplaza una cookie y el almacén debe desaparecer al final. No permitas que un endpoint inscriba a cada agente en una sesión duradera solo con devolver un encabezado.

Una política mínima puede ser lo bastante simple para revisar:

```
cookie mode: disabled by default
allowed mode: ephemeral per agent run
persistence: prohibited
sharing: prohibited between agent processes
redirects: same-origin only unless the action definition permits another origin
logging: record cookie names and scope, never values
```

Es deliberadamente menos sofisticada que un motor de reglas. Una política de cookies sofisticada acumula excepciones hasta que nadie puede decir qué acción transporta qué estado. Un conjunto pequeño de opciones da a los revisores una respuesta real.

## Audita la transición de estado, no solo la solicitud

Un registro de auditoría que enumera URL y códigos de estado omitirá el evento más útil: una respuesta cambió lo que pueden hacer las llamadas posteriores. Captura los cambios de estado de las cookies como eventos de primera clase sin conservar el secreto de sesión.

Para cada acción HTTP, el registro debe permitir responder: ¿la solicitud envió cookies?, ¿la respuesta estableció o borró alguna?, ¿qué almacén las recibió?, ¿el almacén pertenecía a esta ejecución? y ¿hubo una redirección? Los nombres y atributos de las cookies suelen bastar para diagnosticar. Guarda valores solo si tienes un diseño de seguridad convincente para protegerlos y hacerlos caducar, algo que la mayoría de herramientas de agente no necesitan.

Cuando un agente usa Sallyport para acciones HTTP, la bóveda puede mantener la credencial de API configurada fuera del agente mientras se ejecuta la acción. Esa separación solo es útil si el cliente HTTP trata cualquier estado de sesión devuelto con la misma cautela, en vez de convertirlo silenciosamente en otra vía de credenciales.

Los registros de auditoría también necesitan un límite de ejecución legible para una persona. Si un operador revoca una ejecución de agente, debe saber si ese acto impide futuras llamadas solo mediante la credencial configurada o si también borra el estado de sesión adjunto a la ejecución. Si no lo borra, dilo claramente y haz que el estado restante sea inaccesible para un proceso posterior.

La primera prueba que añadiría es deliberadamente sencilla: un endpoint envía `Set-Cookie`, el siguiente confirma si llegó y un proceso nuevo del agente repite la llamada. Ejecútala antes de añadir reintentos, redirecciones, compatibilidad con navegadores o una caché persistente. Si la respuesta no es evidente en el rastro, tu cliente tiene más autoridad de la que reconoce su interfaz.

## Los autores de API pueden hacer más seguros a los agentes sin adivinar

Los autores de API deben documentar si las cookies son necesarias, qué las crea, cuál es su vida prevista y cómo las invalidan los clientes. Una frase como «usa este endpoint después de iniciar sesión» no basta cuando el inicio de sesión puede emitir una sesión que dure más que la credencial usada para obtenerla.

Ofrece una alternativa limitada a cada solicitud cuando sea posible. La autenticación bearer, las solicitudes firmadas o un token de acción de alcance reducido suelen hacer más fácil auditar el comportamiento del cliente porque cada llamada lleva su autoridad de forma visible. Eso no hace que esos mecanismos sean seguros automáticamente, pero evita un canal adicional de repetición oculto en la memoria del cliente.

Si emites una cookie de sesión, haz que la invalidación de sesión funcione y pruébala. Rotar un token sin invalidar las sesiones deja a los operadores con una falsa sensación de haber terminado. Si aceptas tanto un token bearer como una cookie de sesión, define cuál prevalece cuando no coinciden y muestra esa decisión en la salida de diagnóstico.

No digas a quienes crean agentes que imiten a los navegadores salvo que tu servicio dependa realmente del comportamiento de un navegador. Los agentes hacen llamadas repetidas sin supervisión y a menudo operan en tareas distintas. El cómodo estado persistente de un navegador es un mal valor predeterminado para ese entorno.

## El valor predeterminado seguro es un cliente nuevo sin sesión recordada

El soporte de cookies no es malo; el estado sin propietario sí. Un almacén de vida corta, seleccionado explícitamente, puede ser la forma correcta de completar una tarea de API con varias llamadas. Un almacén que aparece porque alguien reutilizó un cliente HTTP es un accidente esperando el reintento, la redirección o la rotación de credenciales adecuados.

Haz visible el límite de sesión en la interfaz de la herramienta y en el registro de auditoría. Después demuéstralo con la prueba entre ejecuciones. El rastro de solicitudes debe permitir a un revisor señalar cada vía de credenciales que tuvo el agente, incluidas las que el servidor intentó devolver.
