# Cómo debe seguir la inyección de credenciales a la validación de solicitudes

Las credenciales deben añadirse al final del flujo de una solicitud saliente, después de que el cliente haya decidido qué está dispuesto a enviar. Si un componente añade una clave API o una credencial SSH antes de validar el destino real y la forma de la solicitud, ya ha tomado la decisión de seguridad. Todo lo que viene después es limpieza.

Ese orden importa aún más con los agentes de programación autónomos. Un agente puede generar una solicitud plausible, seguir un enlace incluido en una respuesta de API, reutilizar un ejemplo de un repositorio o aceptar una redirección sin comprender las consecuencias. Nada de eso requiere que el agente sea malicioso. Basta con que la ruta de la solicitud permita que una entrada no confiable influya en el destino de una solicitud autenticada.

La regla útil es sencilla: analiza la acción propuesta, valida la acción completa, congela la acción, establece la conexión correspondiente e inyecta la credencial en el último momento responsable. Si la solicitud cambia, descarta la decisión de autorización y vuelve a empezar.

## Las credenciales convierten la validación de solicitudes en un límite de seguridad

Un inyector de credenciales no es un simple envoltorio práctico alrededor de un cliente HTTP. Decide qué parte remota recibe autoridad para actuar en tu nombre. Por eso, el límite de validación debe incluir algo más que un campo de nombre de host copiado de un objeto de solicitud.

Para una acción HTTP, valida como mínimo el esquema, el nombre de host, el puerto, el método, la ruta, las reglas de consulta, los encabezados relevantes y el cuerpo. Para SSH, valida el host, el puerto, la decisión de confianza en la clave del host, la cuenta remota, el comando, el reenvío del entorno y cualquier destino de transferencia de archivos. Los detalles cambian, pero el orden no.

Los equipos suelen mezclar dos preguntas distintas:

- ¿Puede esta solicitud llegar al servicio previsto?
- ¿Debe esta credencial autorizar exactamente esta solicitud?

Una búsqueda DNS correcta y un certificado TLS válido solo responden a una parte de la primera pregunta. No responden a la segunda. Una solicitud a `https://api.example.com:8443` no equivale automáticamente a otra enviada al puerto HTTPS habitual. Un `POST /v1/refunds` con un token bearer no es intercambiable con un `GET /v1/me`, aunque ambos lleguen al mismo host.

El error que veo con más frecuencia es una regla amplia como «esta clave es para api.example.com», seguida de un cliente que acepta una URL arbitraria, añade el encabezado y pide a la biblioteca que la envíe. Esa regla deja demasiada autoridad en el análisis de URL, la gestión de redirecciones, el comportamiento del proxy y los encabezados controlados por el agente. También vuelve engañosas las revisiones. Una persona puede aprobar una solicitud descrita de una forma mientras que la solicitud enviada por la red dice otra.

El validador de solicitudes debe ser la autoridad en ambos lados de esa brecha. Debe tomar una decisión explícita sobre una solicitud estructurada, no buscar una cadena con un nombre de dominio conocido y esperar que todo lo demás se comporte correctamente.

## Analiza el destino como un origen canónico

Una comprobación del destino debe comparar componentes estructurados de la URL, no prefijos de texto. La identidad relevante de un origen HTTP es el esquema, el host y el puerto. RFC 3986 define la parte de autoridad como información de usuario opcional, un host y un puerto opcional. RFC 9110 utiliza el concepto de origen para las solicitudes HTTP. Son definiciones pequeñas con consecuencias importantes.

Empieza analizando la URL con un analizador real. Rechaza los valores que tu integración no necesite. No repares entradas mal formadas para convertirlas en algo más permisivo. Un validador que intenta ayudar suele crear un segundo analizador cuyo comportamiento acaba separándose del cliente HTTP.

Para una credencial API típica, una regla de destino conservadora puede ser esta:

```text
esquema aceptado: https
host aceptado: api.billing.example
puerto aceptado: solo 443
rutas aceptadas: /v1/invoices/* y /v1/customers/*
información de usuario: prohibida
fragmentos: ignorados antes del envío, rechazados en las acciones propuestas
literales IP: prohibidos salvo configuración explícita
```

