Cómo las firmas de solicitudes HTTP limitan las llamadas a API de los agentes de IA
Las firmas de solicitudes HTTP vinculan las llamadas a API operadas por IA con un método, destino, cuerpo y hora. Aprende sobre campos seguros, controles contra repeticiones y reglas para la desviación del reloj.

Un agente de IA con un token bearer tiene, en la práctica, la misma libertad que cualquier otro proceso capaz de leer ese token. Puede llamar ahora a un endpoint permitido, reintentarlo más tarde, enviar el token a otro host si el código lo permite y crear una solicitud cuyo cuerpo tenga poca relación con la instrucción del usuario que inició la ejecución. El servidor ve que alguien posee la credencial, pero poco más.
Las firmas de solicitudes HTTP mejoran esta situación al vincular la autorización con un mensaje concreto. Un diseño sólido puede hacer que una firma solo sea válida para POST https://api.example.test/v1/releases/42, solo con el cuerpo exacto que preparó el agente, solo durante un periodo breve y solo bajo una identidad de firma. Es un control útil. No sustituye a la autorización, la aprobación ni el aislamiento de credenciales.
Los equipos suelen equivocarse de dos formas opuestas. Algunos conservan los tokens bearer porque firmar parece complicado y luego descubren que un agente puede usar un token con permisos demasiado amplios desde cualquier lugar al que pueda realizar una solicitud saliente. Otros firman todos los encabezados que genera su biblioteca HTTP y construyen un verificador tan frágil que los proxies normales, la desviación del reloj o una actualización de la biblioteca rompen la producción. El diseño correcto vincula los campos que cambian el significado o el destino de una acción y hace que la frescura y la verificación sean lo bastante sencillas como para operar sin sorpresas.
Las firmas limitan un mensaje, mientras que los tokens bearer solo demuestran posesión
Un token bearer responde a una pregunta: ¿esta solicitud presentó un secreto aceptado actualmente? Normalmente no vincula el secreto con el método, el destino, el cuerpo ni la hora de la solicitud. Los tokens de acceso OAuth pueden incluir permisos, audiencias y caducidad, lo que ayuda, pero quien los posee todavía puede usar cada permiso autorizado hasta que caduquen.
Una firma de solicitud responde a una pregunta criptográfica más concreta: ¿quien posee esta clave de firma autorizó este conjunto definido de componentes de la solicitud? El servidor reconstruye la entrada firmada, la verifica con la clave pública registrada o con el secreto compartido, comprueba los límites temporales y después aplica la autorización normal. El orden importa. La verificación de la firma establece la integridad del mensaje y la identidad del firmante. La autorización decide si esa identidad puede realizar la acción.
Imagina un servicio de despliegue con un token bearer limitado a crear versiones. Primero, un agente crea una versión de staging sin riesgo. Más tarde, una inyección de instrucciones le indica que cree una versión de producción. El token permite ambas solicitudes si sus permisos cubren los dos entornos. Sustituir el token por una solicitud firmada no corrige por sí solo ese error de autorización. Si la identidad de firma puede crear versiones de producción, puede firmar una solicitud de producción.
Las firmas sí proporcionan al servicio protecciones que un encabezado bearer normal no ofrece:
- Una solicitud firmada capturada caduca rápidamente y no se puede repetir para siempre.
- Una firma copiada normalmente no puede trasladarse de
POST /v1/staging/releasesaPOST /v1/production/releases. - Un cuerpo JSON modificado no supera la verificación cuando se firma el resumen del cuerpo.
- El servicio puede identificar una credencial de firma sin aceptarla como un valor de encabezado reutilizable.
- Un verificador puede registrar exactamente qué campos aprobó el firmante.
No describas esto como un reemplazo de los tokens de acceso en todas las arquitecturas. Muchos sistemas usan ambos. Un token de acceso puede identificar al usuario o la carga de trabajo delegada, mientras que una firma de solicitud vincula cada mensaje con una credencial de firma específica del agente. En otros sistemas, una solicitud firmada autentica directamente al emisor y el servidor deriva los permisos de la identidad de firma.
La diferencia tiene una consecuencia práctica para los agentes de IA: una firma convierte la acción en un objeto concreto que puedes inspeccionar, aprobar y registrar. Un token bearer aparece sobre todo como una capacidad disponible en el entorno. Esa diferencia permite revisar la acción, pero solo si el límite de tus herramientas impide que el agente extraiga el secreto de firma.
Usa RFC 9421 en lugar de inventar una cadena canónica
RFC 9421, HTTP Message Signatures, define una forma estructurada de declarar los componentes cubiertos y enviar una firma. Evita el formato privado habitual en el que un lado une campos con saltos de línea, otro normaliza una URL de forma distinta y ambos culpan a la criptografía cuando falla la verificación.
El RFC separa dos ideas. Signature-Input declara una etiqueta, los componentes cubiertos y parámetros como created, expires, nonce, alg y keyid. Signature contiene el valor criptográfico resultante bajo la misma etiqueta. El verificador construye la base de firma a partir de los componentes y parámetros declarados y después la verifica.
Una solicitud compacta podría verse así:
POST /v1/releases/42?environment=staging HTTP/1.1
Host: api.example.test
Content-Type: application/json
Content-Digest: sha-256=:rPMyV6WTE4Duf0JApE9tXvDYy9EzrgFQbq3e2XTCwbs=:
Signature-Input: sig1=("@method" "@authority" "@path" "@query" "content-digest" "date");created=1735689600;expires=1735689660;keyid="agent-release-17";alg="ed25519"
Signature: sig1=:BASE64_SIGNATURE_BYTES:
Date: Wed, 01 Jan 2025 00:00:00 GMT
{"version":"2025.01.01","notes":"staging validation"}
El valor del resumen anterior muestra la forma que tendría en la transmisión, pero no corresponde al resumen del JSON de ejemplo. Un cliente de producción calcula el resumen a partir de los bytes exactos que enviará. Si vuelve a serializar el JSON después de firmarlo, habrá creado una fuente de errores.
RFC 9421 es deliberadamente flexible. Esa flexibilidad resulta útil para intermediarios y distintas versiones de HTTP, pero significa que el contrato de tu API debe definir un perfil exacto. Indica el algoritmo permitido, los componentes obligatorios cubiertos, la duración máxima de la firma, el formato de keyid, el algoritmo de resumen aceptado y si se requiere un nonce. Si el contrato solo dice que las solicitudes deben estar firmadas, cada autor de cliente hará suposiciones distintas.
Ed25519 es una opción predeterminada razonable cuando tu servicio puede registrar claves públicas. El servidor guarda una clave pública de verificación y la pérdida de ese registro público no expone ningún secreto de firma. Las firmas HMAC pueden funcionar cuando un componente de confianza y la API comparten un secreto, pero ese secreto debe existir en ambos lados. En los flujos de agentes, esto suele aumentar el número de lugares donde puede filtrarse un secreto reutilizable.
Evita un esquema propietario salvo que una limitación del protocolo lo exija. Los formatos propietarios suelen firmar la URL sin procesar en un cliente, la ruta decodificada en otro y una representación diferente del host en el verificador. RFC 9421 te proporciona identificadores de componentes definidos y campos estructurados. Úsalos y prueba el perfil exacto que publiques.
Vincula el método, el destino y la consulta que definen la acción
Un agente debería firmar todos los campos de la solicitud que cambien adónde se dirige o qué operación del servidor invoca. Para la mayoría de las llamadas a API, el conjunto mínimo útil es @method, @authority, @path y @query. También puedes usar @target-uri si quieres un componente que cubra toda la URI de destino, pero no firmes ambos formatos sin una razón que tus implementadores puedan explicar.
@method impide reutilizar una firma destinada a GET como DELETE. Parece obvio, pero los esquemas creados a mano lo omiten con frecuencia porque un ingeniero supone que la ruta ya implica la operación. Las API REST suelen reutilizar una ruta con métodos distintos. El método cambia la acción.
@authority vincula la autoridad del host y del puerto. Impide que una firma emitida para un origen de API valide contra otro origen que acepte la misma credencial. Esto importa en organizaciones con hosts de vista previa, staging y producción. Una identidad de firma destinada a staging no debería obtener autoridad sobre producción porque un agente o una redirección cambió el host.
@path y @query requieren el mismo cuidado. Muchas API colocan parámetros importantes en la cadena de consulta:
POST /v1/invoices/817/refund?amount=2500¤cy=USD
Si la firma solo cubre la ruta, un atacante que pueda alterar la solicitud durante el tránsito puede cambiar el importe o la divisa. Si el servidor obtiene dry_run, environment, force, page_size, include_deleted o un selector de tenant de la consulta, esos valores forman parte de la acción. Firma @query.
RFC 9421 también define @query-param, que puede cubrir un parámetro concreto por nombre. Tiene sentido en protocolos donde algunos parámetros de consulta quedan explícitamente fuera de la decisión de seguridad, como los datos de trazabilidad. Para una API interna usada por agentes, firmar toda la consulta suele resultar menos sorprendente. Cada parámetro se convierte en parte de la solicitud aprobada y los revisores no tienen que recordar una lista de excepciones.
No trates la normalización de URL a la ligera. Tu verificador debe usar la semántica de componentes especificada por RFC 9421 y por la biblioteca elegida. No decodifiques los escapes de porcentaje para volver a codificarlos a mano. No ordenes los parámetros de consulta repetidos salvo que la definición del componente seleccionado lo haga. El destino de una solicitud son bytes en la transmisión antes de convertirse en un objeto cómodo para la aplicación.
Las redirecciones necesitan una regla firme: no lleves automáticamente una solicitud firmada a través de una redirección hacia otra autoridad. Una firma que cubra la autoridad original debe fallar en el nuevo host, y eso es correcto. Deja que el cliente reciba la redirección, aplique una lista de permitidos explícita, construya una solicitud nueva y firme esa solicitud. Para solicitudes que modifican datos, muchos equipos deberían rechazar las redirecciones directamente.
Un cuerpo firmado necesita un resumen, no confianza en JSON
Firma content-digest cuando el cuerpo influya en el resultado. Esto incluye casi todas las solicitudes de modificación JSON, las cargas multipart, los envíos de formularios y las operaciones masivas. También puede tener sentido firmar content-type cuando el servidor interprete los mismos bytes de forma distinta según el tipo de contenido.
El IETF define Content-Digest en RFC 9530. Transporta un resumen del contenido del mensaje HTTP mediante la sintaxis de Structured Fields. La firma cubre el encabezado del resumen en lugar de cubrir directamente un cuerpo enorme, mientras el receptor calcula el resumen del cuerpo y lo compara antes de aceptar la firma. Así, la firma obtiene una representación de tamaño fijo del contenido exacto.
Una secuencia de envío segura es sencilla y debe mantenerse en este orden:
- Construye el objeto final de la solicitud, incluidos los parámetros de consulta y los encabezados que afecten a su interpretación.
- Serializa el cuerpo una sola vez en bytes y conserva esos bytes para la transmisión.
- Calcula
Content-Digestsobre esos bytes. - Crea
Signature-Inputsobre los componentes elegidos y firma después su base de firma. - Envía los bytes y encabezados sin modificar.
El fallo habitual es más mundano que un ataque criptográfico. Una aplicación serializa un objeto para calcular el resumen, lo firma y después una ayuda HTTP vuelve a serializar el objeto. Cambian el orden de los miembros JSON, los escapes, los espacios, el formato numérico o un campo de marca de tiempo. El verificador informa correctamente de un resumen distinto. Entonces los desarrolladores eliminan la protección del cuerpo para poder publicar el cambio. Esa no es la solución correcta.
Entrega al transporte un búfer de bytes, un flujo o un cuerpo de solicitud inmutable. Si la transmisión por flujo hace imposible calcular un resumen completo antes de enviar, usa un protocolo diseñado para ese caso y pruébalo a fondo. No omitas silenciosamente el resumen del cuerpo de una operación de alto impacto porque la transmisión por flujo resulte incómoda.
Los encabezados necesitan una regla más limitada. Firma un encabezado cuando un receptor o intermediario pueda usarlo para cambiar el significado de seguridad de la solicitud. content-type es un candidato. Un encabezado de tenant también lo es si el servidor lo usa para seleccionar una cuenta. Un encabezado de idempotencia es candidato si importan los reintentos y los efectos duplicados. Un encabezado de diagnóstico normalmente no lo es.
Firmar user-agent, accept, los identificadores de trazabilidad, los encabezados de conexión y todos los encabezados que genere tu biblioteca crea clientes frágiles. Los proxies pueden añadir, combinar o reescribir encabezados normales. HTTP permite transformaciones legítimas. Quieres que la firma rechace cambios semánticos, no que convierta una variación de transporte inofensiva en una interrupción.
Las ventanas de frescura deben tolerar la desviación, pero rechazar el trabajo en cola
Los límites temporales hacen que las firmas capturadas duren poco. También provocan incidentes innecesarios cuando los equipos fingen que todas las estaciones de trabajo, contenedores y máquinas virtuales tienen la hora perfecta. La respuesta es una regla de aceptación limitada y una sincronización razonable del reloj, no un margen de dos horas.
Usa created y expires en Signature-Input. Una duración de sesenta segundos funciona bien para llamadas de acción interactivas cuando el agente firma justo antes de enviar. Unos minutos pueden ser apropiados para una red poco fiable o un flujo de trabajo que reintenta después de un fallo temporal. La API debe documentar una duración máxima y hacerla cumplir. No permitas que los clientes elijan una caducidad arbitraria porque les resulte incómoda.
El verificador debería evaluar tres casos por separado:
- Rechaza una solicitud cuyo momento
createdesté demasiado adelantado, más allá de una pequeña tolerancia de desviación configurada. - Rechaza una solicitud cuyo momento
expiresya haya pasado. - Rechaza una solicitud cuya duración,
expires - created, supere el máximo de la API aunque todavía no haya caducado.
Un servidor puede aceptar un reloj de cliente ligeramente atrasado o adelantado sin aceptar trabajo obsoleto. Por ejemplo, un servicio puede permitir una desviación futura moderada y un intervalo de caducidad corto. Los valores exactos dependen del lugar donde se ejecuten los clientes, pero el principio no cambia: la tolerancia de desviación no es una ventana de repetición que dejes abierta toda la tarde.
No uses el encabezado HTTP Date como único mecanismo de frescura. Puede ser útil como componente cubierto para compatibilidad y diagnóstico, pero created y expires viven directamente en los parámetros de la firma y son menos ambiguos. Si firmas ambos, indica qué valores usa el servidor para hacer cumplir la regla cuando no coinciden. Un verificador que acepta cualquiera de los dos da a los atacantes una ventaja innecesaria.
Las tareas de agentes en cola exponen un error de diseño oculto. Supón que un agente crea solicitudes firmadas a las 09:00, una aprobación humana espera hasta las 09:20 y un trabajador envía la solicitud antigua después de la aprobación. El servicio debería rechazarla. La tarea necesita un nuevo evento de firma después de la aprobación, porque la acción aprobada debe tener una hora actual y un destino actual significativos.
Para las operaciones que admiten reintentos, guarda un identificador de idempotencia en un encabezado o en un campo del cuerpo firmado y cúbrelo con la firma. El cliente puede crear una firma nueva para cada reintento, mientras el servidor reconoce la operación lógica y evita efectos duplicados. Reutilizar una solicitud firmada caducada no es una estrategia de reintento.
Los nonces detienen la repetición solo cuando el servidor los recuerda
Una caducidad corta limita la repetición, pero no impide que un atacante repita varias veces una solicitud capturada durante esa ventana. Que eso importe depende del endpoint. Repetir una lectura inofensiva tiene poco efecto. Repetir una transferencia de dinero, la eliminación de una cuenta o un cambio de infraestructura puede ser grave.
Un nonce aborda ese riesgo cuando el servidor trata cada nonce como de un solo uso para una identidad de firma. El cliente genera un valor impredecible, lo coloca en los parámetros de la firma o en un encabezado cubierto y el servidor registra su uso correcto hasta que caduca la firma. Una segunda solicitud con el mismo firmante y nonce falla aunque su firma siga siendo válida.
Esta es la parte que los equipos omiten cuando dicen que usan nonces. Un nonce que el servidor no conserva no es más que otra cadena aleatoria. No demuestra unicidad. Una caché o tabla de base de datos compartida necesita una operación de creación atómica para que las repeticiones simultáneas no superen ambas la verificación.
Usa un almacén de nonces cuando el daño de una repetición justifique el coste operativo. Tendrás que elegir el periodo de conservación, los límites de tamaño, el comportamiento ante fallos y la partición. Conserva un nonce aceptado hasta el último momento en que el servidor podría aceptar la solicitud. Define los registros por identidad del firmante y nonce, no solo por nonce, porque identidades de firma distintas pueden generar el mismo valor sin afectar a la seguridad.
No hagas obligatorio un nonce para todas las llamadas de bajo riesgo y gran volumen solo porque suene más seguro. Esa decisión puede convertir una interrupción del almacén de nonces en una interrupción de las lecturas inofensivas. Un perfil práctico puede exigirlo para modificaciones irreversibles y basarse en firmas de corta duración y controles de idempotencia para el resto. Escribe la regla endpoint por endpoint.
Las comprobaciones de nonce tampoco sustituyen a la idempotencia. El nonce dice que este mensaje firmado debe aceptarse una vez. Un identificador de idempotencia dice que varios intentos de reintento firmados por separado representan una única operación de negocio prevista. Resuelven fallos distintos.
La verificación debe fallar de forma segura antes de que el código de la aplicación vea la solicitud
La puerta de enlace de la API o el punto de entrada de la aplicación debe verificar la solicitud antes de que un controlador de ruta analice los parámetros de acción, inicie un trabajo o consulte servicios posteriores. Un controlador que lee el cuerpo y realiza trabajo antes de verificar ya ha renunciado a la propiedad de seguridad que la firma debía proporcionar.
Un verificador necesita una secuencia predecible:
- Analiza
Signature-InputySignaturecomo Structured Fields, y rechaza la sintaxis mal formada y las ambigüedades por duplicación. - Selecciona una etiqueta de firma permitida y rechaza algoritmos desconocidos, componentes obligatorios ausentes o combinaciones de componentes prohibidas.
- Resuelve
keyidhasta una identidad de firma activa y obtiene su material de verificación. - Reconstruye la base de firma según RFC 9421, usando la solicitud recibida en lugar de una URL de aplicación reconstruida.
- Comprueba la firma criptográfica, el resumen del cuerpo, los límites temporales, el estado del nonce cuando sea necesario y después la autorización.
Mantén separados en los registros el fallo criptográfico y el fallo de autorización. Las respuestas públicas pueden seguir siendo deliberadamente sencillas. Un 401 o 403 con un código de error estable basta para los clientes. Internamente, registra si el servicio rechazó la solicitud por un keyid desconocido, una firma caducada, un resumen no válido, una autoridad distinta, un nonce reutilizado o permisos insuficientes.
No registres los bytes de la firma como si fueran material de depuración inofensivo. Las firmas de clave pública no son secretas como las credenciales HMAC, pero los registros completos de solicitudes suelen contener encabezados de autorización, datos personales y cuerpos. Registra un identificador de solicitud, la identidad del firmante, los nombres de los componentes cubiertos, un valor de resumen si tu política de conservación lo permite y la decisión. Limita la captura sin filtrar a un procedimiento deliberado para incidentes.
Los vectores de prueba importan más que la prosa. RFC 9421 incluye ejemplos, pero el perfil de tu API necesita sus propios casos. Mantén solicitudes que deban verificarse y mutaciones que deban fallar: cambio de método, consulta modificada, cambio de un byte del cuerpo, firma caducada, valor created futuro, autoridad incorrecta, keyid alterado y nonce repetido. Ejecútalos en todas las implementaciones de cliente compatibles.
Un verificador de firmas debería rechazar la ambigüedad, aunque un analizador permisivo pudiera adivinar la intención del emisor. Los encabezados duplicados, la serialización incoherente de componentes y los algoritmos no compatibles son errores de protocolo. Un agente no necesita que el servidor sea complaciente; necesita que sea exacto.
Mantén el material de firma fuera del contexto del agente
Dar a un agente de programación de IA una clave privada de firma o un secreto HMAC anula buena parte del propósito de firmar. La clave puede aparecer en la salida de una herramienta, el historial del shell, archivos temporales, informes de errores o una instrucción que ordene al agente imprimir su entorno. Incluso un agente bien comportado tiene demasiada superficie indirecta para manejar una credencial reutilizable.
En su lugar, expón un límite de acciones estrecho. El agente proporciona el método, el destino permitido, los encabezados y el cuerpo a un componente local o remoto de confianza. Ese componente valida el objetivo permitido, obtiene la aprobación cuando el flujo la requiere, construye la lista de componentes cubiertos, firma justo antes del envío y devuelve la respuesta. El agente no recibe ni un secreto en texto plano ni un marcador falso que pueda reenviar accidentalmente.
Este límite también hace concreta la revisión de autoridad. Una identidad de firma puede limitarse a un servicio, entorno, familia de rutas y clase de acción. Si el agente solo necesita abrir una versión de staging, no le concedas una credencial capaz de firmar ajustes de facturación o eliminaciones en producción. La autorización del servidor sigue siendo responsable de aplicar esos límites después de verificar la firma.
Sallyport aplica esta separación a las acciones HTTP: la aplicación conserva las credenciales de API en su bóveda cifrada y realiza la llamada HTTP, de modo que un agente compatible con MCP recibe el resultado, no la credencial en texto plano.
No confundas una puerta de enlace de acciones con un estándar de firmas de solicitudes. RFC 9421 indica a dos partes HTTP cómo autenticar determinados componentes de un mensaje. Una puerta de enlace de acciones decide dónde vive el material de firma, cuándo ve una persona una aprobación y qué registro de auditoría existe alrededor de una ejecución del agente. Puedes usar una sin la otra, pero la combinación resulta útil cuando las herramientas autónomas actúan sobre API con consecuencias importantes.
Si dependes de un firmante local, trata su interfaz local como un límite de autorización. Vincula las solicitudes al proceso que llama siempre que sea posible, rechaza destinos arbitrarios y asegúrate de que un proceso de agente no pueda usar en silencio la sesión aprobada de otro proceso. Un servicio local que firma cualquier URL enviada por cualquier programa local simplemente ha trasladado una capacidad bearer detrás de un socket.
La aprobación y las firmas responden preguntas distintas
Una aprobación humana registra que alguien permitió una clase concreta de acción del agente. Una firma de solicitud registra que una identidad de firma autorizó un mensaje HTTP definido. Ninguno de los dos registros demuestra lo que demuestra el otro, salvo que el diseño los vincule explícitamente.
Para las llamadas de alto impacto, muestra en la pantalla de aprobación los campos que cubrirá la firma: método, autoridad, ruta, parámetros de consulta relevantes, resumen del cuerpo o un resumen legible del cuerpo, identidad de firma y caducidad. Si un usuario aprueba POST /v1/releases/42?environment=staging, el firmante no debe poder sustituir después staging por producción mediante un parámetro de consulta sin firmar.
Aquí es donde resumir solo un cuerpo opaco puede perjudicar la revisión humana. El resumen criptográfico demuestra la identidad de los bytes, pero no dice casi nada a una persona. Conserva ambos artefactos: una representación canónica de la solicitud para la revisión y un resumen para la integridad. La vista de revisión debe derivarse del mismo objeto de solicitud inmutable que enviará el firmante, no de un plan representado por separado.
La aprobación de una sesión puede ser adecuada para una ejecución breve del agente con muchas llamadas de bajo impacto. La aprobación por llamada es mejor para eliminaciones, publicaciones externas, cambios financieros o cualquier operación que un atacante pudiera ocultar entre el tráfico habitual. No pidas aprobación para cada lectura solo para afirmar que existe control humano. La gente hará clic sin leer y habrás creado fatiga de aprobación sin una decisión significativa.
El registro de auditoría debe incluir la identidad del firmante, los componentes cubiertos, la duración de la firma, la decisión de autorización, la referencia de aprobación si existe, el estado de la respuesta y un identificador de solicitud. Un registro legible ayuda al operador a responder una pregunta sencilla después de un incidente: ¿qué envió el agente, bajo la autoridad de quién y el servidor lo aceptó?
Los fallos que merece la pena ensayar suelen ser fallos normales de ingeniería
Los errores de implementación más peligrosos no son curvas elípticas rotas. Son campos sin firmar, canonicalización incoherente, trabajo obsoleto y secretos colocados donde los agentes pueden leerlos.
Un fallo aparece cuando un equipo firma @method, @path y date, pero omite @query. Su API de versiones acepta normalmente ?environment=staging. Más tarde, un cambio de mantenimiento añade ?environment=production al mismo endpoint. Un error del proxy o un componente local hostil cambia el parámetro después de la firma. La firma se verifica, el controlador recibe producción y el registro de auditoría afirma engañosamente que el agente envió una solicitud firmada válida. La firma hizo exactamente lo que le pidió la lista de componentes. La lista estaba incompleta.
Otro fallo aparece cuando los desarrolladores aceptan firmas de diez minutos para reducir las incidencias relacionadas con el reloj. Un agente firma una solicitud de eliminación, escribe todos los encabezados en un registro de depuración y un desarrollador copia el registro en una incidencia. Cualquiera que tenga acceso a esa incidencia puede repetir la solicitud durante buena parte de la jornada. Una caducidad breve no elimina la filtración original, pero limita mucho su utilidad. Exigir un nonce para las eliminaciones elimina la ventana restante de repetición después de la primera aceptación.
Un tercer fallo ocurre con credenciales HMAC compartidas. Varios agentes usan el mismo secreto porque aprovisionar identidades individuales parecía demasiado trabajo. Cuando una auditoría encuentra una llamada destructiva, el equipo puede identificar la integración compartida, pero no la ejecución del agente, la aprobación del usuario ni el proceso que la originó. Da identidades de firma distintas a límites de autoridad distintos. La atribución forma parte de la respuesta a incidentes, no es un lujo de los informes.
Empieza con un endpoint que modifique datos y escribe el perfil antes de elegir una biblioteca. Especifica su autoridad permitida, los componentes obligatorios, la regla del resumen del cuerpo, la duración de la firma, la tolerancia de desviación, la regla de repetición, el algoritmo de firma y la relación con la autorización. Después crea pruebas negativas que modifiquen cada campo cubierto. Si una prueba puede cambiar un campo relevante de la solicitud y aun así verificarse, no publiques el perfil.
Una solicitud firmada debería ser fácil de rechazar por el motivo correcto. Ese criterio orienta el diseño hacia una autoridad limitada, mensajes de corta duración, cuerpos inmutables y registros que muestran qué ocurrió después de que actuó el agente.
FAQ
¿Cuál es la diferencia entre un token bearer y una firma de solicitud HTTP?
Un token bearer autoriza a quien lo posee. Una firma de solicitud demuestra que quien tiene la clave de firma aprobó una forma concreta de solicitud, como un método, destino, marca de tiempo y resumen del cuerpo determinados. Reduce la repetición y la sustitución de solicitudes, pero no decide si el agente debía tener permiso para actuar.
¿Las firmas de solicitudes HTTP hacen seguros a los agentes autónomos?
No. Una firma vincula una solicitud con una clave de firma, pero un agente que puede usar esa clave todavía puede firmar una solicitud destructiva dentro de su autoridad. Sigues necesitando credenciales limitadas, autorización en el servidor, aprobación para acciones sensibles y un registro de auditoría.
¿Qué campos HTTP debería firmar un agente?
Empieza con @method, @target-uri o @authority junto con @path y @query, content-digest para las solicitudes con cuerpo y un valor de frescura como date o @created. Añade encabezados solo cuando el servidor tome una decisión de seguridad a partir de ellos. No firmes encabezados irrelevantes solo porque un SDK los envíe.
¿Debe una firma de solicitud incluir el cuerpo de la solicitud HTTP?
Firma content-digest siempre que el cuerpo cambie la acción, lo que incluye la mayoría de las solicitudes POST, PUT, PATCH y DELETE con JSON. Sin un resumen, un intermediario o un error entre la firma y el envío puede sustituir el cuerpo mientras la firma sigue siendo válida. Firmar el método y la ruta no protege un contenido sin firmar.
¿Cómo deben gestionar las API la desviación del reloj en las solicitudes firmadas?
Usa un periodo de validez corto y permite una tolerancia pequeña y explícita para los errores normales del reloj. Rechaza las solicitudes antiguas y las que estén demasiado adelantadas, y haz que los clientes corrijan sus relojes mediante la sincronización habitual en lugar de ampliar indefinidamente la ventana de aceptación. Si los agentes ponen el trabajo en cola durante mucho tiempo, firma justo antes de transmitirlo.
¿Las solicitudes de API firmadas necesitan un nonce?
Un nonce puede impedir la repetición dentro de una ventana de validez si el servidor almacena cada nonce aceptado por credencial o identidad de firma. Ese almacenamiento tiene un coste y necesita expiración, por lo que muchas API usan firmas de corta duración para llamadas de bajo riesgo y añaden nonces para transferencias, eliminaciones u otras acciones en las que una sola repetición sería inaceptable. El nonce debe estar firmado; de lo contrario, un atacante puede sustituirlo.
¿Es RFC 9421 el estándar adecuado para firmar solicitudes de API?
RFC 9421 define las firmas de mensajes HTTP y proporciona nombres de componentes estándar como @method, @authority, @path y @query. Es una buena opción de formato de transmisión cuando el cliente y el servidor controlan la integración. No define tu modelo de autorización, el almacén de repetición ni la distribución de claves de firma.
¿Debe un agente de IA tener la clave de firma de la API?
Por lo general, no. Un secreto copiado en el contexto de un agente convierte cada inyección de instrucciones, filtración de registros y error de una herramienta en un incidente de credenciales. Dale al agente una interfaz de acciones limitada, deja que un componente de confianza conserve la credencial y registra la solicitud exacta que ese componente envía.
¿Por qué se rechazan firmas de solicitudes que son válidas?
Primero distingue las firmas mal formadas de las firmas válidas que no tienen permiso, y usa códigos de estado y códigos internos de motivo distintos. Mantén los errores públicos escuetos para que los atacantes no puedan explorar la lógica de verificación, pero registra en el servidor la lista de componentes fallida, el identificador del firmante, los valores del reloj y la entrada canónica. Nunca registres el secreto de firma.
¿Pueden las firmas de solicitudes HTTP sustituir a TLS?
No. TLS protege la conexión mientras existe; una firma de mensaje viaja con la solicitud y permite al destinatario verificar determinados campos. La mayoría de las llamadas a API necesitan TLS de todos modos, porque las firmas no ocultan el contenido de las solicitudes, el contenido de las respuestas ni los tokens bearer que se transporten junto con ellas.