Skip to content

Authentication

Slotty Labs uses API keys and SSO tokens to authenticate operators and players.

API Key Format

EnvironmentPrefixExample
Sandboxsk_sandbox_sk_sandbox_abc123def456...
Productionsk_live_sk_live_xyz789ghi012...

DANGER

Sandbox and production keys are NOT interchangeable. A sandbox key will be rejected in production, and vice versa.

Integration Modes

Slotty Labs supports two integration modes:

Transfer Mode

The platform manages player authentication entirely. Slotty Labs creates and manages player accounts internally.

  • Simpler to integrate
  • Less control over player lifecycle
  • Suitable for smaller operators

The operator manages player authentication via SSO. The operator's backend creates launch tokens that map to existing player accounts.

  • Full control over player identity
  • Single sign-on experience
  • Recommended for B2B integrations

SSO Token Flow

The SSO flow consists of 5 steps:

┌──────────┐     ┌──────────────┐     ┌──────────────┐
│ Operator │     │  Slotty Labs │     │  Game Client  │
│ Backend  │     │     API      │     │   (iframe)    │
└────┬─────┘     └──────┬───────┘     └──────┬────────┘
     │                  │                    │
     │ 1. POST /auth/sso/create-token       │
     │  (API key + HMAC)│                    │
     │─────────────────>│                    │
     │                  │                    │
     │ 2. JWT launch    │                    │
     │    token (30s)   │                    │
     │<─────────────────│                    │
     │                  │                    │
     │ 3. Token in URL  │                    │
     │──────────────────┼───────────────────>│
     │                  │                    │
     │                  │ 4. POST /auth/sso/exchange
     │                  │<───────────────────│
     │                  │                    │
     │                  │ 5. Session token   │
     │                  │───────────────────>│
     │                  │                    │
  1. Operator backend calls POST /api/v1/auth/sso/create-token with API key and HMAC signature
  2. Slotty Labs API returns a single-use JWT launch token with a 30-second TTL
  3. Operator passes the token to the game iframe via URL parameter
  4. Game client exchanges the token for a session via POST /api/v1/auth/sso/exchange
  5. Subsequent API calls use the session token from the exchange response

HMAC Request Signing

All API requests must include HMAC signatures for authentication:

X-Slotty-Timestamp: <unix seconds>
X-Slotty-Signature: sha256=<HMAC-SHA256 of "timestamp.METHOD.path.body">

Signing Algorithm

typescript
import crypto from 'crypto';

function signRequest(
  secret: string,
  timestamp: number,
  method: string,
  path: string,
  body: string,
): string {
  const payload = `${timestamp}.${method}.${path}.${body}`;
  const hmac = crypto.createHmac('sha256', secret);
  hmac.update(payload);
  return `sha256=${hmac.digest('hex')}`;
}

Timestamp Tolerance

The server accepts timestamps within ±5 minutes (300 seconds) of the current time. All comparisons use timing-safe equality to prevent timing attacks.

SSO Token Claims

The JWT launch token contains these claims:

ClaimDescriptionExample
subPlayer external ID"player-123"
tidTenant (operator) ID"tenant-abc"
curCurrency code"USD"
jurJurisdiction code"CW"
locLocale"en"
pidInternal player ID"pl_abc123"
gidTarget game ID (optional)"slotty-slots"
demoDemo mode flagfalse
unameDisplay username"Player123"
jtiUnique token ID"tok_xyz789"

Single-Use Enforcement

Each SSO token can only be used once. After exchange, the token's jti is stored in Redis:

Key:   {tenantId}:sso:used:{jti}
TTL:   120 seconds

Any attempt to reuse an exchanged token will return a SSO_TOKEN_ALREADY_USED error.

SSO Exchange Response

A successful token exchange returns:

typescript
interface SSOExchangeResponse {
  accessToken: string;       // JWT for API calls (15min TTL)
  refreshToken: string;      // Refresh token (7d TTL)
  sessionId: string;         // Unique session identifier
  player: {
    id: string;              // Internal player ID
    externalId: string;      // Operator's player ID
    username: string;        // Display name
    currency: string;        // Player currency
    jurisdiction: string;    // Jurisdiction code
  };
}

Session Information

Active sessions expose the following data:

typescript
interface SessionInfo {
  sessionId: string;
  playerId: string;
  tenantId: string;
  jurisdiction: string;
  activeGameId: string | null;
  sessionDuration: number;          // seconds elapsed
  maxSessionMinutes: number;        // jurisdiction limit
  nextRealityCheckAt: string;       // ISO 8601 timestamp
}

REST API Example

Create SSO Token

typescript
// POST /api/v1/auth/sso/create-token
const response = await fetch('https://api.slottylabs.com/api/v1/auth/sso/create-token', {
  method: 'POST',
  headers: {
    'Content-Type': 'application/json',
    'Authorization': 'Bearer sk_live_abc123...',
    'X-Slotty-Timestamp': timestamp.toString(),
    'X-Slotty-Signature': signature,
  },
  body: JSON.stringify({
    externalPlayerId: 'player-123',
    currency: 'USD',
    jurisdiction: 'CW',
    locale: 'en',
    username: 'Player123',
    gameId: 'slotty-slots',
    demoMode: false,
  }),
});

const { data } = await response.json();
// data.launchToken — single-use JWT, 30s TTL