La canonicalización requiere moderación. Escribe en minúsculas el nombre de host DNS antes de compararlo. Trata un puerto HTTPS omitido y el puerto 443 como el mismo puerto efectivo. Asegúrate de que el analizador haya separado la información de usuario del host. Normaliza los segmentos con puntos solo si después validas la ruta normalizada, y no descodifiques caracteres reservados hasta saber cómo los interpretará el cliente.

Varias URL muestran por qué fallan las comprobaciones por prefijo:

```text
https://api.billing.example.attacker.invalid/v1/invoices
https://api.billing.example@attacker.invalid/v1/invoices
https://api.billing.example:8443/v1/invoices
https://api.billing.example/v1/../admin/users
```

Solo los primeros caracteres parecen conocidos. Su autoridad o su ruta final pueden ser distintas. Conviene probar especialmente la segunda URL porque el texto anterior a `@` es información de usuario, no el host remoto. Un navegador puede mostrarla de una forma que lleve a un revisor apresurado a mirar la parte equivocada.

Los nombres de dominio internacionalizados requieren la misma cautela. Decide si la integración acepta un nombre de host ASCII fijo o un conjunto definido de nombres internacionalizados. Convierte y compara siguiendo una única regla documentada. No compares la forma visible en un lugar y la forma enviada por la red en otro.

DNS no es tu base de datos de autorización. Puedes usar DNS para conectarte después de aceptar un origen, pero no aceptes un destino solo porque resuelve a una dirección esperada. El alojamiento compartido, los balanceadores, las direcciones cambiantes de los servicios y el DNS rebinding vuelven frágiles las suposiciones basadas en IP. Si necesitas protecciones para redes privadas, aplícalas como una regla adicional de conexión, no como sustituto de una lista de orígenes permitidos.

## Valida juntos el destino de conexión y la autoridad HTTP

La URL, el nombre del servidor TLS y la autoridad HTTP deben describir el mismo destino aprobado. Si no lo hacen, el inyector de credenciales debe detenerse.

HTTP tiene más de un lugar donde puede aparecer la autoridad. HTTP/1.1 tiene el encabezado `Host`. HTTP/2 y HTTP/3 usan el pseudoencabezado `:authority`. Un proxy HTTP puede recibir un destino de solicitud en formato absoluto que contenga otra autoridad. RFC 9112 exige que un cliente envíe un encabezado Host en HTTP/1.1 y trata los campos Host ausentes, repetidos o no válidos como mal formados. Esa regla existe porque el enrutamiento por autoridad no es un adorno opcional.

En un cliente que gestiona credenciales, lo más seguro es mantener la construcción de la autoridad fuera del control del agente. El transporte de confianza crea `Host` o `:authority` a partir de la URL ya aprobada. No acepta una segunda autoridad de enrutamiento proporcionada por el agente. Tampoco acepta encabezados `Connection`, `Proxy-Authorization`, `Transfer-Encoding`, `Content-Length` o `Expect` proporcionados por el agente, salvo que una integración concreta requiera uno y la implementación lo gestione deliberadamente.

Esto evita una solicitud dividida. Imagina un validador que aprueba `https://api.billing.example/v1/invoices` y después combina encabezados arbitrarios del agente. Si la pila HTTP inferior respeta un valor `Host` proporcionado, un proxy, una puerta de enlace o un servidor mal configurado podría enrutar la solicitud según ese encabezado. El validador aprobó un destino, pero la solicitud llegó a otro.

La misma regla se aplica a la configuración del proxy. Un proxy corporativo puede ser legítimo, pero es una ruta de transporte, no una nueva autoridad para la credencial. Mantén la configuración del proxy fuera de los datos de la solicitud del agente. Valida el destino final de forma independiente y haz visible el comportamiento del proxy en los registros de auditoría.

