Skip to main content

Wallet Access Policies

Wallet access policies (v0.53.1) extend spend policies with role- and principal-based grants — control which users, agents, or role tags can send, swap, view balances, or export keys on treasury wallets.

Tier and principal requirements
  • Pro or higher plan required to create policies
  • Human-only — agents cannot create or delete wallet access policies
  • Distinct from spend policies (platform app caps on end-user sends) — see comparison below

Spend policies vs wallet access policies

Spend policiesWallet access policies
PurposeCap what embedded-wallet end-users can send/swapGrant specific principals permission to act on wallets
Set byPlatform app (plt_ key)Org admin (human JWT)
Endpoints/v1/platform/apps/{id}/spend-policies/v1/treasury/wallets/access-policies
EnforcementLive on send/swapAPI + dashboard live; runtime enforcement on treasury routes is rolling out with v0.53.1

Use spend policies for consumer wallet caps in embedded apps. Use wallet access policies when agents, team roles, or platform apps need granular wallet permissions inside an org.

Policy model

Each policy row defines:

FieldDescription
scope_typewallet (specific wallet), platform_app, or org (org-wide)
scope_idUUID when scope is wallet or platform_app; omit for org
principal_typeuser, agent, role, or platform_app
principal_idUser/agent UUID, role tag string, or platform app UUID
can_send / can_swap / can_view_balance / can_export / can_signBoolean permission flags
allowed_chainsChain allowlist (empty = all)
max_value_per_tx_eth / daily_limit_ethOptional caps on the grant
conditionsJSONB for extended conditions
expires_atOptional expiry

Resolution order in the domain evaluator: direct principal match → role tag match → platform app match → org-wide default. No matching policy = deny (fail-closed).

API endpoints

MethodPathAuth
POST/v1/treasury/wallets/access-policiesHuman JWT
GET/v1/treasury/wallets/access-policiesHuman JWT
DELETE/v1/treasury/wallets/access-policies/{id}Human JWT

Query params on list: scope_type, scope_id.

Create a policy

curl -X POST "https://api.1claw.xyz/v1/treasury/wallets/access-policies" \
-H "Authorization: Bearer $USER_JWT" \
-H "Content-Type: application/json" \
-d '{
"scope_type": "org",
"principal_type": "agent",
"principal_id": "AGENT_UUID",
"can_send": true,
"can_swap": false,
"can_view_balance": true,
"can_export": false,
"allowed_chains": ["ethereum", "base"],
"max_value_per_tx_eth": "0.5",
"daily_limit_eth": "2.0"
}'

Returns 201 with the full policy object.

List policies

curl "https://api.1claw.xyz/v1/treasury/wallets/access-policies?scope_type=org" \
-H "Authorization: Bearer $USER_JWT"

Response: { "policies": [ ... ] } — active policies only.

Delete (soft-delete)

curl -X DELETE "https://api.1claw.xyz/v1/treasury/wallets/access-policies/$POLICY_ID" \
-H "Authorization: Bearer $USER_JWT"

Returns 204. Sets is_active = false.

Dashboard

Manage policies at Settings → Wallet Access (/settings/wallet-access). Create grants by chain, target type (agent/user), permissions (send, swap, receive), and optional expiry.

Example: agent read-only balance

Allow a support agent to view balances but not send:

{
"scope_type": "org",
"principal_type": "agent",
"principal_id": "support-agent-uuid",
"can_view_balance": true,
"can_send": false,
"can_swap": false,
"can_export": false
}

Example: role-based ops team

Grant all users with wallet role tag treasury_ops send access on Ethereum only:

{
"scope_type": "org",
"principal_type": "role",
"principal_id": "treasury_ops",
"can_send": true,
"can_swap": true,
"allowed_chains": ["ethereum"],
"max_value_per_tx_eth": "1.0"
}

Assign roles via users.wallet_roles / agents.wallet_roles (org admin).