Skip to main content
WorldMonitor uses Clerk for authentication. The auth system gates premium panels behind sign-in and tier checks, and enforces session-based access on server-side API endpoints via local JWT verification.

Auth Stack

Key Files


Panel Gating

Premium panels show a CTA overlay instead of content until the user meets the access requirements.

Gate Reasons

How to Configure Which Panels Are Premium

Three files control gating. All three must stay in sync when adding or removing premium panels.

1. Panel config — src/config/panels.ts

Add premium: 'locked' to the panel entry in the relevant variant:

2. Client-side gate set — src/app/panel-layout.ts

Add the panel key to WEB_PREMIUM_PANELS:
This set drives the reactive UI gating — when auth state changes, panels in this set get checked and show/hide CTAs accordingly.

3. Server-side API enforcement (if the panel calls premium APIs)

Client token injectionsrc/services/runtime.ts (WEB_PREMIUM_API_PATHS):
When a fetch request matches a path in this set and the user has a Clerk session, the client automatically injects Authorization: Bearer <token>. Server gatewayserver/gateway.ts (PREMIUM_RPC_PATHS):
The gateway validates the bearer token via local JWKS verification (jose) and checks session.role === 'pro'. Returns 403 if the user isn’t pro.

Currently Gated Panels

Desktop Behavior

Desktop users with a valid WORLDMONITOR_API_KEY in the Tauri keychain bypass all panel gating. The existing API key flow is unaffected — bearer tokens are a second auth path, not a replacement.

Server-Side Session Enforcement

The Vercel API gateway accepts two forms of authentication for premium endpoints:
  1. Static API keyX-WorldMonitor-Key header (existing flow, unchanged)
  2. Bearer tokenAuthorization: Bearer <clerk_jwt> (for web users)
The gateway tries the API key first. If that fails on a premium endpoint, it falls back to bearer token validation using local JWKS verification via server/auth-session.ts. The JWT is verified against:
  • Issuer: CLERK_JWT_ISSUER_DOMAIN
  • Audience: convex (matches the Clerk JWT template)
  • Signature: RSA256 via Clerk’s published JWKS
Non-premium endpoints don’t require any authentication from web origins.

Environment Variables


User Roles

User roles (pro / free) are stored as a plan claim in the Clerk JWT. The server extracts this from the verified token payload. Unknown or missing plan values default to free (fail closed — never pro). On the client side, getAuthState().user?.role exposes the role. Both isProUser() and hasPremiumAccess() check this alongside legacy API key gates.