La verificación del certificado TLS es obligatoria para HTTPS, pero verificar el certificado no concede permiso para usar cualquier credencial. El cliente debe verificar el nombre de host de la URL aprobada, usar ese nombre para la indicación del nombre del servidor cuando corresponda y rechazar cualquier discrepancia del certificado. No ofrezcas al agente una opción para «omitir la verificación». Un atajo temporal de diagnóstico suele acabar convertido en una vía de escape permanente.

## Las redirecciones son solicitudes nuevas, no una continuación

Una redirección autenticada es una segunda solicitud con un nuevo destino. Tratarla como una continuación transparente es la forma en que las credenciales salen del límite que pretendías imponer.

La opción predeterminada más segura para los clientes API es desactivar el seguimiento automático de redirecciones cuando una solicitud lleva credenciales. Devuelve la respuesta de redirección a la capa de solicitudes de confianza, analiza el valor `Location`, resuélvelo según las reglas de URL y pasa la solicitud resultante por el validador completo. Solo después decide si harás otra solicitud y solo entonces inyecta una credencial para esa nueva solicitud.

Una redirección a un origen distinto no debe recibir credenciales de la solicitud original. Esto incluye un esquema, nombre de host o puerto efectivo diferente. Una redirección de HTTPS a HTTP debe fallar directamente en una llamada API con credenciales. Una redirección de `api.example.com` a `login.example.com` también cambia de origen, aunque ambos nombres pertenezcan a la misma empresa. La propiedad común de una compañía no es una regla de transporte.

El código de estado HTTP cambia el riesgo. RFC 9110 especifica el comportamiento de las redirecciones, incluidos códigos que conservan el método y el cuerpo de la solicitud. RFC 9700, las buenas prácticas actuales de seguridad de OAuth 2.0, advierte que los servidores de autorización no deben usar HTTP 307 para redirigir una solicitud que pueda contener credenciales de usuario. La razón es sencilla: un cliente puede repetir el método y el cuerpo originales en la nueva ubicación.

Esto proporciona una política práctica de redirecciones:

1. Rechaza las redirecciones por defecto en llamadas autenticadas de máquina a máquina.
2. Permite solo un conjunto pequeño y documentado de redirecciones cuando una integración las necesite.
3. Vuelve a validar el destino resuelto, el método, los encabezados y el cuerpo en cada salto.
4. Elimina todas las credenciales antes de considerar el siguiente salto.
5. Establece un límite bajo de redirecciones y registra cada decisión.

No resuelvas esto confiando en cualquier subdominio. `uploads.example.com` y `api.example.com` pueden estar gestionados por equipos distintos, usar infraestructuras diferentes o exponer rutas de ataque distintas. Un comodín que parece práctico durante la configuración suele sobrevivir a la razón por la que se creó.

Hay una trampa relacionada con las solicitudes firmadas. Si una API firma el método, la ruta, determinados encabezados o el resumen del cuerpo, normalmente una redirección tampoco puede conservar la firma. Volver a firmar solo es correcto después de que la siguiente solicitud supere su propia validación. Una firma demuestra que alguien con el secreto firmó unos datos. No demuestra que esos datos sigan describiendo un destino aprobado.

## Los encabezados necesitan un responsable antes que filtros

Filtrar encabezados resulta más sencillo cuando decides quién es responsable de cada uno. La capa de solicitudes debe ser responsable de las credenciales y el enrutamiento. El agente solo puede controlar los encabezados de aplicación que permita una integración concreta.

Los encabezados de credenciales incluyen `Authorization`, un encabezado de clave API específico del proveedor, las cookies y, en ocasiones, un encabezado de firma. Inyéctalos después de validar. Nunca tomes uno del agente, aunque diga que contiene un marcador de posición. Un marcador invita a una sustitución accidental y enseña una interfaz equivocada: el agente propone una acción y el componente de confianza proporciona la autoridad.

Los encabezados de enrutamiento y entramado incluyen `Host`, `Content-Length`, `Transfer-Encoding`, `Connection`, `Upgrade` y los pseudoencabezados de HTTP/2. Deja que los cree la biblioteca de transporte. La entrada del usuario no debe sobrescribirlos.

