Skip to main content

Authentication

Cadenza uses OAuth 2.0 Bearer token authentication powered by Supabase Auth.

Overview

┌─────────┐     1. Login      ┌─────────────┐
│ Client │ ───────────────── │ Cadenza │
│ │ ◄──────────────── │ Auth │
└─────────┘ 2. Access Token └─────────────┘

│ 3. API Request + Bearer Token

┌─────────────┐
│ Cadenza │
│ API │
└─────────────┘

Authentication Flow

1. Login

Authenticate with email and password to receive tokens:

import { createClient } from '@supabase/supabase-js'

const supabase = createClient(SUPABASE_URL, SUPABASE_ANON_KEY)

const { data, error } = await supabase.auth.signInWithPassword({
email: 'user@example.com',
password: 'your-password',
})

const accessToken = data.session.access_token
const refreshToken = data.session.refresh_token

2. Use Access Token

Include the access token in the Authorization header for all API requests:

Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...

3. Refresh Token

Access tokens expire after 1 hour. Use the refresh token to get a new access token:

const { data, error } = await supabase.auth.refreshSession()
const newAccessToken = data.session?.access_token

Token Properties

PropertyDescription
accessTokenJWT token for API authentication (expires in 1 hour)
refreshTokenToken for obtaining new access tokens (longer lived)
expiresInToken lifetime in seconds
expiresAtToken expiration Unix timestamp

WebSocket Authentication

For WebSocket connections, pass the access token when creating the client:

import { Centrifuge } from 'cadenza-client-typescript'

const client = new Centrifuge(CADENZA_WS_URL, {
token: accessToken,
})

client.connect()

Token Expiry Handling

When a token expires:

  • HTTP API returns 401 Unauthorized
  • WebSocket disconnects with code 3500

Handle expiry by refreshing the token and retrying the request.

Security Best Practices

  1. Never expose tokens in client-side code or logs
  2. Store tokens securely (e.g., httpOnly cookies, secure storage)
  3. Refresh proactively before expiration to avoid interruptions
  4. Use HTTPS for all API communications