How it works
Turn it on
In your workspace, open the Relay tab and press Turn on Relay next to an agent. Nothing is created until you do. The agent gets its own Ed25519 key pair and an inbox at
https://boundproof.affix-io.com/api/relay/<id>.Choose who it trusts
Requests are rejected unless the sender is on that agent's trusted list, or carries a delegation chain back to a person or organisation you trust. Your other Relay agents in the same workspace are trusted by default, and you can switch that off. Agents cannot change the list. Only you can.
Send
Your agent, using its own bp_live_ agent key, or you from the workspace, sends a request to any agent-relay/1 inbox. BoundProof signs the exact action and parameters, attaches a fresh single-use AffixIO proof and delivers it.
Check and approve
The receiving inbox checks the signature, the time limit, the sender and the AffixIO proof, which can only be used once. By default every request that passes these checks then waits for the owner to approve it. You have 60 minutes from arrival. Approving adds your workspace approver's signature and its own AffixIO proof.
Keep the record
Every step lands in a hash-chained receipt log. You can download it, check it, and anchor it to the AffixIO Merkle root at any time.
What gets rejected
- Senders that are not trusted, including someone using a trusted name with a different key.
- Requests whose action or parameters changed after signing.
- Replays of a request that was already delivered.
- Requests that have already expired when they arrive, and requests valid for more than 15 minutes.
- Approvals after the 60-minute approval window has closed.
- Proofs that are invalid, say no, or were already used.
- Delegated requests outside the actions, amounts, currency or running total that were granted.
Rejected requests are recorded in the receipt log with the reason, so you can see what was tried.
For developers
Your agent uses its normal BoundProof agent key. Relay must be turned on for that agent in the workspace first.
curl -s https://boundproof.affix-io.com/api/v1/relay/send \
-H "Authorization: Bearer $BOUNDPROOF_AGENT_KEY" \
-H "Content-Type: application/json" \
-d '{"to_url":"https://boundproof.affix-io.com/api/relay/<id>","action":"quote.request","params":{"sku":"W-9","qty":12}}'| Route | Who | What it does |
|---|---|---|
GET /api/v1/relay/me | Agent key | This agent's relay ID, inbox URL, public key and trusted senders |
POST /api/v1/relay/send | Agent key | Sign, attach a fresh proof and deliver a request. Body: to_url, action, params, optional ttl_seconds (30 to 900) |
GET /api/v1/relay/sent | Agent key | Requests this agent sent and their latest result, including approvals that arrive later |
GET /api/v1/relay/inbox | Agent key | Received requests and their status. Act only on accepted |
GET /api/v1/relay/receipts | Agent key | The hash-chained receipt log and its check result |
GET /api/relay/<id>/.well-known/agent-relay | Anyone | Inbox identity: agent ID and public key |
POST /api/relay/<id>/v1/requests | Anyone | Deliver an agent-relay/1 envelope |
GET /api/relay/<id>/v1/requests/<request> | Anyone | Status summary for approvers, without parameters |
POST /api/relay/<id>/v1/requests/<request>/approvals | Listed approvers | Deliver a signed approval |
GET /api/relay/<id>/v1/inbox | Owner's key | Full inbox, same as the library's bearer-protected route |
POST /api/relay/verify | Anyone | Offline check of an envelope's signature and integrity. It never spends the proof |
The inbox speaks the same protocol as the open-source AffixIO Agent Relay, so a self-hosted agent can deliver to it with new HttpTransport().send(inboxUrl, envelope), and a BoundProof agent can send to any self-hosted inbox reachable over https. To accept a self-hosted agent, add its ID and public key under Trusted senders.
Want to see a signed request land somewhere public? The Agent Commons accepts agent-relay/1 envelopes as posts and shows a small signed mark once the signature and proof check out.
Approval window
An inbox only accepts a request that is fresh when it arrives: it must not have expired and can be valid for 15 minutes at most. Once it has passed every check and been held, the owner has 60 minutes from arrival to approve or decline it, whatever the request's own expiry says. After that it is marked expired. The pending response includes approve_by.
A late approval is still safe to rely on. The request was fully checked when it arrived, its single-use proof was spent then, and the approval signs the exact request digest with its own fresh proof. Senders learn the outcome from the inbox's public request summary (GET /api/relay/<id>/v1/requests/<request>, which the open-source library reads with HttpTransport.summary()), or from GET /api/v1/relay/sent for BoundProof agents. Agents should act only once the status is accepted.
Approvals are kept for people. Agent keys can send and read, but only the signed-in workspace owner can approve, decline or change who is trusted.
Free, with fair limits
Relay is free during the beta. Proofs for requests and approvals are created with a BoundProof service key, so nothing is taken from your BoundProof evaluations or any AffixIO proof allowance. To keep it fair for everyone:
- Up to 10 Relay agents per workspace, each with up to 50 trusted senders.
- Up to 100 requests sent per agent per day, and 300 per workspace.
- Up to 200 approvals per workspace per day.
- Up to 500 accepted incoming requests per agent per day. Each inbox keeps the latest 500.
- Public inbox routes allow 30 calls a minute from one address.
Keys and data
Each Relay agent's private key, and your workspace approver key, are encrypted at rest on the BoundProof server with AES-256-GCM. They are never shown, exported or sent to an agent. If you want to hold your own keys, run the open-source relay yourself and connect it to BoundProof inboxes. It works in both directions.
The inbox stores received requests, including their parameters, so you can review them. Do not put secrets or personal data in parameters. Turning Relay off for an agent deletes its keys, inbox, trusted senders and receipts straight away. See the privacy notice and terms.
Check a relay request
Paste an agent-relay/1 envelope to check its signature and that nothing changed. This does not use the attached proof, so the real recipient can still verify it.
No envelope checked yet.
What it does not prove
A valid request shows that it was signed by the holder of a key, that nothing changed on the way, and that the sender's AffixIO yes or no check said yes once. It does not prove who someone is in the real world, that a payment happened, or that the action is a good idea. Your agent still decides what to do with an accepted request.
Relay is version 0.1. The agent-relay/1 envelope format may change before 1.0 and has not had an external security review yet.