Los encabezados de aplicación pueden permitirse, pero solo mediante un esquema. Supón que una API acepta un identificador de cliente, una clave de idempotencia y un tipo de contenido. Permite esos nombres, valida sus valores y rechaza todo lo demás. No transmitas un mapa arbitrario de encabezados porque la mayoría de las llamadas use encabezados inofensivos. El encabezado poco frecuente es el que convierte una solicitud normal en una instrucción para un proxy, una variante de caché, una identidad alternativa o una ruta de depuración.

`Authorization` también requiere un tratamiento especial en los registros. Registra que el inyector utilizó la referencia de credencial `billing-prod-readwrite`, no su valor ni una forma codificada. Ocultar un encabezado después de que un registrador genérico ya lo haya capturado no es fiable. Crea un evento seguro a partir de campos estructurados antes de que cualquier componente serialice la solicitud.

Las credenciales en encabezados personalizados no son menos sensibles que los tokens bearer solo porque usen un nombre como `X-Api-Key`. Si el servicio receptor acepta el valor como autoridad, cualquiera que lo reciba podría reutilizarlo. Los nombres diferentes cambian la interoperabilidad y las prácticas de registro. No cambian la necesidad de validar adónde llega el valor.

## El método, la ruta y el cuerpo definen la acción

Una lista de hosts permitidos es demasiado amplia cuando una credencial puede leer datos, modificarlos o iniciar movimientos de dinero. La forma de la solicitud debe participar en la decisión de permisos.

Empieza por el método. Permite los métodos que la integración necesita y rechaza el resto. No describas `POST` como intrínsecamente peligroso y `GET` como seguro. Muchas API exponen operaciones que cambian el estado mediante endpoints GET, y un GET puede filtrar información privada a través de parámetros de consulta o registros. Las reglas de método siguen siendo importantes porque hacen concreta la revisión de la política.

Después valida la ruta con plantillas, no mediante un prefijo impreciso. Una plantilla como `/v1/projects/{project_id}/deployments` puede exigir el número de segmentos, los caracteres permitidos en los identificadores y comprobar si un agente puede seleccionar un proyecto fuera de su ámbito. Si un endpoint usa un parámetro de consulta para seleccionar una cuenta, valida también ese parámetro. Un nombre de host correcto no convierte `/v1/accounts/other-team/export` en una ruta aceptable.

El cuerpo debe formar parte de la solicitud congelada. Un validador que aprueba un objeto JSON y después deja que otra capa lo serialice o modifique puede no estar autorizando los bytes que salen de la máquina. Esto se vuelve visible con claves JSON duplicadas, codificación de formularios, límites multipart, conversiones de coma flotante y middleware que añade campos.

Un diseño práctico hace que el validador produzca un plan de ejecución inmutable:

```json
{
  "method": "POST",
  "url": "https://api.billing.example/v1/invoices/inv_123/cancel",
  "headers": {
    "content-type": "application/json",
    "idempotency-key": "job-7f3c"
  },
  "body_sha256": "4d94c2...",
  "credential_ref": "billing-cancel"
}
```

El transporte recibe el plan y los bytes del cuerpo ya preparados. Confirma el resumen del cuerpo antes de abrir la solicitud autenticada. Deriva los encabezados de enrutamiento a partir de la URL, añade el secreto de `credential_ref` y envía exactamente esos bytes. Si el resumen difiere, la operación falla en lugar de intentar adivinar qué fase cambió la solicitud.

Este enfoque también mejora la aprobación humana. Una tarjeta de aprobación puede mostrar una acción en lenguaje claro junto con el origen canónico, el método, la ruta, el identificador de cuenta seleccionado y el importe o nombre del recurso. No debe pedir a una persona que apruebe un bloque JSON sin formato en el que un campo peligroso esté oculto cerca del final.

## Un validador pequeño es más seguro que un lenguaje de políticas general

El impulso habitual es crear un motor de reglas amplio: condiciones arbitrarias, expresiones regulares, variables, excepciones y un bypass de emergencia. Parece flexible hasta que alguien tiene que decidir si una credencial puede llegar a un destino de redirección con un encabezado de proxy y un cuerpo JSON ensamblado por un agente.

