Nava Gateway security and limitations
Developer Preview
Controls present in the Developer Preview
| Control | Preview behavior |
|---|---|
| Asset and network pinning | /verify and /settle reject requirements outside the facilitator's configured network and asset. The supported defaults are canonical USDC on Base/Base Sepolia. |
| Exact fee quote binding | A caller-supplied verification requirement is compared with a fresh authoritative quote by payee, base-unit amount, and asset before its authorization is accepted. |
| Full approval binding | Merchant settlement compares payer, payee, amount, and asset with the approval stored for the signed EIP-3009 nonce. |
| One-time consumption | With Redis, /settle uses atomic GETDEL before broadcasting. The default memory store implements separate async read/delete steps and is not atomic under concurrent settlement calls. |
| Bounded outbound calls | Guardian, pricing, and facilitator JSON calls use a whole-request timeout, reject redirects, and cap declared/read response bodies at 1 MB by default. |
| Fail-closed dependencies | Missing fee quotes, unsuccessful upstream responses, exhausted Guardian polling, malformed responses, and failed required fee settlement do not grant access. |
| Deterministic repricing | A resource quote callback reruns when the paid request arrives; the result must match the amount the payer signed. |
| Caller authentication | When configured, /verify, /settle, and /verification/quote require x-facilitator-key. Leaving the key unset makes them open for development. |
| Request limits | The preview server applies a global 120-requests-per-minute rate limit and can reject merchant settlement values below a configured base-unit minimum. |
| Minimal health response | /health returns only { "status": "ok" } by default. Detailed wallet, balance, network, and Guardian URL disclosure is opt-in and invokes cached RPC reads. |
The default in-memory approval store is process-local. It is bounded and expires
records, but approvals disappear on restart, are not shared between instances,
and its async read/delete sequence allows concurrent callers to both reach
broadcast. EIP-3009 prevents both authorizations from successfully transferring
the tokens, but the facilitator can still spend gas on a transaction that
reverts. The Redis-backed store uses atomic GETDEL, shares nonce state,
and survives process restarts. Use Redis for any multi-instance or
concurrency-sensitive preview.
The shared HTTP default is 10 seconds per call. Although GuardianConfig
declares timeoutMs and direct GuardianClient use reads it, the current
verifyPayment implementation constructs its client with only baseUrl and
apiKey. Consequently, the high-level verifyPayment, withGuardian, and
facilitator paths do not honor a caller timeout override; their Guardian calls
use the 10-second default. This is a Developer Preview limitation. Polling is
still attempt-bounded, and timeouts, non-2xx responses, or persistent failures
do not authorize settlement.
Approval is consumed before merchant broadcast. If settlement fails or the
resource gate returns 502, do not blindly retry /settle: reconcile any
uncertain transaction, re-run /verify for the exact payment, and obtain a fresh
verification-fee authorization when the prior fee authorization was consumed.
Sensitive data
- The facilitator hot-wallet private key and
x-facilitator-keyare secrets. - The payer-scoped
navaApiKeyand fallbackGuardianConfig.apiKeyare bearer secrets. Redact them from payment-envelope logs, traces, storage, and errors. - Leave payer prompt override disabled; derive the description from the signed action.
- Do not reflect raw upstream bodies across the facilitator boundary.
Unresolved preview contracts
These items remain open in the Developer Preview and must not be converted into setup steps or assumed guarantees:
- Payment venue and field names:
protocol: "payment"and thepayTo/asset/amount/resourcefields are a proposed adapter contract, not the final Guardian payments schema. - Canonical input: the boundary between a normalized
PaymentActionand a raw x402 payload is not finalized. - Period-cap timing: the accounting and timing contract for period spend caps is unresolved.
- Signed verdicts: the preview consumes HTTP verdicts; a signed-verdict trust model for third-party facilitators is unresolved.
- Authenticated Guardian-key binding:
navaApiKeycurrently rides in the unsigned payment envelope and is not cryptographically bound to the payer. - Usage-metered quote IDs: the preview requires deterministic repricing and does not yet bind after-the-fact usage with a short-lived quote ID.
Until these contracts are finalized, keep testing to placeholder/test contexts,
use required only for a controlled fail-closed preview, and do not infer
production availability from this preview.