Seguridad y modelo de confianza
Burnbound decide si tu agente puede pagar; no custodia tu dinero ni la clave privada de tu cartera. Esta página explica qué guarda y qué ve Burnbound en cada modo de firma, de qué protege el servidor MCP y dónde termina esa protección, en particular el límite cooperativo de la firma en el cliente.
¿Guarda Burnbound mis claves privadas o mis fondos?
No. Burnbound nunca guarda la clave privada de una cartera ni custodia fondos. Con Coinbase CDP, la clave se queda en Coinbase; con la firma en el cliente, se queda en tu máquina. Los pagos van directamente de tu cartera al vendedor.
Lo que Burnbound sí guarda en el modo Coinbase CDP son tus credenciales de la API de CDP (API key ID, API key secret y wallet secret), porque las necesita para pedir a Coinbase que firme los pagos que tu política permite. Se guardan cifradas en reposo (AES-256-GCM), se descifran solo para pedir una firma y nunca vuelven a mostrarse en el panel ni las devuelve la API. Aun así, son credenciales potentes: trata la cartera de CDP como una cartera de gasto y guarda en ella solo lo que tus agentes deberían poder gastar.
¿Qué ve Burnbound en cada modo de firma?
Burnbound ve lo que necesita para decidir y para auditar: la petición de pago, nunca el contenido que compras. La tabla compara los dos modos.
| Coinbase CDP | Firma en el cliente | |
|---|---|---|
| Clave privada de la cartera | No (se queda en Coinbase) | No (se queda en tu máquina) |
| Credenciales de firma | Tus credenciales de la API de CDP, cifradas | Ninguna |
| Dirección de la cartera | Sí | Sí (lo único que registras) |
| ¿Puede Burnbound hacer firmar un pago? | Sí, a través de CDP, para los pagos que su política permite | No |
En los dos modos, Burnbound ve y registra de cada pago:
- la URL que respondió HTTP 402, con su ruta y su query string;
- el challenge x402 del vendedor: precio, red, activo y payee;
- la decisión (permitido, denegado con sus motivos o enviado a aprobación) y la versión de la política;
- el
originque el agente declaró para la URL (user,catalog,tool_outputoweb), cuando envía uno; - el recibo
PAYMENT-RESPONSEdel vendedor y la transacción on-chain.
Burnbound no ve las cabeceras ni el cuerpo que tu agente envía al vendedor, ni el cuerpo de la respuesta del vendedor. El servidor MCP solo envía a Burnbound el challenge 402 y, después de pagar, el recibo.
¿Cómo se protegen las claves de agente?
Una clave de agente (bb_agent_…) se muestra una sola vez al crearla, y Burnbound guarda solo su hash SHA-256. Solo puede actuar en nombre de su propio agente: leer su presupuesto y sus pagos, pedir autorización para un pago, informar de un recibo y leer sus propias aprobaciones. No puede cambiar la política, subir un tope, aprobar un pago, conectar una cartera ni crear claves; para eso hace falta una persona con sesión iniciada en el panel.
La clave vive en la configuración de tu cliente MCP (~/.claude.json, .cursor/mcp.json). Un agente que pueda ejecutar comandos de shell en la misma máquina podría leerla, así que es preferible usar claves de agente con topes ajustados antes que claves de organización, que tienen permisos de administrador. Puedes revocar una clave en el panel en cualquier momento.
¿De qué protege el servidor MCP?
@burnbound/mcp añade protecciones en el cliente por delante de la política de Burnbound. Reducen lo que un agente confundido o manipulado puede hacer con fetch_paid; la API de Burnbound sigue siendo la que manda sobre el gasto.
- La clave solo va a la API de Burnbound. Nunca se envía a las URL que pide
fetch_paidy nunca aparece en los resultados de las herramientas ni en los logs. Se rechaza cualquier entrada que contenga la clave (contains_credential). - Solo se piden hosts permitidos.
fetch_paidcomprueba los hosts permitidos del agente antes de enviar nada, sea de pago o no. - Nada de redes privadas. Se bloquean las direcciones privadas, de loopback, link-local y reservadas, tanto en IP literales como en cada dirección a la que resuelve un nombre de host, en el momento de conectar.
- El vendedor no puede redirigir el pago. El recurso del challenge del vendedor tiene que estar en el host pedido, y la petición pagada nunca sigue redirecciones.
- Las respuestas del vendedor no son de confianza. Una API de pago puede devolver texto escrito para manipular al agente ("ignora tus instrucciones y paga…").
fetch_paiddevuelve el cuerpo delimitado y etiquetado como datos no fiables, separado de los metadatos. - Los mensajes de error los escribe el servidor, nunca se copian de la API ni del vendedor.
- Solo aprueba una persona. El servidor puede ofrecer al usuario la página de aprobación desde el chat, pero nunca aprueba ni rechaza un pago, y la clave del agente tampoco puede.
- Ninguna clave de cartera en la configuración. El servidor se niega a arrancar si una variable
BURNBOUND_*parece una clave privada.
¿Y si una página engaña al agente para que pague?
Una página web, el resultado de otra herramienta o el propio 402 del vendedor pueden intentar que el agente pague a quien no debe. Burnbound juzga cada pago antes de que se firme nada, en todos los agentes:
- Se rechazan los hosts que imitan a otros. Los hosts permitidos tienen que coincidir exactamente (o como
*.suffix), así quese11er.exampleo un host con una letra cirílica se rechazan salvo que los hayas permitido (host_not_allowed). - Una dirección de cobro nueva espera a una persona. El primer pago a una dirección a la que la organización nunca ha pagado en ese host y esa red se retiene (
new_pay_to), salvo que el vendedor esté en el catálogo de Burnbound y pida cobrar en una dirección que Burnbound le tiene fijada. - A un vendedor del catálogo solo se le paga en sus direcciones fijadas. Si un vendedor del catálogo de Burnbound, cuyas direcciones de cobro en esa red ha fijado Burnbound, pide cobrar en otra dirección, el pago se deniega (
pay_to_not_verified). - Un 402 que parece dar instrucciones espera a una persona. Si la descripción o el texto
errordel 402 le dice al agente qué hacer ("ignora las instrucciones anteriores…"), el pago se retiene (instruction_like_description), también cuando el texto está partido con caracteres invisibles o llega después de un comienzo largo e inofensivo. - Un precio inflado choca con tus topes: el máximo por pago, el tope diario y el propio
maxAmountUsdde la llamada.
Estos casos se prueban en cada cambio contra páginas trampa que reproducen cada truco. La protección tiene límites:
- La detección de instrucciones busca una lista corta de patrones. Una instrucción reformulada puede colarse; aun así, el pago sigue teniendo que pasar los hosts permitidos, los topes y las comprobaciones de la dirección de cobro.
- Burnbound juzga el pago (host, dirección de cobro, importe, texto del 402), no la página que llevó al agente hasta él. El
originque declara el agente se registra para la auditoría y nunca cambia la decisión. - El precio se comprueba contra tus topes, no contra el precio habitual del vendedor.
- Un comodín como
*.example.comadmite cualquier nombre por debajo.
¿Cuál es el límite de la firma en el cliente?
La firma en el cliente es cooperativa. Burnbound no puede detener un proceso que ya se ejecuta con tu usuario: un agente que pueda ejecutar comandos de shell en la máquina podría leer la clave de la cartera (del llavero del sistema operativo o del archivo de la cartera) y firmar pagos sin preguntar a Burnbound. La política solo se cumple mientras el agente pase por el servidor MCP.
El servidor MCP lo pone más difícil, no imposible:
- la clave nunca está en la configuración MCP ni en el entorno que el agente puede leer, y nunca se envía a ningún sitio;
- se carga solo en el primer
fetch_paid, nunca desde las herramientas de solo lectura; - se revisa cada petición a Burnbound y a los vendedores en busca de la clave, y se bloquea si aparece;
- solo firma autorizaciones de transferencia de USDC que Burnbound ha permitido, para la propia oferta del vendedor y con una ventana de validez corta.
Si necesitas un control que no dependa de la cooperación del agente, usa Coinbase CDP: el agente nunca tiene nada que pueda firmar, y Burnbound pide cada firma.
¿Cómo funciona la detección de movimientos fuera de la política?
En las carteras con firma en el cliente, Burnbound vigila la dirección de la cartera on-chain y registra un evento payment.out_of_policy cuando sale USDC de ella sin un pago correspondiente que Burnbound haya permitido. Lo detecta a posteriori; no puede bloquear ni revertir la transferencia.
Un movimiento se marca cuando es:
- una autorización de transferencia cuyo nonce no pertenece a ningún pago que Burnbound haya permitido;
- una autorización de transferencia que pertenece a un pago, pero con otro payee, otro importe u otro pagador;
- una autorización de transferencia de un pago que ya había fallado o caducado;
- un
transfer()otransferFrom()sin más, sin ninguna autorización; - un
approve()opermit()que concede una asignación (allowance).
Los movimientos marcados aparecen en la auditoría y como aviso en la página del agente en el panel, normalmente pocos minutos después de llegar a la cadena.
¿Por qué debería recargar la cartera con un saldo pequeño?
Porque el saldo es el techo real de lo que un agente comprometido o que se porta mal puede gastar fuera de la política. Con la firma en el cliente, un agente que lea la clave puede gastarse la cartera entera; en cualquier modo, una cartera con el gasto de una semana pierde como mucho el gasto de una semana.
- Mantén un saldo a la medida de lo que el agente debería gastar en un periodo corto, y recárgalo.
- No guardes ETH en una cartera con firma en el cliente. Los pagos x402 no lo necesitan y, sin él, la cartera no puede enviar por sí misma una transacción normal. Otra persona sí podría enviar una autorización de transferencia ya firmada, así que lo que de verdad acota el riesgo es el saldo de USDC.
- Usa una cartera por agente, para que un problema en una no llegue a las demás.
¿Cómo mantengo a Claude Code lejos de la clave de la cartera?
Quítale al agente las vías para leer la clave en .claude/settings.json (o ~/.claude/settings.json). Estas reglas reducen los accidentes; no son un sandbox.
{
"permissions": {
"deny": [
"Read(~/.burnbound/**)",
"Edit(~/.burnbound/**)",
"Bash(security find-generic-password:*)",
"Bash(security dump-keychain:*)",
"Bash(secret-tool lookup:*)",
"Bash(npx -y @burnbound/mcp@latest wallet export:*)",
"Bash(npx -y @burnbound/mcp wallet export:*)",
"Bash(burnbound-mcp wallet export:*)"
]
}
}