Una arquitectura cliente-servidor no describe necesariamente dos máquinas. Describe roles en una interacción: quien inicia un request adopta el rol cliente respecto de ese salto; quien recibe y decide adopta el rol servidor. Un proxy puede ser servidor para el cliente y cliente para otro servidor. Confundir el rol lógico con una máquina, proceso o cuenta oculta dónde cambia la autoridad y produce modelos falsos de autenticación, caché y trazabilidad.
Este capítulo parte del parsing y la validación estricta del 52 y de archivos/canonicalización del 53: un request ya es una representación que debe validarse, y un nombre o URL no es por sí mismo autorización. El 55 añadió concurrencia, carreras y consistencia; aquí esa incertidumbre aparece distribuida entre saltos. El capítulo 57 continuará con navegador, origen y políticas de fetch. No se presenta una topología universal: se reconstruye qué papel desempeña cada componente en el flujo observado.
Roles, mensajes y estado
Un request tiene un emisor, un receptor previsto, método, destino, cabeceras, representación y contexto. Un response tiene estado, cabeceras, representación opcional y relación con el request. RFC 9110 define semántica HTTP, pero no decide qué recurso está autorizado para cada principal. La semántica del método orienta efectos e idempotencia; la aplicación debe concretar sus precondiciones y resultados.
Modelar la interacción como C --request--> S --response--> C es útil sólo si se preservan tres preguntas: ¿quién construyó el mensaje?, ¿quién validó sus campos?, ¿qué estado cambió y con qué evidencia? Un response 200 demuestra que un componente produjo ese response bajo su contrato; no prueba que un downstream recibió el efecto ni que una base de datos durable refleje la decisión. Del mismo modo, un error de transporte deja abierta la posibilidad de que el servidor haya procesado el request.
El estado vive en ambos lados. El cliente puede tener una sesión, cache local, clave de idempotencia y UI; el servidor tiene identidad, autorización, recurso y estado persistido. Un intermediario puede tener conexiones, caché, límites y registros. La misma URL puede producir respuestas distintas por autorización, versión, idioma o cache-control. La revisión debe distinguir estado observado de estado inferido.
Vista adaptada. Toca el diagrama para ampliarlo.
Intermediarios y atribución
Un intermediario reenvía, termina, transforma o almacena mensajes. Un reverse proxy puede terminar TLS y establecer otro canal; un gateway puede validar un token y derivar un contexto; una caché puede responder sin contactar al origin. RFC 9111 §2 describe cachés y revalidación, no una garantía de que todo response sea fresco o autorizado para todos los usuarios. Cache-Control, Vary y reglas de almacenamiento son parte del contrato concreto.
Cada salto introduce una decisión: qué headers se conserva, qué identidad se propaga, qué dirección se registra, qué límites se aplica y qué error se devuelve. Un header X-Forwarded-For puede ser útil como dato de cadena, pero no debe convertirse en identidad confiable sólo porque llegó desde internet. La identidad debe derivarse del canal o de un mecanismo de autenticación cuyo emisor y alcance estén validados. Los intermediarios no deben elevar autoridad por transportar una etiqueta.
La atribución requiere correlación. Un request_id, timestamp, principal autenticado, decisión y resultado observado pueden vincular logs de varios componentes, pero el ID no prueba por sí mismo que el mismo actor originó todos los eventos. Los relojes pueden diferir; los reintentos pueden reutilizar o cambiar IDs; un proxy puede registrar recepción sin que el upstream termine. La evidencia debe indicar observación, fuente y lagunas. No registrar secretos o cuerpos completos por defecto.
Fronteras de confianza, principal y contexto
Una frontera de confianza es el punto donde cambian supuestos sobre integridad, autoridad o comportamiento de datos. Puede estar entre navegador y gateway, gateway y servicio, servicio y base de datos, o entre dos procesos del mismo host. No coincide necesariamente con una frontera de red. Un socket local puede cruzar una frontera de privilegio; una conexión privada puede contener una entrada no confiable.
El principal es la entidad a la que se atribuye una acción: persona, servicio, workload o proceso. El contexto añade tenant, recurso, método, estado, tiempo, propósito y políticas aplicables. Autenticar el principal no responde qué puede hacer en ese contexto. Autorizar debe comprobar sujeto, acción, recurso y estado en el componente que protege el recurso; un gateway que autoriza una ruta no sustituye la comprobación del servicio si éste es el dueño del dato.
Un error común es copiar tenant_id, user_id o role desde el body o un header del cliente hacia una escritura privilegiada. Esos campos son datos candidatos; el servidor debe ligarlos al principal autenticado y al contexto derivado. Otro error es aceptar un token válido emitido para servicio A como permiso universal sobre servicio B. Validez criptográfica, audiencia, expiración y autorización son controles distintos.
Autenticación, autorización y TLS
Autenticación establece una identidad o credencial según un protocolo. Autorización decide si esa identidad puede realizar una acción sobre un recurso bajo un estado. TLS 1.3 protege el canal negociado y autentica el servidor cuando el cliente valida su certificado; en algunos perfiles puede autenticar también al cliente (RFC 8446 §1.2). No determina si /tenant-b/export pertenece al principal ni si un token tiene audiencia correcta.
La terminación TLS en un proxy cambia la frontera. El tramo proxy–origin necesita su propio contrato de confidencialidad e integridad, y el origin necesita saber qué contexto autenticado acepta del proxy. Reenviar un header de identidad por un canal no autenticado o desde un proxy no autorizado convierte una afirmación en entrada no confiable. mTLS puede autenticar workloads, pero no reemplaza autorización por recurso.
Vista adaptada. Toca el diagrama para ampliarlo.
La decisión debe fallar cerrada cuando falta autenticación, audiencia, tenant o estado requerido. Un 401 y un 403 tienen semánticas diferentes en HTTP, pero el detalle expuesto debe equilibrar diagnóstico y filtración. CORS, cookies, API keys y certificados son mecanismos de transporte o presentación; ninguno es una política de autorización completa. El control debe ubicarse junto al recurso y verificar que no haya una ruta alternativa que omita la comprobación.
Timeout, retry y resultado unknown
Un timeout es una observación del cliente sobre una ventana de espera, no una prueba de que el servidor no actuó. El request pudo estar en cola, aplicado y sin response, rechazado por un intermediario o perdido antes del origin. Tras timeout, el estado defendible suele ser unknown hasta consultar una fuente de verdad o recibir una evidencia correlacionada.
Reintentar depende de la semántica del método y del contrato de la operación. RFC 9110 §9.2.2 distingue métodos idempotentes, pero una aplicación puede hacer un POST idempotente mediante una clave y registro de resultado; eso requiere un contrato real, no sólo repetir el header. El retry debe tener límite de tiempo, backoff y política de errores transitorios. No repetir una operación sensible sólo porque el cliente no vio respuesta.
El resultado unknown necesita tres salidas explícitas: observar estado por una consulta autorizada, reintentar bajo idempotencia y deduplicación, o escalar/reconciliar. No debe convertirse en éxito para simplificar la UI ni en fracaso definitivo sin evidencia. La clave de idempotencia debe ligarse a principal, operación, recurso y parámetros; reutilizarla con otro contexto puede mezclar operaciones.
Vista adaptada. Toca el diagrama para ampliarlo.
SSRF y confused deputy: la autoridad no viaja con la URL
En SSRF (Server-Side Request Forgery), un servicio realiza una petición inducida por una entrada externa hacia un destino que el usuario no debía alcanzar desde esa posición de red. El problema arquitectónico no es que una URL sea «maligna» por texto: es que el servidor se convierte en diputado con más conectividad y autoridad que el principal. DNS, redirecciones, IPv4/IPv6 y parsers distintos pueden cambiar el destino efectivo; la mitigación debe limitar destinos y egress según un inventario de necesidad, validar cada salto y no confiar sólo en una lista textual (OWASP SSRF Prevention).
Un confused deputy aparece cuando un componente usa sus credenciales para ejecutar una acción cuyo contexto de autorización no está ligado al principal que la solicitó. Un backend que descarga una URL y luego publica el resultado puede cruzar dos fronteras: acceso de red y escritura de datos. Debe separar el recurso solicitado del destino de red, resolver y validar bajo una política, bloquear redes administrativas no necesarias y aplicar autorización al resultado. No basta con que el usuario esté autenticado.
El análisis defensivo pregunta: ¿qué principal decide?, ¿qué componente hace el request efectivo?, ¿qué credenciales y rutas de red posee?, ¿qué datos devuelve al solicitante?, ¿qué redirecciones y nombres se siguen?, ¿qué límite de tamaño/tiempo existe? No se convierte el capítulo en instrucciones de enumeración. La consecuencia depende de precondiciones, controles de egress y exposición de respuestas.
Observabilidad, errores y límites de evidencia
Una traza distribuida debe conservar correlación sin convertir logs en una copia indiscriminada de tokens, cookies o cuerpos. Campos útiles son request ID, trace ID, principal pseudonimizado, servicio, operación, recurso abstracto, decisión, códigos, latencias, reintento y resultado observado. Un log de authorized=true sólo es evidencia si identifica la política/version y el punto que tomó la decisión.
Los intermediarios pueden ocultar causa o condensar errores. Un 502 del gateway no adjudica si el origin rechazó, expiró o nunca recibió; hace falta evidencia del siguiente salto. La ausencia de log tampoco prueba ausencia de request: sampling, caída del agente o retención pueden explicar el hueco. Un diseño responsable expresa incertidumbre y permite reconciliarla mediante una fuente de verdad, no inventa una narrativa lineal.
La caché agrega otra atribución: un response puede ser servido por un intermediario sin revalidación reciente. La política debe impedir que datos privados se compartan por una clave de cache incompleta y definir cuándo un response es almacenables. El cliente no debe interpretar un response cacheado como prueba de una autorización actual si el contrato no lo permite.
Fronteras de representación y protocolo
El request que un cliente construye no es necesariamente el request que el origin interpreta. Un intermediario puede normalizar headers, limitar el body, cambiar el método en una redirección o seleccionar una versión de protocolo. La validación del 52 exige que cada consumidor aplique un perfil claro y rechace ambigüedad; la arquitectura del 56 añade que la autoridad no debe cambiar sólo porque un proxy reescriba una representación.
Una cabecera de autenticación es un dato con procedencia. Si un gateway termina TLS y añade Authenticated-Principal, el origin debe aceptar esa cabecera únicamente desde el gateway autenticado y en un canal con integridad; debe eliminar entradas suministradas por el cliente y fijar audiencia, expiración y contexto. Una lista de nombres de headers no reemplaza un contrato de confianza.
La misma precaución aplica a host, scheme y puerto. Un servicio que construye URLs absolutas a partir de Host recibido puede generar enlaces o redirecciones con autoridad equivocada. Un proxy que conoce el host externo y el origin interno debe transportar esa diferencia como contexto validado, no como una cadena libre.
Estado distribuido y caché
El servidor puede responder antes de que un evento sea visible en todos los consumidores. Un 201 Created puede significar que el recurso fue aceptado y persistido localmente; no necesariamente que una búsqueda por caché o réplica ya lo devuelve. El contrato debe nombrar la postcondición: existencia en el origin, disponibilidad de lectura, publicación de evento o finalización de trabajo asíncrono.
La caché tiene claves, expiración, validadores y reglas de invalidación. Si la clave no incluye una dimensión que altera autorización o representación —por ejemplo, tenant o idioma— puede servir un response a un contexto equivocado. ETag valida una representación bajo el recurso y reglas del servidor; no prueba que un actor tenga permiso para leer otra representación.
Los intermediarios también pueden hacer buffering y reintentos propios. El cliente puede observar una sola request mientras el gateway vuelve a intentar el upstream. La trazabilidad debe distinguir intento lógico, intento de transporte y efecto aceptado; de lo contrario una métrica puede duplicar intentos o una auditoría atribuir un cambio al componente equivocado.
Contratos operacionales
Una interacción declara límites de tamaño, tiempo, conexiones y concurrencia en cada salto. El límite del cliente no garantiza el del origin; un body aceptado por el proxy puede ser rechazado después. Los timeouts deben cubrir conexión, lectura, cabecera y procesamiento según el componente, con presupuestos que eviten que cada capa reinicie un reloj ilimitado.
Los errores deben preservar la diferencia entre rechazo conocido y resultado incierto. Un 400 por sintaxis inválida puede ser definitivo; un 401 puede requerir credencial; un 409 puede requerir reconciliar estado; un 429 exige respetar el límite; un 5xx no identifica por sí solo si el efecto ocurrió. La aplicación puede mapearlos a una interfaz común, pero no debe borrar la causa que determina si reintentar es seguro.
La cancelación del cliente no necesariamente cancela el trabajo del servidor. Si el servidor continúa una exportación tras cerrar la conexión, necesita un job identificable, autorización que no dependa de la socket viva y política de retención. El cliente puede consultar el job con el mismo principal y obtener complete, failed o unknown. Cancelar una espera no revierte una transición concurrente.
Caso trabajado: descarga y procesamiento de un informe
Una API recibe POST /reports/import con un identificador de informe y solicita a un worker que descargue una fuente. El cliente está autenticado, pero el identificador no debe convertirse directamente en URL. El servicio consulta un catálogo autorizado que liga informe, tenant, esquema y origen permitido. El worker es cliente del origen y servidor para el pipeline de parseo; su identidad de workload no es la identidad del usuario, pero necesita un contexto de delegación verificable.
Antes de descargar, se valida el destino contra el catálogo y la política de egress, se fija un límite de bytes/tiempo y se decide cómo seguir redirecciones. El worker conserva hash, origen, versión de parser y request ID. Si el origin devuelve bytes, el parser del 52 valida la representación y el 53 gobierna archivos, codificación y canonicalización. El resultado se escribe como artefacto derivado, no se presenta como el original firmado.
Si el cliente pierde la conexión después de que el worker acepta el job, el response no observado deja unknown. Una consulta posterior autorizada devuelve estado del job; repetir POST con la misma clave devuelve el resultado existente o un conflicto de parámetros. Si la descarga falla tras obtener parte del archivo, el worker aísla el temporal y no publica un informe parcial como completo. Cada relación —usuario–API, API–worker, worker–origen y pipeline–almacenamiento— necesita principal, credencial, contexto y evidencia.
Método de reconstrucción
- Dibujar cada salto como rol cliente/servidor, sin fijarlo a una máquina.
- Para cada request y response, registrar emisor, receptor, estado, transformación e identidad que se afirma.
- Marcar fronteras donde cambian transporte, parser, credenciales, tenant o dueño del recurso.
- Separar autenticación, autorización, confidencialidad del canal, integridad del mensaje y frescura de caché.
- Modelar timeout y retry como transiciones con resultado unknown y evidencia requerida.
- En destinos inducidos, limitar autoridad, resolución, egress, tamaño, tiempo y redirecciones.
- Correlacionar observaciones y declarar qué queda desconocido.
Errores de atribución frecuentes
El diagrama «cliente → servidor» suele ocultar tres sustituciones. Primero, se trata la dirección IP como principal, aunque una conexión puede representar un proxy, NAT o workload. Segundo, se trata un token válido como autorización completa, ignorando audiencia, tenant, recurso y estado. Tercero, se trata el response como prueba de la transición completa, aunque el servidor haya delegado trabajo o el intermediario haya respondido desde caché. La corrección mínima es nombrar la relación exacta que se está afirmando y la evidencia que la respalda.
Otro error es usar la topología como política: «está en la red interna, por tanto es confiable». Una red privada reduce exposición en ciertos escenarios, pero no autentica cada emisor ni elimina entradas manipuladas. Del mismo modo, un servicio puede ser legítimamente cliente de varios destinos y aun así necesitar una allowlist por operación. La confianza se asigna por contrato y se verifica en la frontera, no por la posición dibujada en un plano.
En revisiones de incidentes, separar causa de observación. «El gateway recibió 200» es una observación; «el usuario descargó el informe» es una inferencia que exige evidencia de body entregado y autorización. «El origin tuvo timeout» es una interpretación del gateway; la causa puede ser saturación, cierre o una respuesta perdida. Esta disciplina evita escalar severidad por una narrativa no comprobada y ayuda a decidir qué instrumentación falta.
Transferencia y frontera con el 57
Contrato mínimo de una operación remota
Antes de implementar una operación remota, escribir su contrato en términos que puedan observarse. El request debe declarar quién lo emite, qué recurso nombra, qué versión de la representación usa, qué credencial o delegación porta y qué límite de tamaño/tiempo aplica. El servidor debe declarar qué principal deriva, qué precondiciones comprueba, qué estado modifica, qué response significa cada código y qué evidencia queda disponible. Si la operación es asíncrona, el response debe distinguir aceptación del trabajo de finalización.
La respuesta también tiene una frontera de confianza. Los datos que devuelve un servicio pueden incluir información que el cliente está autorizado a ver, pero no se debe inferir que el cliente puede reutilizarlos para autorizar otra llamada. Un servicio que recibe una URL de callback, un identificador de objeto o una etiqueta de rol debe volver a validar su significado. La salida de un componente confiable se convierte en entrada no confiable cuando cruza hacia otro dominio o cuando el contexto de autorización cambia.
La compatibilidad entre versiones requiere conservar el significado de errores y estados. Añadir un intermediario que traduzca 202 Accepted a 200 OK puede hacer que el cliente crea que el efecto terminó. Cambiar una cabecera de cache puede exponer una representación entre tenants. Sustituir un timeout por un error definitivo puede disparar retries peligrosos. Las traducciones deben documentar qué información se pierde y mantener un estado desconocido cuando la evidencia no alcanza.
El contrato debe incluir recuperación. Tras reinicio de un worker, ¿cómo se encuentra un job aceptado?, ¿cómo se evita ejecutar dos veces?, ¿qué principal puede consultar o cancelar?, ¿qué ocurre con un artefacto parcial? Estas preguntas conectan arquitectura con estado y concurrencia: no se resuelven sólo con una conexión TLS o un status code. Una garantía es válida únicamente para el alcance declarado, el perfil de intermediarios y la fuente de verdad que puede observarse.
Una aplicación de documentos tiene navegador, CDN, gateway, API y almacenamiento. El navegador puede ser cliente de la API y el gateway cliente del origin; el CDN puede servir una respuesta sin consultar la API. La sesión del usuario, el origen del documento, las cabeceras de cache y la política de fetch no son un único control. El 57 estudiará cómo el navegador calcula origen, aplica restricciones entre orígenes y decide qué credenciales o respuestas son accesibles.
La transferencia correcta conserva el modelo: identificar principal y contexto, describir qué salto toma la decisión, distinguir response recibido de recurso autorizado y declarar qué intermediarios pueden responder. No se debe importar al 57 una conclusión como «TLS permite leer cualquier response» ni «misma red implica mismo origen». Origen es una política del navegador; rol cliente-servidor es una relación por interacción.
Síntesis
Cliente y servidor son roles, no identidades ni máquinas. Un intermediario puede cambiar el mensaje y la frontera, y una caché puede producir response sin contactar al origin. TLS ofrece propiedades del canal negociado; autenticación identifica; autorización decide sobre recurso y contexto. Timeout deja unknown; retry requiere contrato e idempotencia. SSRF y confused deputy surgen cuando la autoridad efectiva y la autoridad pretendida divergen. La observabilidad debe conservar procedencia y límites de evidencia.
La revisión final debe comparar contrato y evidencia. Para cada afirmación, preguntar qué componente la observó, en qué instante, con qué identidad y si hubo transformación posterior. Un trace puede demostrar orden de mensajes sin demostrar autorización; un token puede demostrar posesión de una credencial sin demostrar su uso legítimo; un response puede demostrar una decisión local sin demostrar persistencia. Mantener estas distinciones evita que una arquitectura parezca más fuerte por tener más cajas y flechas.
Fuentes primarias
- RFC 9110, HTTP Semantics, §§3, 7, 9 y 15; RFC Editor, 2022.
- RFC 9111, HTTP Caching, §§2–5; RFC Editor, 2022.
- RFC 8446, The Transport Layer Security (TLS) Protocol Version 1.3, §§1.2, 4–4.6; RFC Editor, 2018.
- W3C, Fetch Living Standard, §§2–3; Fetch, consultado 2026-10-05.
- W3C, HTML Living Standard, §7.1 Origins; Origins, consultado 2026-10-05.
- OWASP, Server-Side Request Forgery Prevention Cheat Sheet, validaciones de destino y egress; OWASP, consultado 2026-10-05.


