Aelio
Guides

Authentication

How authentication works across SDK, server, and widget.

Aelio uses three separate authentication mechanisms. Do not conflate them.

1. SDK authentication

The SDK connects to the server over WebSocket at /sdk with a Bearer token:

Authorization: Bearer <AELIO_SDK_SECRET>
  • Constant-time comparison (timingSafeEqual)
  • Max 32 concurrent SDK connections
  • Must send register frame within 15s or connection is closed
  • Auto-reconnect with exponential backoff
await aelio.listen({
  secret: process.env.AELIO_SDK_SECRET,
  url: 'ws://127.0.0.1:3010',
});

For production, the widget uses short-lived session tokens:

Your backend → POST /auth/magic-link (Bearer secret)
  → magic link URL
  → user clicks → GET /auth/verify?token=...
  → sessionToken
  → widget init with authToken

Session tokens are HMAC-SHA256 signed, TTL default 60 minutes. The server verifies the token matches customerId.

See Widget Authentication for the full flow.

3. Protected HTTP routes

These routes require Authorization: Bearer <AELIO_SDK_SECRET>:

RoutePurpose
POST /auth/magic-linkIssue magic link
POST /proactiveSend proactive message
POST /proactive/opt-inSet customer opt-in
GET /api/v1/telemetry/*Telemetry data

Also accepts x-aelio-secret header as an alternative.

4. WhatsApp webhook auth

  • GET verification: hub.verify_token must match config
  • POST messages: HMAC x-hub-signature-256 verified against raw body + app_secret

Security rules

DoDon't
Store AELIO_SDK_SECRET in server env varsPut AELIO_SDK_SECRET in frontend code
Issue session tokens from your backendHardcode customer IDs in production
Use HTTPS/WSS in productionUse allow_anonymous: true in production
Rotate secrets periodicallyShare secrets across environments

Anonymous mode (dev only)

identity:
  allow_anonymous: true

Allows widget init with just customerId and email, no token required.

On this page