Skip to content
On this pageLanesWhat always holdsDefaults for a new agentContent checkObserve modeAttacks and the rules that catch themKnown limitsReport a vulnerability

Explanation / Security model

Security model and limits

The guard decides the payments you route through it. It holds no key of yours and never signs your payments.

An agent that pays some other way is not stopped. This page says which lanes enforce, what always holds, and where the limits are.

Lanes

Two lanes enforce the policy. Two only advise, and your agent or code acts.

LaneBadgeWhat it checksGuard downYou still own
Proxy URLEnforcedThe signed payment, the seller's 402, pages fetched through it, and paid answers.Nothing is forwarded, so nothing is paid.The proxy token. Anyone holding it pays under your agent's limits.
SDKEnforced on routed paymentsEach x402 payment before it is signed, and pages fetched with its fetch.Nothing is signed. With mode: "observe" in code, it pays unchecked and warns.Sending every payment through the x402 client the SDK wraps.
MCPAdvisoryThe payment and the text the agent passes to the tool.The tool says it could not check and not to pay. The agent decides.The agent can skip the tool or ignore its answer.
HTTP APIAdvisory: your code actsWhat your code sends.Your code decides.Sending every payment, and acting on each answer.
advisory

The MCP tool is advisory. The agent chooses whether to ask. For a check it cannot skip, use the proxy URL or the SDK hook.

The proxy decides and records each x402 payment sent through it. So the agent skips check_payment and report_settlement for that payment, unless the paid answer carries guard-settlement-status: unverified.

What always holds

  • The key your agent holds can read its policy. It cannot change a limit or approve its own hold. A signed-in person answers every review.
  • A denied payment is never signed by the SDK or forwarded by the proxy.
  • A decision belongs to its account. Another account's key gets a 404, never the decision.
  • The guard cannot pull back a payment once it has settled.
  • A leaked proxy token cannot move your money, but anyone holding it can pay under your agent's limits. It sits in the URL, so treat it as a password and rotate it on Keys.

Defaults for a new agent

A new agent starts small. Every field is on the policy page.

SettingDefault
Per-transaction limit0.10 USDC
Daily cap across all networks1.00 USDC
Auto-allow unlisted payees under0, so every payment to a payee off the allowlist waits for a person
Payments per hour per network20
Review timeout120 seconds (2 minutes)
NetworksBase Sepolia, with test USDC
Managed wallet blocklistOff
Modeenforce

Content check

The content check reads text for instructions aimed at the agent. It can block a payment or hold it for a person. It never allows one.

Through the proxy URL it reads the seller's 402, pages fetched through it, and paid answers. Through the SDK it reads pages fetched with the SDK's fetch. Through the advisory MCP tool and the API it reads the text the caller sends.

ResultWhat happens to the payment
BlockedDenied. A person cannot approve it.
FlaggedHeld for review.
Did not finishHeld for review.
ClearYour rules decide.
UnavailableYour rules decide. A payment auto-allow would let through waits for a person.

A flagged or unfinished check also holds later payments for an hour. Which ones depends on where the text came from.

Where the text came fromWhat it holds
A page or a 402 from a siteThe agent's payments to that site, through every lane.
Text with no site, such as a tool's outputEvery payment in the same session.
Any text in a contract call's sessionEvery contract call in that session, since a call has no seller page.
Text a payment citesThat payment, and for an hour the agent's later payments to the same site in that session.

Approve and clear page on a review ends that hour of holds for the agent.

Observe mode

Every agent starts in enforce. In observe, the guard lets a payment through and records what enforce would have said in shadowStatus. Five cases still deny, since no policy allows them in any mode.

  • A network the policy does not allow (network_allowed)
  • An asset the policy does not allow (asset_allowed)
  • A payee the seller's own 402 did not name (payee_matches_402)
  • A declared payment method the guard cannot judge (payment_method_supported)
  • A contract call other than a supported USDC call (contract_call_denied)
A decision in observe mode
{
  "status": "allowed",
  "shadowStatus": "denied",
  "rules": [
    { "id": "amount_per_tx", "result": "deny",
      "sentence": "The amount 2.50 USDC is over the per-transaction limit of 0.10 USDC." }
  ]
}

Read a week of your own traffic this way, then switch the agent back to enforce (modes).

Attacks and the rules that catch them

The attacks the home page names, plus a swapped payee, with the rule that stops each.

AttackCaught byResult
Inflated pricesamount_per_tx, amount_daily_capDenied
Wallet takeover callscontract_call_deniedDenied
Injected payments that look normalinjection_suspectedDenied or held
A payee swapped from the seller's 402payee_matches_402Denied in every mode
Purchases you never asked forresource_allowedHeld
Unapproved payeesfirst_time_payee, payee_denylistedHeld, or denied if listed
Runaway payment loopsvelocity_per_hourHeld

Known limits

Does the guard stop a payment made some other way?

No. It decides only the payments routed through it. An agent that holds its own wallet key can pay a seller directly, so keep that wallet small.

Can the content check be wrong?

Yes. It can miss a page written to look harmless, and flag one that meant nothing by it. The decision keeps the result either way, and observe mode shows what it would have stopped.

Is a request sent twice decided twice?

A request sent twice without an Idempotency-Key is decided twice. When both are allowed or held, both count toward the day's cap and the hour's count. The SDK resends a post the guard did not answer under the same key, so that resend reads the first decision. A new payment attempt gets a new key and a new decision. The proxy URL knows a payment by what was signed, so a resent copy reads its first decision and counts once. One exception: once a newly signed retry picks up a payment the proxy held, a copy of the first signature is decided as a new payment.

What does a reused Idempotency-Key answer?

The first decision, until that payment's settlement is reported. Then it answers 409 decision_already_used, and a new payment needs a new key. The same key with a different payment answers 409 idempotency_conflict.

Is a reported settlement proof of payment?

Not always. A settlement reported through the SDK, the advisory MCP tool or an EVM proxy payment is a claim with a transaction id you can check. The Solana proxy confirms the transaction on chain first. If the network does not answer in time, it records the receipt as reported too. The settlement's verification field says which.

Can payments sent at once pass a limit?

Requests sent at the same moment can pass a per-minute request limit briefly. The daily cap and the hourly count are checked again once each decision is recorded, so a burst cannot pass them. Waiting payments already count, so approving a hold can never push the day over the cap.

Is there a history of policy edits?

No. Nothing records who changed a policy or when. Every decision keeps a copy of the policy it ran under.

Which releases send the payment method?

Releases before SDK 0.7.0 and the advisory MCP tool 0.4.0 do not, so the guard judges only the scheme for them. Update, or send those payments through the proxy URL.

What is not supported?

Assets and x402 payment methods outside the supported payments. Contract calls other than USDC transfer, transferFrom, and capped approve or increaseAllowance on Base and Base Sepolia. Raw Solana instructions. SMS and phone alerts. The guard also does not control what a spender does later with an allowance.

Report a vulnerability

Email the contact in /.well-known/security.txt with what you found and how to reproduce it.