Signed Agent Cards: prevención de envenenamiento y suplantación con JWS
Cuando los agentes de IA se descubren entre sí en redes públicas recuperando un archivo agent.json,
la confianza no puede depender ciegamente de la red. Una tarjeta sin firmar está a solo un secuestro de DNS o
un error de CDN de redirigir sistemas autónomos a endpoints maliciosos. En A2A v1.0, las Signed Agent Cards
resuelven este problema mediante JSON Web Signatures (JWS).
Por qué las tarjetas no firmadas son vulnerables
En la Especificación del protocolo A2A, el descubrimiento está diseñado para ser ligero, estático y sin autenticación: un agente cliente realiza una simple petición HTTP GET a /.well-known/agent.json.
Si bien esta simplicidad aceleró la adopción del ecosistema, introduce una superficie de ataque crítica conocida en seguridad empresarial como Agent Card Poisoning (envenenamiento de Agent Card):
- Redirección de endpoints: Un atacante que comprometa una entrada DNS o un proxy perimetral puede reescribir el campo
supportedInterfaces[].url, enviando silenciosamente prompts sensibles a un servidor de escucha o suplantación. - Inyección de capacidades y prompts: Al manipular el array
skillso las descripciones, los actores maliciosos pueden engañar a los agentes llamantes para que deleguen tareas financieras o administrativas críticas a un modelo no verificado. - Suplantación de identidad: Sin verificación criptográfica, cualquiera puede alojar una tarjeta de agente afirmando en
provider.organizationque representa a una institución financiera de confianza o un proveedor de software reconocido.
Para defender las arquitecturas multiagente frente a estos riesgos, la especificación oficial mantenida por el repositorio a2aproject/A2A formaliza el array signatures basándose en el estándar RFC 7515: JSON Web Signature (JWS).
Anatomía del array signatures
En una Agent Card de A2A v1.0, la propiedad de nivel superior signatures contiene un array de objetos de firma. Esto permite que una tarjeta sea firmada por múltiples autoridades; por ejemplo, el proveedor que desarrolló el agente y un auditor de cumplimiento de seguridad externo.
Cada entrada adopta el formato estándar de serialización JWS Flattened JSON o el formato JWS compacto canónico:
{
"name": "Treasury Reconciliation Agent",
"version": "1.2.0",
"supportedInterfaces": [
{
"url": "https://agents.acme-finance.com/a2a/v1",
"protocolBinding": "JSONRPC",
"protocolVersion": "1.0"
}
],
"signatures": [
{
"protected": "eyJhbGciOiJFUzI1NiIsImtpZCI6IjIwMjYtMDktY29yZSIsInR5cCI6IkpXUyJ9",
"signature": "MEQCIFz8fV9Q2b6HqVqYx3...7k1vU8X3g"
}
]
}
Los campos dentro de cada objeto de firma funcionan de la siguiente manera:
protected: Cadena JSON codificada en Base64URL que contiene los parámetros del encabezado JWS:alg: El algoritmo criptográfico utilizado (comoES256oRS256).kid: Identificador de clave, que resuelve a la clave pública de verificación alojada en el almacén de confianza del proveedor.crit: (Opcional) Array de extensiones de encabezado críticas que el agente verificador debe reconocer obligatoriamente.
signature: Firma digital codificada en Base64URL calculada sobre la carga útil normalizada y el encabezado protegido.
Firma de un agent.json con ES256
Para firmar una Agent Card, la carga útil del documento debe canonicizarse de forma determinista (eliminando cualquier campo signatures existente antes de firmar) a fin de garantizar una generación consistente del hash en diferentes lenguajes y entornos de ejecución.
A continuación se muestra una implementación de referencia en Node.js utilizando la API estándar Web Crypto:
import crypto from 'node:crypto';
import fs from 'node:fs';
// 1. Leer tarjeta y eliminar firmas existentes para payload canónico
const rawCard = JSON.parse(fs.readFileSync('agent.json', 'utf8'));
const { signatures, ...unsignedPayload } = rawCard;
const payloadString = JSON.stringify(unsignedPayload);
// 2. Preparar JWS Protected Header
const header = {
alg: 'ES256',
kid: 'https://acme-finance.com/.well-known/jwks.json#key-2026',
typ: 'JWS'
};
const base64Url = (str) => Buffer.from(str).toString('base64url');
const protectedHeaderB64 = base64Url(JSON.stringify(header));
const payloadB64 = base64Url(payloadString);
const signingInput = `${protectedHeaderB64}.${payloadB64}`;
// 3. Firmar usando clave privada EC (P-256)
const privateKeyPem = fs.readFileSync('private-key.pem', 'utf8');
const signer = crypto.createSign('SHA256');
signer.update(signingInput);
signer.end();
const signatureB64 = signer.sign(privateKeyPem, 'base64url');
// 4. Adjuntar bloque de firmas a la Agent Card
const signedCard = {
...rawCard,
signatures: [
{
protected: protectedHeaderB64,
signature: signatureB64
}
]
};
fs.writeFileSync('agent.signed.json', JSON.stringify(signedCard, null, 2));
console.log('✓ Agent Card firmada con éxito usando ES256');
Cómo los agentes clientes verifican las firmas
Cuando un agente cliente recupera una Agent Card de un homólogo no verificado previamente, la verificación debe ocurrir antes de inspeccionar capacidades o invocar interfaces:
- Extracción: Analizar la clave
signaturesdel documento. Si no existe, marcarla como no verificada o rechazarla según las políticas de seguridad internas. - Decodificación de encabezado: Decodificar
protectedmediante base64url e inspeccionaralgykid. Rechazar algoritmos que no cumplan con la línea base de seguridad (por ejemplo, descartar algoritmos inseguros comononeo longitudes de clave obsoletas). - Obtención de claves: Obtener la clave pública referenciada por
kid. Verificar que el dominio de la URL de la clave coincida rigurosamente con elprovider.urldeclarado en la tarjeta. - Validación de firma: Reconstruir la carga útil no firmada, calcular el resumen canónico y verificar la firma criptográfica contra la clave pública.
Rotación de claves y lista de verificación de seguridad
Siga estas recomendaciones operativas al gestionar Signed Agent Cards en producción:
- Desacople el ciclo de vida de claves del despliegue: Utilice identificadores de clave (
kid) que apunten a una URL JWKS (/.well-known/jwks.json) en lugar de codificar claves estáticas directamente. Esto permite una rotación de claves transparente y sin interrupciones. - Exija HTTPS en todos los endpoints: Cada interfaz listada en
supportedInterfacesy cada endpoint de claves debe requerir HTTPS con certificados TLS válidos. - Vincule el dominio al proveedor: Asegúrese de que el dominio que aloja la Agent Card coincida exactamente con el
provider.urly el origen del endpoint JWKS. - Auditoría previa al despliegue: Compruebe siempre su tarjeta terminada en el validador antes de publicarla en la raíz pública de su dominio.
Preguntas frecuentes
¿Son obligatorias las firmas JWS en una Agent Card bajo A2A v1.0?
Son opcionales en el esquema base, pero muy recomendadas para cualquier agente en producción expuesto a redes públicas o entornos multinquilino. Sin firmas, los agentes clientes no pueden certificar si la tarjeta fue alterada en tránsito.
¿Qué es el "envenenamiento de Agent Card" (Agent Card Poisoning)?
Ocurre cuando un atacante altera un documento agent.json (por ejemplo, mediante envenenamiento de caché DNS, errores de configuración en CDN o ataques man-in-the-middle) para redirigir endpoints hacia infraestructuras maliciosas o inyectar descripciones de habilidades falsificadas.
¿Qué algoritmo criptográfico se recomienda para Signed Agent Cards?
Se recomienda ES256 (ECDSA utilizando P-256 y SHA-256) por el tamaño compacto de su firma y su alto rendimiento. RS256 (RSA con SHA-256) también está ampliamente soportado para compatibilidad con infraestructuras PKI empresariales heredadas.
¿Dónde deben alojarse las claves públicas o los endpoints JWKS?
Las claves públicas deben publicarse bajo HTTPS en el dominio autoritativo del proveedor, comúnmente en /.well-known/jwks.json, o referenciarse mediante los parámetros kid o x5u en el encabezado protegido JWS.
¿Cómo evalúa las firmas el validador de Agent Card?
El validador comprueba que el array signatures contenga objetos JWS compactos o aplanados bien estructurados, con encabezados protegidos válidos, identificadores de algoritmos estándar y referencias a claves verificables.
Referencias
Herramienta relacionada: Validador de Agent Card
Siguiente paso
Compruebe la integridad de su Agent Card antes de desplegarla.
El validador inspecciona la estructura de su tarjeta, comprueba el formato de firma JWS y advierte sobre referencias a claves públicas faltantes o endpoints no cifrados.