Skip to main content

Architecture Overview

Cavos uses session keys bound to OAuth JWTs. Instead of storing a master private key, the SDK generates a fresh session key pair on each login that’s cryptographically linked to the user’s verified identity.

How Sessions Work

1. Session Initialization (Pre-Login)

When you call login(), the SDK generates a session key pair and computes a nonce before the OAuth redirect:
// Generated BEFORE OAuth redirect
const sessionPrivateKey = generateStarkKey();  // Random 252-bit Stark key
const sessionPubKey = derivePublicKey(sessionPrivateKey);

// Split pubkey into two 128-bit halves (lo/hi)
const eph_pubkey_lo = sessionPubKey & ((1n << 128n) - 1n);
const eph_pubkey_hi = sessionPubKey >> 128n;

// Compute nonce that binds the JWT to this session key and block range
const nonce = poseidon([
  eph_pubkey_lo,
  eph_pubkey_hi,
  max_block,     // block height after which the session expires
  randomness     // random value for replay protection
]);

2. OAuth Redirect

The nonce is included in the OAuth request to Google or Apple.

3. JWT Verification

When the user completes OAuth, the JWT returned contains the nonce, proving the identity is linked to that specific browser session.

4. On-Chain Registration

The first transaction registers the session by verifying the JWT signature and nonce on-chain.

Session Management

The SDK provides methods to manage your active on-chain sessions.

Session Renewal

Sessions expire after 24h by default. Within the 48h grace period after expiry, you can renew without a new OAuth login — the old session key signs the renewal request for the new key.
const { renewSession } = useCavos();

try {
  const txHash = await renewSession();
  console.log('Session renewed:', txHash);
} catch (err) {
  if (err.message.includes('still active')) {
    // Not expired yet — no action needed
  } else if (err.message.includes('outside the grace period')) {
    // Beyond 48h grace — must re-login
    await login('google');
  }
}
The SDK also handles renewal automatically inside execute(): if the session is expired but within the grace period, it renews before executing the transaction.

Explicit Registration

The session key is normally registered on-chain automatically during the first transaction. If you need to register it before any transaction (e.g., to pre-activate a policy), call:
const { updateSessionPolicy, registerCurrentSession } = useCavos();

// Always update policy before registering
updateSessionPolicy({
  allowedContracts: [TOKEN_ADDRESS],
  spendingLimits: [{ token: TOKEN_ADDRESS, limit: BigInt(10 * 10**18) }],
  maxCallsPerTx: 5,
});

const txHash = await registerCurrentSession();
[!WARNING] If you change the policy after login but before registration, you must call updateSessionPolicy() first — otherwise the stale policy from login time gets registered on-chain.

Session Policies

Session keys can be restricted by policies to limit the damage if a session key is compromised. Policies are enforced by the account contract on every transaction. They are set at session registration time and cannot be changed without creating a new session.
// Policy shape (matches CavosProvider session.defaultPolicy)
const policy = {
  allowedContracts: string[],                              // contract addresses the session may call
  spendingLimits?: Array<{ token: string, limit: bigint }>, // max spend per token
  maxCallsPerTx?: number,                                   // max calls in a single multicall
};

allowedContracts

Restricts the session key to specific contract addresses. Any call to a contract not in this list is rejected by the account contract at the validation step.
allowedContracts: [
  '0x049d36570d4e46f48e99674bd3fcc84644ddd6b96f7c741b1562b82f9e004dc7', // ETH
  '0x04718f5a0fc34cc1af16a1cdee98ffb20c31f5cd61d6ab07201858f4287c938d', // STRK
]

spendingLimits

Caps the total amount of a given token the session key can transfer. The account contract accumulates spend across all transactions and rejects any call that would exceed the limit.
spendingLimits: [
  { token: '0x04718f5a0fc34cc1af16a1cdee98ffb20c31f5cd61d6ab07201858f4287c938d', limit: 10n * 10n**18n }, // 10 STRK
]

maxCallsPerTx

Limits the number of calls that may be bundled into a single multicall transaction. Useful for preventing automated abuse.
maxCallsPerTx: 5

Session Revocation

If you suspect a session key has been compromised, or simply want to logout securely from a shared device, you have two options:

1. Revoke Specific Session

Invalidates a single session key on-chain. The sessionKey argument is required — pass sessionPublicKey from useCavos() to revoke the current one.
const { revokeSession, sessionPublicKey } = useCavos();

// Revoke the current session key
if (sessionPublicKey) {
  await revokeSession(sessionPublicKey);
}

// Or revoke any specific session key by its public key
await revokeSession('0x123...');

2. Emergency Revoke All

Invalidates all currently active sessions for the wallet by incrementing the global revocation epoch.
const { emergencyRevokeAllSessions } = useCavos();

await emergencyRevokeAllSessions();

Session Export/Import

For advanced use cases like command-line tools or multi-device workflows, you can export active sessions and import them elsewhere.

Export Session from Dashboard

Export your current active session as a base64-encoded token:
const { exportSession, walletStatus } = useCavos();

// Only export when session is active
if (walletStatus.isSessionActive) {
  const token = exportSession();
  
  // Copy to clipboard
  navigator.clipboard.writeText(token);
  console.log('Session exported!');
}
[!WARNING] The exported token contains your session private key. Store it securely and never share it publicly.

Import Session in CLI

Once exported, the session can be used in the Cavos CLI without any login:
# Set as environment variable
export CAVOS_TOKEN="<base64_token>"

# Or import directly
cavos session import <base64_token>

# Execute commands
cavos balance
cavos transfer --to 0x... --amount 1.5 --token STRK --wait
cavos approve --spender 0x... --amount 100 --token STRK

Use Cases

  1. AI Agents: Export session from your dashboard, give it to an AI agent for autonomous trading/transactions
  2. CI/CD Pipelines: Automate on-chain deployments without manual signing
  3. Multi-Device: Use the same session on desktop dashboard and mobile/server CLI
  4. Batch Operations: Execute multiple transactions quickly from command line
[!NOTE] Exported sessions have the same policies (spending limits, allowed contracts) as configured in the dashboard.
  • Non-Custodial: Neither Cavos nor the application ever sees your session private key. It lives only in your browser’s memory.
  • Auto-Expiry: Sessions automatically expire, minimizing the impact of a lost device or session key.
  • Per-App Isolation: Each app uses a different derivation salt, so a session key for App A cannot sign for App B.
  • Enforced Policies: Even if a session key is stolen, the attacker is limited by the allowed contracts and spending limits defined at session creation.