Skip to main content

Secrets

Auth isolation

Separate viewer vs operator Supabase cookie jars (lib/supabase/auth-scope.ts). Theme preview requires operator session.

Database

Enable and keep RLS migrations applied (006+). Service role only on the server.

Cron / jobs

POST /api/internal/jobs/run requires header X-Streamly-Cron-Secret: <STREAMLY_CRON_SECRET>.

Operator login

  • First install requires STREAMLY_INITIAL_ADMIN_EMAIL and STREAMLY_INITIAL_ADMIN_PASSWORD (server-only, never NEXT_PUBLIC_, password ≥ 16 characters). Only that pair creates and promotes the first operator.
  • Passwords are hashed by Supabase Auth. Streamly never stores plaintext passwords in application tables.
  • After the first operator exists, /api/admin/login uses signInWithPassword and allows access only when profiles.is_operator=true. Unknown users are never promoted. In production, the bootstrap password cannot reset an existing operator.
  • You may remove STREAMLY_INITIAL_ADMIN_PASSWORD from the host after bootstrap.
  • Configured bootstrap secrets are never returned to the browser.
  • /api/admin/login is rate-limited per application instance. Also configure your host firewall/WAF for distributed rate limiting in production.
  • Public viewer signup does not create operators. The shared operator demo is available only when the public preview explicitly sets ENABLE_DEMO=true; customer deployments must leave it disabled. There is no Envato verification.