← Blog
20 de agosto, 2026 · 9 min

Open Payments y GNAP: auditoría de pagos de agentes sobre el rail de Interledger

La mayoría de los rails de pago de agentes son repos de doce meses con un token y un demo. Open Payments de Interledger es un estándar bancario de siete años sobre dos RFCs publicadas. Así que apuntamos una llave descartable a su testnet en vivo y preguntamos algo más simple: ¿puede un agente autónomo pagar de verdad con esto?

La respuesta es más interesante que un sí o un no. Open Payments funciona — firmamos grant requests reales, creamos un incoming payment en vivo, listamos los pagos de otros y rotamos un access token, todo contra interledger-test.dev con una llave Ed25519 generada segundos antes. Pero en el momento en que un agente quiere gastar, el protocolo pone a un humano en el medio por diseño. Esta es una auditoría de dónde cae esa línea y qué significa para un stack de agentes nativo de stablecoins.

Sigue a nuestras otras auditorías empíricas de protocolos: L402, el HTTP 402 de Lightning; la superficie del facilitator de x402; y los registries de ERC-8004 on-chain. Mismo método: clonar la spec, manejar el endpoint en vivo, reportar solo lo que el wire devuelve.

Qué es Open Payments en realidad

Open Payments es un estándar de API para mover dinero entre wallets en la web. No es una blockchain ni un token. Es la capa de aplicación que se sienta sobre el Interledger Protocol, y es lo que expone el software de proveedores de wallets como Rafiki. El repo open-payments se creó el 13 de septiembre de 2019, tiene 542 stars y licencia Apache-2.0, y su último push fue el 18 de agosto de 2026. Las specs OpenAPI normativas viven en otro repo, open-payments-specifications, hoy en versión 1.4.0 con releases etiquetados hasta la serie v1.4.x.

La superficie es chica y deliberada. Tres servidores:

La autorización no es OAuth. Es GNAP — el Grant Negotiation and Authorization Protocol, publicado como RFC 9635 en octubre de 2024 (Proposed Standard, autores J. Richer y F. Imbault). Los requests se firman con HTTP Message Signatures, RFC 9421, febrero de 2024. Ambas son estándares IETF terminados. Eso ya separa a Open Payments de la sopa de drafts que encontramos auditando KYAPay y del BLIP nunca mergeado detrás de L402: las primitivas de identidad y autorización acá no son propuestas, son RFCs con registros IANA. El registro de algoritmos de RFC 9421 lista ed25519 entre sus seis entradas — el mismo scheme que usa el testnet.

Resolver una wallet address en vivo

El punto de entrada para cualquier agente es una wallet address — una URL HTTPS que además funciona como identificador de pago. Resolvimos la address de demo de Alice en el testnet:

# GET https://ilp.interledger-test.dev/alice  (Accept: application/json)
{
  "id": "https://ilp.interledger-test.dev/alice",
  "publicName": "Alice Summit Demo",
  "assetCode": "ZAR",
  "assetScale": 2,
  "authServer": "https://auth.interledger-test.dev/f537…822c",
  "resourceServer": "https://ilp.interledger-test.dev/f537…822c"
}

La resolución tardó 577 ms y devolvió HTTP 200. El record apunta a los dos servidores que un agente necesita — dónde pedir un grant, dónde gastarlo — y el asset en que liquida. Fijate en la moneda: rand sudafricano, escala 2. Este es el primer punto estructural. Open Payments es agnóstico de moneda y de settlement. El asset es lo que el proveedor de wallet corra. Puede ser una stablecoin; puede ser un saldo bancario en ZAR. El protocolo lleva un monto como un triple { value, assetCode, assetScale } y nunca asume cripto. Es una fortaleza para el alcance y un costo para el mundo machine-native de moneda única que optimiza x402.

La address también sirve jwks.json — un JSON Web Key Set con una llave pública EdDSA. Este es el camino de identidad persistente: el authorization server busca tu llave pública en tu wallet address para verificar tus firmas. Guardá ese dato.

Firmar un grant con una llave descartable

Generamos un keypair Ed25519 nuevo en Node y armamos firmas RFC 9421 a mano — cubriendo content-type, content-digest (un hash SHA-512 del body), content-length, @method y @target-uri. Un grant request sin firma se rechaza de inmediato:

# POST al authorization server, sin firma
HTTP 401
{ "error": { "code": "invalid_client",
           "description": "invalid signature headers" } }

Bien. Ahora la jugada interesante. GNAP deja que un cliente se identifique de dos formas: por un string de wallet address (el AS busca tu llave en /jwks.json), o por directed identity — inyectás tu llave pública como un jwk en el request mismo. La spec es explícita en que directed identity "mejora la privacidad al no requerir que el cliente exponga un identificador de wallet address persistente," y que "solo puede usarse para grant requests no interactivos (es decir: incoming payments)."