La mayoría de los casos de inyección de credenciales necesita un modelo más pequeño. Cada credencial debe tener un canal explícito y un contrato compacto de solicitud. Para HTTP, ese contrato especifica los orígenes aceptados, los métodos, las rutas, los encabezados permitidos, el comportamiento de las redirecciones y las restricciones del cuerpo. Para SSH, especifica los hosts, usuarios, expectativas sobre las claves del host, formas de comando permitidas y restricciones de transferencia.

Una configuración compacta puede ser así:

```yaml
credential: billing-cancel
channel: https
origins:
  - https://api.billing.example:443
methods: [POST]
routes:
  - /v1/invoices/{invoice_id}/cancel
headers:
  content-type: application/json
  idempotency-key: generated
redirects: deny
body:
  required_fields: [reason]
  allowed_fields: [reason]
```

Este fragmento no es un sistema de seguridad completo. Sí demuestra la restricción importante: una credencial está vinculada a una forma de acción limitada. Si la siguiente integración necesita `GET /v1/invoices/{invoice_id}`, asígnale una ruta independiente y, si es posible, una credencial de solo lectura separada. No conviertas silenciosamente la credencial de cancelación en una clave general de la cuenta.

Las expresiones regulares merecen desconfianza en este contexto. Pueden servir para un campo con una gramática cuidadosamente definida, pero son un mal sustituto del análisis de URL, JSON, comandos de shell o encabezados HTTP. Una expresión que parece restringir una ruta puede fallar cuando la descodificación, la normalización o un enrutador posterior interpreta los mismos bytes de otra forma.

Sallyport adopta deliberadamente una ruta más pequeña para las acciones de los agentes: mantiene los secretos en su almacén cifrado y ejecuta acciones HTTP o SSH sin exponer esos secretos al agente. Esta separación solo es útil cuando la puerta de enlace de acciones valida la acción antes de pedir al almacén que use una credencial.

## La validación debe sobrevivir a la entrega al transporte

Un validador perfecto no sirve de nada si una capa posterior puede alterar el destino. El límite necesita una entrega que conserve lo aprobado.

No valides un objeto de solicitud mutable para después entregarlo al middleware que puede reescribir URL, combinar encabezados, adjuntar cookies, seguir redirecciones o seleccionar un proxy a partir de variables de entorno controladas por el agente. Valida en un plan nuevo e inmutable. Proporciona al transporte la entrada menos expresiva posible.

El orden de ejecución debe ser fijo y aburrido:

1. Analiza la acción propuesta por el agente en campos tipados.
2. Valida el destino canónico y la forma permitida de la solicitud.
3. Serializa una sola vez el contenido aprobado y registra su resumen.
4. Construye la conexión usando el esquema, host y puerto aprobados.
5. Inyecta la credencial en el transporte de confianza justo antes de la transmisión.

No inyectes antes para facilitar el código de reintentos. Un reintento es otra transmisión y necesita las mismas comprobaciones de destino y solicitud. Puede reutilizar un plan inmutable aprobado si nada importante ha cambiado. Si un reintento cambia el host, la ruta, el modo del proxy, el método, el cuerpo o el esquema de autenticación, es una acción nueva.

La reutilización de conexiones es segura solo si la biblioteca HTTP mantiene intactos los límites de autoridad. Una conexión agrupada no debe permitir que los metadatos de autorización de una solicitud se filtren a la siguiente. Parece obvio, pero los mapas de encabezados mutables compartidos y los interceptores con un alcance incorrecto son fuentes habituales de este tipo de errores.

En SSH, el fallo equivalente consiste en validar un nombre de host pero permitir que un envoltorio de comandos pase un `ProxyCommand`, socket de agente, host de salto de destino o comando remoto distinto después de la aprobación. La decisión de confianza debe vincular toda la ruta y la solicitud de ejecución, no solo el primer nombre de host visible para el agente.

## Prueba los fallos que las pruebas de integración normales omiten

