Policies
Spending policies are guardrails that constrain what an autonomous agent can do with its wallet. Before deploying any agent with real funds, configure a policy.
Why policies matter
An autonomous agent with unconstrained wallet access is a liability. A bug, a prompt injection, or a runaway loop can drain a wallet in seconds. Policies let you define hard limits that the orbserv platform enforces server-side — your code cannot override them.
Policy fields
| Field | Type | Description |
|-------|------|-------------|
| dailyLimit | string | Maximum USDC to spend per rolling 24-hour window |
| maxPerTx | string | Maximum USDC per individual transaction |
| allowedDomains | string[] | Whitelist of domains for x402 payments (empty = all allowed) |
| allowedTokens | string[] | Tokens the agent may spend (default: ['USDC']) |
| allowedChains | Chain[] | Chains the agent may use |
| paused | boolean | If true, all spending is blocked |
Getting the current policy
const agent = await orb.wallet.get(walletId)
const policy = await agent.policy.get()
console.log(policy)
// {
// dailyLimit: '100.00',
// maxPerTx: '10.00',
// allowedDomains: ['api.openai.com'],
// allowedTokens: ['USDC'],
// allowedChains: ['base'],
// paused: false,
// }Updating a policy
await agent.policy.update({
dailyLimit: '10.00',
maxPerTx: '2.00',
allowedDomains: ['api.openai.com', 'api.anthropic.com'],
allowedChains: ['base'],
})Updates are partial — only fields you provide are changed. To clear allowedDomains (allow all domains), pass an empty array:
await agent.policy.update({ allowedDomains: [] })Pausing and resuming
Use pause() to immediately block all spending without deleting the wallet:
await agent.policy.pause()
// All transactions will now fail with 403 PolicyViolationResume when ready:
await agent.policy.resume()Example: $10/day agent
A minimal safe configuration for a research agent with a tight budget:
import { OrbWallet } from '@orbserv-labs/orb-wallet'
const orb = new OrbWallet({ apiKey: process.env.ORB_API_KEY! })
const agent = await orb.wallet.get(process.env.AGENT_WALLET_ID!)
await agent.policy.update({
dailyLimit: '10.00',
maxPerTx: '1.00',
allowedTokens: ['USDC'],
allowedChains: ['base'],
allowedDomains: [
'inference.orbmarket.co',
'search.orbmarket.co',
],
})
console.log('Policy applied. Agent is ready.')Policy violations
When an agent exceeds its policy, the SDK throws a PolicyViolationError:
import { PolicyViolationError } from '@orbserv-labs/orb-wallet'
try {
await agent.send({ to: '0x...', amount: '50.00', token: 'USDC', chain: 'base' })
} catch (err) {
if (err instanceof PolicyViolationError) {
console.error('Blocked:', err.reason)
// e.g. "Transaction exceeds dailyLimit of $10.00 (used: $9.50)"
}
}Covenant integration
orbserv policies are enforced server-side by the platform. For an additional client-side gate, you can configure the SDK to call a Covenant daemon before each spend is signed. The daemon checks capability, per-call cap, and budget, then returns a decision_id for audit correlation.
When covenant.perCallCap is omitted, the SDK uses the wallet's maxPerTx as the per-call cap. Updating the policy invalidates the cached cap so authorizations always reflect the current bound.
See Covenant Spend Authorization for setup, configuration, settlement recovery, and error handling.