Tomamos el camino de directed identity con nuestra llave descartable. Firmado, jwk inline, pidiendo un grant de incoming-payment:

# POST auth server, firmado, client = { jwk }, access = incoming-payment
HTTP 200  (726 ms)
{
  "access_token": {
    "access": [{ "type": "incoming-payment",
                "actions": ["create","read","list"] }],
    "value": "6B668D92C208CB849428",
    "manage": "https://auth.…/token/05b2…7510",
    "expires_in": 600
  },
  "continue": { … }
}

Un grant de quote volvió igual en 177 ms. Así que una llave que nunca existió antes, atada a ninguna wallet, ninguna cuenta, ningún humano, puede obtener access tokens válidos para crear incoming payments y quotes. Es la propiedad de privacidad funcionando como fue diseñada — y es exactamente la forma que un agente autónomo quiere.

El muro: no podés gastar sin un humano

Después pedimos un grant de outgoing-payment — el que saca dinero — con la misma llave de directed identity y un bloque interact declarando un redirect:

# POST auth server, firmado, client = { jwk }, access = outgoing-payment
HTTP 400
{ "error": { "code": "invalid_client",
           "description": "JWK client identifier cannot be used for interactive grants" } }

Este es el hallazgo. Gastar en Open Payments es un grant interactivo. Los grants interactivos requieren una identidad de cliente persistente y resoluble — una wallet address sirviendo jwks.json con información de display del cliente — porque un humano dueño del recurso tiene que ver quién pregunta y aprobarlo en un navegador. La llave descartable que preserva la privacidad se rechaza justo donde más importa para la autonomía.

Y la interacción misma es un redirect. El schema interact-response es inequívoco: el AS devuelve una URI redirect "para dirigir al usuario final" más un secreto finish. El único método de start enumerado es redirect; el único método de finish es redirect. Después de que el humano aprueba, el AS llama de vuelta al cliente con un hash que el cliente debe recalcular a partir de cuatro valores — el nonce del cliente, el nonce de interacción, el interact_ref y la URI del authorization server — como SHA-256, base64url, sin padding. Recién entonces /continue entrega el token de gasto.

Cero. La cantidad de veces que aparece "agent", "autonomous" o "AI" en las specs OpenAPI de Open Payments es cero. Es un estándar humano-a-wallet que precede a la ola de agentes por años. Todo lo agéntico se está retroadaptando desde la comunidad, no desde la spec.

De punta a punta, y una nota de privacidad

Para confirmar que el camino no interactivo es real y no un stub, corrimos un flujo completo de incoming. Grant (521 ms) → POST /incoming-payments en la wallet de Alice con un monto de 500 ZAR → HTTP 201 con un id de pago y una ILP address más shared secret para el movimiento real de dinero. Después listamos los incoming payments en la wallet de Alice y volvieron 20 registros — incluyendo sus descripciones de metadata: "payment-1", "Hi", "aaa" y nuestro propio "audit probe".

Vale marcarlo: una llave anónima recién creada con solo la acción list leyó las descripciones de los incoming payments de otras partes en una wallet address pública. Es por diseño — los incoming payments miran al receptor y la wallet de demo está abierta — pero es un recordatorio de que la metadata de un incoming payment no es privada, y los agentes que escriben descripciones de texto libre las escriben donde un extraño con una llave nueva puede leerlas. También rotamos un access token vía su URL manage (HTTP 200, valor nuevo, vida fresca de 600 segundos) — la rotación y revocación de tokens son de primera clase, algo que los diseños de bearer descartable que auditamos en otro lado no tienen.

La capa de agentes es un repo con cero stars

Si la spec calla sobre agentes, ¿quién construye el puente? Encontramos exactamente un intento serio: open-payments-mcp, un MCP server que envuelve el SDK de Open Payments como diez tools — resolver wallet address, request grant, continue grant, crear/leer incoming payment, crear/leer quote, crear/leer outgoing payment, y un orquestador "execute peer-to-peer payment". Dos commits, creado el 10 de junio de 2026, cero stars.

Su autor documentó la misma fricción que medimos. En un artículo titulado "Agentic Payments over Interledger Protocol — I tried it, and it works," llama a la verificación del hash del callback "sin duda la parte más difícil" y cuenta que en una versión temprana "lo resolvió extrayendo manualmente el interact_ref" en vez de verificar el hash. El tool que pide un grant de outgoing se describe como uno que "devuelve una URL de aprobación" — es decir, el agente le pasa un link de vuelta a un humano. El código actual sí implementa la verificación del hash SHA-256 con comparación en tiempo constante, así que el workaround se cerró. Pero el punto estructural queda: el agente "autónomo" se detiene y espera un navegador.

Open Payments frente a x402, con honestidad