Un inyector de credenciales debe tener pruebas que demuestren que rechaza entradas sospechosas. Las pruebas del caso correcto confirman que una llamada API funciona. Las pruebas de rechazo confirman que el diseño sigue significando lo que crees después de una actualización de la biblioteca o de una nueva función del agente.

Crea una tabla de acciones propuestas y decisiones esperadas. Incluye como mínimo estos casos:

- Un origen HTTPS y una ruta aprobados exactamente, que funcionan.
- Un sufijo de nombre de host como `api.billing.example.attacker.invalid`, que falla.
- Una URL con información de usuario antes de `@`, que falla.
- Un host válido en un puerto inesperado, que falla.
- Una redirección a otro origen, que falla sin enviar una credencial.
- Un encabezado `Host`, `Authorization` o de proxy inesperado, que falla.
- Un cuerpo que cambia después de la aprobación, que falla en la comprobación del resumen.

Usa un servidor de pruebas local que registre todos los encabezados recibidos. Es más convincente que comprobar un objeto de solicitud simulado. La prueba debe afirmar que el servidor situado en un destino de redirección no aprobado no recibió ninguna clave API, token bearer, cookie ni encabezado de firma. Prueba tanto los códigos de respuesta de redirección que conservan el cuerpo como los que suelen convertirse en GET, porque los valores predeterminados de las bibliotecas varían.

Prueba también las discrepancias entre analizadores. Entrega al validador y al cliente HTTP de producción las mismas URL inusuales, incluidos la codificación porcentual, los puertos vacíos, las barras duplicadas, los segmentos con puntos, los literales IPv6 si son compatibles y los nombres internacionalizados si son compatibles. Si discrepan sobre la autoridad o la ruta, rechaza esa categoría hasta que puedas hacer coherente el comportamiento.

Los registros de auditoría deben capturar la decisión del validador antes de la llamada de red y el resultado del transporte después. Un registro útil indica qué referencia de credencial se solicitó, qué origen canónico y ruta se aprobaron, si apareció una redirección y por qué se denegó una solicitud. Nunca contiene material secreto. Si no puedes reconstruir por qué se usó una credencial saliente, no tienes pruebas suficientes para revisar un incidente.

## La aprobación solo sirve cuando la solicitud es concreta

Un aviso de aprobación humana puede impedir que un agente use una credencial en el momento equivocado, pero el aviso debe describir una solicitud que el sistema ya haya validado. Pedir aprobación primero y analizar después convierte a la persona en un analizador de URL débil.

Muestra el origen, la acción, el método, la ruta y los campos empresariales importantes. En una llamada de pago, muestra el destinatario, la divisa y el importe. En el control de código fuente, muestra el repositorio, la rama y la operación. En una API de infraestructura, muestra la cuenta, la región, el recurso y el efecto destructivo. Mantén los secretos y los cuerpos de solicitud sin límites fuera del aviso.

La aprobación por llamada tiene sentido para credenciales que pueden causar un daño importante. La aprobación por sesión funciona para llamadas repetidas y de bajo riesgo cuando la sesión tiene una identidad de proceso reconocible y una vida corta. Ninguna sustituye la validación de solicitudes. Un usuario puede aprobar un proceso de programación de confianza, pero eso no significa que cualquier URL creada por ese proceso merezca la misma credencial.

La autorización por sesión de Sallyport y sus aprobaciones opcionales por llamada encajan después de este límite: la aplicación puede pedir a una persona que autorice un proceso de agente conocido o un uso concreto de una credencial, mientras que la ruta de acciones de confianza conserva el secreto y registra la acción. La aprobación debe cubrir el plan de ejecución concreto y validado, no una descripción informal de la intención del agente.

El primer cambio normalmente no es un proyecto de políticas grande. Desactiva las redirecciones automáticas en las llamadas autenticadas. Rechaza los encabezados de enrutamiento y credenciales controlados por el agente. Analiza el destino como un origen canónico. Después vincula el método, la ruta, los encabezados y el cuerpo antes de que entre cualquier secreto en la solicitud. Ese orden evita toda una familia de filtraciones que ningún sistema cuidadoso de almacenamiento de secretos puede reparar.
