# Network · Authentication > How 2plot.ai acts as the Clerk PRIMARY for the whole domain galaxy — the satellite whitelist, the returnTo round trip, and the signup webhook. --- .. toc:: ## One account, every app 2plot.ai is the network's Clerk **primary** instance. Satellite apps (2plot.media, 2plot.xyz, cast.2plot.net, …) run in satellite mode and send visitors here to sign in; after auth the visitor lands back on the exact page that sent them. The round trip: 1. A satellite deep-links to `https://2plot.ai/onboarding?returnTo=`. 2. The hub validates `returnTo` against the **satellite whitelist** — the same origin list handed to Clerk itself, so there is exactly one place a redirect can be authorized (`lib/auth.py`, `allowed_redirect_origins()`; env-overridable via `CLERK_ALLOWED_REDIRECT_ORIGINS` so a new satellite needs no deploy). 3. The sign-in modal opens with force-redirect URLs pointing back to the validated origin. Invalid or missing `returnTo` falls through to the hub home — never an open redirect. .. admonition::Fully optional in dev :icon: tabler:flask :color: yellow With zero `CLERK_*` keys in the environment the entire auth layer no-ops: the app runs unauthenticated, owner gates open up, and no network calls are made. Identical code path, zero configuration. ## The signup webhook `POST /webhooks/clerk` (Svix-verified, fail-closed) receives Clerk events. On `user.created` the hub provisions the new account's welcome wallet on piratesbargain.com through an HMAC-signed cross-app call — and records the outcome (with a privacy-hashed account reference) to the heartbeat, which is the first sensor of the future ledger-of-record flow. ```python # File: lib/auth.py """Optional Clerk authentication gate (dash-clerk-auth, vendored). The integration is FULLY OPTIONAL: with no CLERK_* keys in the environment (or the package missing) the app runs exactly as before — the package's dash hooks no-op, no script/store is injected, no session machinery or routes register. The single source of truth for "is auth on" lives here; run.py (register/configure), the header avatar chip, and the navbar's owner-gated Analytics reveal all call `clerk_enabled()`. Env vars (set all three to enable): CLERK_SECRET_KEY sk_... backend SDK key (never exposed to the client) CLERK_PUBLISHABLE_KEY pk_... embedded in the injected