Skip to main content

Security Architecture

Cavos uses a non-custodial OAuth-based wallet architecture. Users authenticate with their existing identity providers (Google, Apple, Firebase) and Cavos derives a unique wallet address from their verified identity—without ever storing private keys on a server.

How It Works

Wallet Derivation

wallet_address = Contract(Poseidon(user_sub, app_salt), class_hash, registry)
ComponentDescription
user_subOAuth subject claim (unique per user per provider)
app_saltPer-app salt derived from your App ID
class_hashCavos Account contract class hash
registryJWKS registry address for JWT verification
The wallet address is deterministic—same user + same app always produces the same wallet. No private key storage required.

Session Keys (Session Keys)

Instead of storing master private keys, Cavos uses short-lived session keys:
  1. Session Creation: SDK generates a fresh session key pair on each login
  2. JWT Binding: The ephemeral public key is embedded in the JWT nonce
  3. On-chain Registration: The smart contract verifies the JWT and registers the session key
  4. Transaction Signing: All transactions are signed with the session key
┌─────────────┐     ┌───────────────┐     ┌──────────────┐
│ Google JWT  │ ──► │ Cavos Account │ ──► │ Session Key  │
│ (proof)     │     │ (verifies)    │     │ (signs txs)  │
└─────────────┘     └───────────────┘     └──────────────┘

Session Expiration

ParameterDefaultDescription
sessionDuration~24 hoursBlocks until session expires
renewalGracePeriod~24 hoursWindow to renew before expiry
Sessions can be renewed with a fresh JWT before expiration.

Per-App Wallet Isolation

Each app registered on Cavos gets its own app salt, ensuring:
  • Same user on different apps = different wallet addresses
  • Apps cannot access each other’s user funds
  • Users maintain separate identities per app
// App A wallet for user@gmail.com
0x1234...abc

// App B wallet for user@gmail.com (same user, different wallet)
0x5678...def

What Cavos Stores vs Doesn’t Store

DataStored?Notes
Private keys❌ NeverDerived client-side only
OAuth tokens❌ NeverJWT verified and discarded
User sub (ID)✅ HashedFor MAU tracking only
Wallet address✅ PublicFor analytics

What Cavos Cannot Do

  • Access user funds: No private keys stored anywhere
  • Sign transactions: Only users with valid OAuth JWTs can sign
  • Impersonate users: JWTs are verified on-chain via JWKS registry

On-Chain Verification

The Cavos Account smart contract verifies every transaction:
  1. JWT Signature: Verified against Google/Apple JWKS public keys stored on-chain
  2. Nonce Validation: Ensures JWT was issued for this specific session
  3. Expiration Check: JWT and session must be within validity period
  4. Session Key: Ephemeral key must match JWT-registered session
// Simplified verification flow
fn validate_transaction(jwt, session_sig) {
    verify_jwt_signature(jwt, jwks_registry);
    verify_nonce_matches(jwt.nonce, session.ephemeral_pub);
    verify_session_not_expired(session.max_block);
    verify_ecdsa_signature(session_sig, session.ephemeral_pub);
}

Attack Vectors & Mitigations

OAuth Provider Compromise

If Google/Apple’s signing keys are compromised:
  • Risk: Attacker could forge JWTs
  • Mitigation: JWKS registry on-chain; Cavos monitors and updates
  • Mitigation: Session bound to specific session key generated client-side

Browser XSS

If attacker injects JavaScript:
  • Risk: Could access session key in session storage
  • Mitigation: Session keys are short-lived (~24h)
  • Mitigation: Session bound to specific JWT claims
  • Mitigation: Implement Content Security Policy

Backend Compromise

If Cavos servers are compromised:
  • Risk: Attacker could return malicious app_salt
  • Mitigation: app_salt is deterministic from app_id—users would notice different wallet
  • Mitigation: No private keys stored to steal

Man-in-the-Middle

  • Mitigation: All API calls over HTTPS
  • Mitigation: JWT signature verification is on-chain (cannot be spoofed)

Best Practices

For Developers

  1. Use HTTPS everywhere
  2. Implement Content Security Policy to prevent XSS
  3. Validate all user inputs before contract calls
  4. Don’t expose appId secrets in client-side code (appId is public, but don’t commit env files)
  5. Monitor your MAU usage via dashboard

For Users

  1. Protect your OAuth account (Google/Apple) with 2FA
  2. Review connected sessions periodically
  3. Use on trusted devices only
  4. Check transaction details before signing

Compliance Notes

Cavos wallet infrastructure is:
AspectStatus
Non-custodial✅ Users control their own wallets
No key storage✅ Private keys never stored server-side
User-initiated only✅ All transactions require active user auth
Auditable✅ All verification logic is on-chain
This documentation describes the OAuth-based wallet architecture. Cavos does not hold custody of any user funds.