Son animales distintos y el contraste es la lección. x402 es un solo round-trip HTTP: 402 con un precio, reintento con un header de pago, recurso entregado, stablecoin liquidada — sin cuentas, sin redirect, sin humano. Open Payments es una danza de varios pasos y varios recursos: resolver address, obtener grant, quote, crear pago, y para gastar, una aprobación humana en el medio. x402 asume una máquina pagando a una máquina en USDC. Open Payments asume una persona delegando un mandato acotado a un software que después corre sin supervisión dentro de límites.

Ese modelo de mandato es genuinamente fuerte. Un grant de outgoing lleva limits — un tope de monto debit o receive más un interval repetitivo ISO 8601 como R11/2026-08-24T14:15:22Z/P1M, que significa "once veces, mensual." Aprobás una vez, y el agente puede gastar dentro de ese sobre sin volver a preguntar. Eso está más cerca de cómo una tesorería quiere delegar en un agente que un 402 por request. El costo es el setup: una identidad persistente alojada y un redirect con humano en el medio antes de que el sobre se abra.

Qué significa para LLM4Agents

Open Payments no es un competidor del rail x402 que habla nuestro gateway — es un complemento apuntado a un comprador distinto. Donde x402 le da a un agente settlement instantáneo, sin supervisión y por llamada en stablecoins, Open Payments le da a un humano una forma de entregar a un agente un mandato de gasto acotado y revocable que alcanza a cualquier proveedor de wallet en la red, en cualquier moneda, incluido un saldo bancario. Son dos trabajos legítimamente distintos, y un operador de agentes serio va a querer ambos.

La amenaza, si la hay, es angosta. Open Payments no se va a comer los micropagos machine-to-machine; su flujo de redirect-y-mandato es demasiado pesado para una llamada por request de menos de un centavo, y su propio tooling de agentes es un único MCP server con cero stars. Pero podría volverse el rail preferido para pagos agente-a-humano y delegados por tesorería — el caso donde una persona fondea un agente y quiere topes duros y auditables con rotación y revocación real de tokens, respaldados por RFCs terminadas en vez de un bearer token que nunca expira. Esa es una historia que un banco o una fintech regulada va a confiar, y es una que x402 no cuenta tan limpio.

El encaje concreto: la primitiva de mandato. El limits más interval de Open Payments es una expresión limpia y estandarizada de "este agente puede gastar hasta X por mes." Ese es exactamente el contrato de tope de gasto que nuestra plataforma ya aplica internamente alrededor de reserve, proxy, settle. Hablarlo en el vocabulario de Open Payments dejaría a un cliente fondear un agente de LLM4Agents desde una wallet de Interledger con la misma semántica de mandato acotado que usaría para cualquier otra contraparte.

Cómo mantenerse en la frontera

Cuatro movimientos, en orden.

1. Resolver wallet addresses como identificadores de pago de primera clase. Una wallet address es una URL HTTPS que se hace GET y devuelve auth server, resource server y asset. Enseñarle a nuestro gateway a resolver una — igual que ya resuelve un bloque accepts de x402 — cuesta casi nada y deja a un agente aceptar "acá está mi wallet address de Interledger" como fuente de fondos. Es el punto de interop de menor riesgo.

2. Hablar el mandato, no solo el pago. Adoptar la forma limits/interval de Open Payments como forma canónica de expresar topes de gasto de agentes, y mapearla a nuestra lógica interna de reserve. Un tope que se puede expresar idéntico en términos de escrow x402 y en un grant de outgoing de Open Payments es un tope que un cliente puede razonar una vez y aplicar en todos lados.

3. Estandarizar en firma de requests con RFC 9421. Open Payments, y cada vez más la conversación amplia de identidad de agentes, convergen en HTTP Message Signatures para proof-of-possession — la misma primitiva que busca el draft compañero de KYAPay. Hacer de la firma RFC 9421 un modo de auth de cliente soportado en nuestro gateway es inversión que rinde en cada rail que la adopte, no solo en este.

4. Adueñarse de la capa de agentes que falta. El puente de agentes de Open Payments hoy es un MCP server con cero stars y una brecha documentada de humano en el medio. El problema sin resolver — cómo un agente totalmente autónomo completa un grant interactivo sin navegador, vía un mandato preaprobado o una interacción delegada — es justo el tipo de primitiva de infraestructura que vale la pena construir y contribuir upstream. Quien cierre la brecha del redirect limpio, sin debilitar la garantía de consentimiento humano, define cómo funciona la delegación acotada en este rail.

Pagá por llamada, en stablecoins, sin redirect

LLM4Agents es un gateway compatible con OpenAI donde los agentes liquidan por request sobre x402 y EIP-3009 — y seguimos cada rail, de Interledger a Lightning, para que tus agentes se mantengan en la frontera.

Registrar un agente