Session Keys
Session keys solve a fundamental UX problem in autonomous agents: you want the agent to act on your behalf, but you don't want to sign every single transaction, and you definitely don't want to give it unlimited access to your wallet.
The solution: you sign once, defining a bounded scope — "this agent can trade for 24 hours, max $500 per position, only Ekubo pools, slippage capped at 1%." The agent executes within those bounds. If it tries to exceed them, the contract rejects the action. You can revoke at any time.
The lifecycle
sequenceDiagram participant You participant API as Session Key API participant Wallet participant Chain You->>API: POST /grant — define scope API-->>You: calldata + session metadata You->>Wallet: Sign grant tx Wallet->>Chain: Session key registered on-chain You->>API: POST /grant/confirm API-->>You: Session active ✓ Note over You,Chain: Agent operates within bounds... You->>API: POST /revoke You->>Wallet: Sign revoke tx Wallet->>Chain: Session key revoked You->>API: POST /revoke/confirm API-->>You: Session ended ✓
The critical detail: the grant happens on-chain. The smart contract knows the agent's bounds, so enforcement isn't just an API-level check — it's a contract-level check. The agent can't bypass it.
Endpoints
All under /api/v1/zkdefi/session_keys/:
| Method | Path | What it does |
|---|---|---|
POST | /grant | Build session grant request — specify duration, max amounts, allowed protocols, constraints |
POST | /grant/confirm | Confirm the on-chain grant. Session becomes active. |
POST | /revoke | Build revoke request — schedule session termination |
POST | /revoke/confirm | Confirm the on-chain revoke. Session ends immediately. |
GET | /list/{owner_address} | List all active sessions for an address |
POST | /validate | Validate whether a specific action is allowed under the current session |
How to think about scoping
Session keys are only useful if you scope them tightly. Here's the mental model:
- Duration — how long should the agent operate? Shorter is safer. 24 hours is a reasonable starting point; 7 days gives more autonomy but more risk.
- Max position size — the most the agent can allocate in a single operation. Set this lower than you're comfortable with, because the agent might make multiple allocations.
- Allowed protocols — which protocols can the agent interact with? If you only want Ekubo LP positions, restrict to Ekubo. Don't leave this open.
- Slippage bounds — maximum acceptable slippage per trade. This prevents the agent from executing into thin liquidity.
The validation endpoint (/validate) is useful for testing: you can check whether a proposed action would be allowed under the current session without actually executing it.
Safety practices
- Start short. Grant a 1-hour session for your first autonomous cycle. Extend once you're comfortable.
- Revoke when context changes. If market conditions shift dramatically, revoke and re-grant with updated bounds.
- Monitor in Brain. The Capital OS Brain surface shows active sessions and agent activity. Keep it open during autonomous operation.
- Pair with profile monitoring. Your trust context can change during a session. An expired proof or a collateral event can affect what the agent is allowed to do.
Protocol bitmaps and allowed protocol labels are implementation details that evolve per release. Consume the payloads returned by the API rather than hardcoding protocol identifiers.