Skip to content
LogoLogo

Authorizing agents

Sui Agent Payments has one spend account for agent escrow and two ways to provision a spender on it. Both issue a scoped grant bound to a delegate address. The agent holds the key in both cases.

The rail tag on the wire is delegate (renamed from shared_pool, ADR-0035). The Move module is spend_account.

MCP OAuth (hosted / interactive)

Remote MCP agents connect through the platform OAuth flow:

  1. The agent generates a delegate keypair (or reuses the one it already holds) and opens the Sui Agent Payments MCP endpoint to start OAuth.
  2. The owner consents in the browser, selects policies, and signs an on-chain grant transaction with their wallet.
  3. The grant is bound to the address the agent supplied. The platform never mints or stores the delegate secret.

The agent never sees the owner key. This path is best when the agent runtime is hosted or interactive and OAuth is acceptable.

Local MCP URL shape (example for the local stack):

http://localhost:4340/mcp

See Pay with MCP.

Bring-your-own delegated key (SDK / REST)

Non-custodial agents generate their own keypair and share only the public Sui address:

  1. The agent generates an Ed25519 (or other Sui-supported) keypair and keeps the private key in its own runtime.
  2. The owner calls POST /v1/delegated-signers (verified owner session) with that address, name, policy/profile selection, and per-asset scopes (total budget, max per payment, expiry).
  3. The real authority is an owner-wallet-signed create_grant transaction. An owner session alone cannot mint a grant.
  4. Finalization verifies the grant-created event (delegate, caps, expiry, policy set, package target, finality) before the grant is reported active.

Sui Agent Payments never holds the agent's private key. Registration stores the public address and grant metadata only.

See Authorize an agent and Pay with the SDK.

Side-by-side

MCP OAuthBring-your-own key
Key custodyAgent generates and holds the key; OAuth binds the grant to that addressAgent generates the keypair; Sui Agent Payments stores only the public address
How you connectRemote MCP OAuth consentPOST /v1/delegated-signers + owner-signed create_grant
On-chain grantSpend-account grant bound to the agent-held addressSame grant model via create_grant (includes max_per_payment)
SettlementAgent signs in the process that holds the keyspend_account::settle_policy_payment with the BYO delegate as sender

Same policy model

Regardless of provisioning method, scope is:

  • Service allowlist via policy targets (method/path → target hash → fixed recipient)
  • Per-asset total budget (grant session cap)
  • Per-signer per-payment cap (max_per_payment on the grant)
  • Asset (one grant per asset under a logical signer)
  • Expiry

Enforcement is on chain at pay time. Changing scope means a new grant; policy IDs on a grant are an immutable snapshot.

Revoke and pause

  • Revoke is terminal: owner-signed revoke_grant (API: DELETE prepare + finalize). Revoked grants cannot spend.
  • Pause is reversible: owner-signed pause_grant / resume_grant (API: POST /v1/delegated-signers/:id/pause/prepare and .../resume/prepare, then per-grant finalize). A paused signer cannot pay until the owner resumes.

What is not a third path

The V1 allowance rail (per-recipient escrow plus a raw delegate key) is retired. Do not provision new agent authority on allowance. Migrate to a spend-account delegated signer (MCP or BYO).