Overview
Desktop cloud fallback is gated on aWORLDMONITOR_API_KEY. Without a valid key, the desktop app operates local-only (sidecar). A registration form collects emails via Convex DB for future key distribution.
Architecture
Required Environment Variables
Vercel
| Variable | Description | Example |
|---|---|---|
WORLDMONITOR_VALID_KEYS | Comma-separated list of valid API keys | wm_abc123def456,wm_xyz789 |
CONVEX_URL | Convex deployment URL (from npx convex deploy) | https://xyz-123.convex.cloud |
Generating API keys
Keys must be at least 16 characters (validated client-side). Recommended format:WORLDMONITOR_VALID_KEYS in Vercel dashboard (comma-separated, no spaces).
Convex Setup
First-time deployment
Verify Convex deployment
Schema
Theregistrations table stores:
| Field | Type | Description |
|---|---|---|
email | string | Original email (for display) |
normalizedEmail | string | Lowercased email (for dedup) |
registeredAt | number | Unix timestamp |
source | string? | Where the registration came from |
appVersion | string? | Desktop app version |
normalizedEmail for duplicate detection.
Security Model
Client-side (desktop app)
installRuntimeFetchPatch()checksWORLDMONITOR_API_KEYbefore allowing cloud fallback- Key must be present AND valid (min 16 chars)
secretsReadypromise ensures secrets are loaded before first fetch (2s timeout)- Fail-closed: any error in key check blocks cloud fallback
Server-side (Vercel edge)
api/_api-key.jsvalidatesX-WorldMonitor-Keyheader on sebuf routes- Origin-aware: desktop origins (
tauri.localhost,tauri://,asset://) require a key - Web origins (
worldmonitor.app) pass through without a key - Non-desktop origin with key header: key is still validated
- Invalid key returns
401 { error: "Invalid API key" }
CORS
X-WorldMonitor-Key is allowed in both server/cors.ts and api/_cors.js.
Verification Checklist
After deployment:- Set
WORLDMONITOR_VALID_KEYSin Vercel - Set
CONVEX_URLin Vercel - Run
npx convex deployto push schema - Desktop without key: cloud fallback blocked (console shows
cloud fallback blocked) - Desktop with invalid key: sebuf requests get
401 - Desktop with valid key: cloud fallback works as before
- Web access: no key required, works normally
- Registration form: submit email, check Convex dashboard
- Duplicate email: shows “already registered”
- Existing settings tabs (LLMs, API Keys, Debug) unchanged
Files Reference
| File | Role |
|---|---|
src/services/runtime.ts | Client-side key gate + header attachment |
src/services/runtime-config.ts | WORLDMONITOR_API_KEY type, validation, secretsReady |
api/_api-key.js | Server-side key validation (origin-aware) |
api/[domain]/v1/[rpc].ts | Sebuf gateway — calls validateApiKey |
api/register-interest.js | Registration endpoint → Convex |
server/cors.ts / api/_cors.js | CORS headers with X-WorldMonitor-Key |
src/components/WorldMonitorTab.ts | Settings UI for key + registration |
convex/schema.ts | Convex DB schema |
convex/registerInterest.ts | Convex mutation |
