Configure

Environment variable checklist

VariableScopeNotes
VITE_SUPABASE_URLClientLovable Cloud URL — safe in the browser.
VITE_SUPABASE_PUBLISHABLE_KEYClientPublishable anon key — safe in the browser.
VITE_TURNSTILE_SITE_KEYClientCloudflare Turnstile site key.
SUPABASE_SERVICE_ROLE_KEYServer onlyNEVER expose to the client. Used by supabaseAdmin.
SUPABASE_DB_URLServer onlyDirect DB string — never expose.
TURNSTILE_SECRET_KEYServer onlyUsed by the verify server function.

Any variable prefixed with VITE_ is bundled into the browser. Never put a secret there.

Cloudflare Turnstile

Wired into both sign-up and sign-in on /auth. The server functionverifyTurnstile validates the token before Supabase auth runs.

  • VITE_TURNSTILE_SITE_KEY — public, in .env.
  • TURNSTILE_SECRET_KEY — server-only Lovable Cloud secret.

Workers

Manage workers at /settings/workers. Each worker holds an HMAC token used to sign requests to /api/public/worker/v1/*. Rotate tokens whenever a host is decommissioned or a token is suspected leaked.

Tenant concurrency caps

Each tenant has a max_concurrent_jobs column. Raise it for clients with large estates; default is conservative to keep the worker pool fair.

Secret storage and rotation

  • Service role key and DB string live only in Lovable Cloud runtime secrets — never in .env, code, or chat.
  • Rotate TURNSTILE_SECRET_KEY if a leak is suspected; redeploy after rotation.
  • Worker tokens rotate per-worker on the settings page; no redeploy required.
  • Supabase project keys rotate via the Lovable Cloud admin tool when needed.

Rotate the Supabase service role key (Lovable Cloud)

This project runs on Lovable Cloud, so the Supabase project dashboard is not directly accessible. The service role key is managed by the Cloud admin tool — never by editing .env in production, and never by logging into the Supabase dashboard.

When to rotate: suspected leak (committed to a public repo, shared in chat or screenshot), compromised worker/CI runner, scheduled quarterly rotation, or migration from legacy JWT-shaped keys to new-format keys.

  1. Open the Cloud admin surface. In the Lovable editor, use the Backend panel (or the "View Backend" action) to reach this project's Cloud settings.
  2. Quiesce dependents. Pause long-running workers or cron consumers that hold the current SUPABASE_SERVICE_ROLE_KEY. They will briefly fail between rotation and redeploy.
  3. Rotate. Ask Lovable to rotate the Supabase API keys for this project. Lovable will generate fresh publishable + service role keys, update the integration's stored credentials, overwrite the server-side secrets (SUPABASE_URL, SUPABASE_PUBLISHABLE_KEY, SUPABASE_SERVICE_ROLE_KEY), and disable the old keys.
  4. Redeploy. Publish the app so server functions pick up the new secrets. Client VITE_* values refresh on the next build.
  5. Verify. Sign in and load /dashboard (publishable key), run an action that uses supabaseAdmin such as a scan (service role key), and confirm server logs show no Invalid API key / JWT expired errors.
  6. Purge old copies. Remove the previous key from any local .env.local, CI secret store, or worker config. Old keys are already disabled server-side; scrubbing prevents confusion later.

Cannot do on Lovable Cloud: fetch the service role key from a Supabase dashboard (there is no dashboard UI for this project), manually edit SUPABASE_SERVICE_ROLE_KEY in .env for production, or recover an old key after rotation. Rotation is destructive — update every consumer before rotating.

Partial failure: if a consumer still reports Invalid API key after redeploy, confirm the deploy actually shipped (check BUILD_VERSION), then rotate again if needed — it is safe. Any consumer still failing is holding the pre-rotation key and must be updated.

Update the service role key in env vars and redeploy

After you rotate the key with the Lovable Cloud admin tool, follow these steps to make sure every environment picks up the new value.

  1. Server-side secrets (production). Lovable Cloud automatically overwrites SUPABASE_URL, SUPABASE_PUBLISHABLE_KEY, and SUPABASE_SERVICE_ROLE_KEY in the runtime secret store during rotation. You do not hand-edit these — attempting to paste a new key into a committed .env file has no effect in production. Confirm the secrets refreshed by opening the Backend panel and checking the timestamp on the Supabase integration.
  2. Client-side publishable values. VITE_SUPABASE_URL and VITE_SUPABASE_PUBLISHABLE_KEY are re-injected into the bundle on the next build. You do not need to change .env in the repo unless the values there are stale copies used for local dev.
  3. Local development (.env.local). On your workstation, open .env.local and replace SUPABASE_SERVICE_ROLE_KEY (and SUPABASE_PUBLISHABLE_KEY / SUPABASE_URL if you had pinned them) with the new values shown by the Cloud admin tool. Restart bun run dev so server functions pick up the change.
  4. External workers & CI. Update any GitHub Actions secrets, worker~/.nso/worker.json config, cron consumers, or third-party integrations that stored the previous SUPABASE_SERVICE_ROLE_KEY. The old key is disabled server-side, so any consumer holding it will fail with Invalid API key until updated.
  5. Redeploy. Trigger a fresh publish from the Lovable editor (Publish → Update) so server functions load the rotated secrets and clients receive a rebuilt bundle. Backend edge functions redeploy automatically; the frontend requires the explicit publish click.
  6. Verify. After the deploy completes:
    • Sign in and load /dashboard — confirms the new publishable key works.
    • Run a privileged action (start a scan, open /settings/admin-users) — confirms supabaseAdmin can reach Postgres with the new service role key.
    • Check BUILD_VERSION in the footer or /operations matches the redeploy, and tail server logs for Invalid API key or JWT expired — a clean tail means every consumer moved over.

If a consumer still fails after redeploy: it is still holding the pre-rotation key. Update that specific consumer's config (worker env file, CI secret, third-party integration) and restart it — no additional Cloud action is required.