SEQN Auth Public MVP Readiness

Status date: 2026-06-03

This page is the launch gate for SEQN Auth as a public MVP SaaS. Paid billing, invoices, taxes, and Dodo Payments stay outside this milestone; manual subscription state remains the MVP control.

Live gates now green

  • auth.seqn.in serves /healthz, /v1/config, /, /signin, /signup, keyless /v1/client/config, keyless /v1/setup/agent-context, and the hosted SDK tarball.
  • OIDC discovery for the issuer returned by /v1/config is part of the public smoke gate.
  • Browser SDK CORS preflight now allows x-seqn-publishable-key on /v1/client/config and /v1/config.
  • Anonymous /v1/me and /v1/backend/application return 401.
  • Anonymous /user and /auth/console redirect to hosted sign-in.
  • /auth/login starts the Google/Authentik OIDC flow and sets only an HttpOnly pending-login cookie.
  • Live Postgres has applied 0001_core, 0002_subscriptions, 0003_rate_limits, and 0004_email_deliveries.
  • Dedicated production secret-domain env vars are populated for app-secret hashes, invitation-token hashes, webhook hash/encryption, and Google OAuth hash/encryption.
  • docs.seqn.in is served from the host path /srv/silver-auth/docs-site/public through a read-only Caddy bind mount, so docs survive Caddy container recreation.

Credential-bound gates

  • Hosted Croox email/OTP smoke must pass from the VPS using the production ck_... key and branded auth@seqn.in sender after sender or DNS changes.
  • Offsite encrypted backup needs an upload target and age or GPG recipient.
  • A restore drill must be run against a clean target.
  • Public npm publishing for @seqn/auth-js is pending; the hosted tarball remains the fallback install source until publishing succeeds.
  • The SDK package manifest is public-publish ready (publishConfig.access=public) and npm pack --dry-run produces the intended SDK tarball, but this machine is not logged into npm and npm view @seqn/auth-js currently returns 404, so the actual publish step is still credential/ownership-bound.
  • Authenticated live smokes still require an admin browser session and a fresh non-platform Google account.
  • Authenticated smoke tooling is ready: npm run smoke:authenticated accepts a real SEQN_AUTH_SESSION_COOKIE or SEQN_AUTH_SESSION_TOKEN, defaults to non-mutating session/org/console/platform-boundary checks, and requires SEQN_AUTH_MUTATING_SMOKE=true plus canary inputs before creating apps, rotating a secret, creating an invite, or queueing webhook tests.

Latest blocker verification

  • Live /srv/silver-auth/.env has the dedicated application, invitation, webhook, and Google OAuth secret-domain values populated.
  • Live ops audit passes core env, dedicated secret-domain env, migration files, backup scripts, docs hosting artifacts, and local backup freshness.
  • Live restore drill now passes for backup 20260603T053451Z: the drill restored Authentik into a clean temporary Postgres container with 212 public tables and Silver Auth into a clean temporary Postgres container with 25 public tables plus 4 migration rows, then wrote RESTORE_DRILL.json.
  • Live /srv/silver-auth/.env has hosted Croox email configured. Latest npm run smoke:croox-email passed with direct message and OTP message IDs from comms.seqn.in.
  • seqn.in sender-domain DNS is verified with SPF, DMARC, and OCI DKIM; auth@seqn.in is OCI-approved and live. Latest Croox smoke passed with direct email and OTP message IDs from comms.seqn.in.
  • Live /srv/silver-auth/.env is still missing an offsite backup upload target and age or GPG encryption recipient.
  • Local npm is not logged in, and the public registry does not yet contain @seqn/auth-js.

Required launch smokes

Run the consolidated readiness report from the VPS after deploys and ops changes:

cd /srv/silver-auth
npm run readiness:public-mvp

It runs the public smoke, ops audit, Croox email/OTP smoke, authenticated-smoke readiness classification, and npm publish status checks. A launch-ready result is PASS; the current expected result is BLOCKED until offsite backup, authenticated sessions, and npm publishing credentials are supplied.

Run these after every production deploy:

npm.cmd --prefix services\silver-auth-api run smoke:public-mvp

On the VPS, run the operations audit from /srv/silver-auth after env/docs/backup changes:

npm run audit:ops

Expected launch result is PASS. Current live result is BLOCKED only on offsite encrypted backup configuration, authenticated session/canary keys, and npm publishing credentials; Croox email/OTP and restore proof are green.

Run Croox email/OTP canary after email provider, template, sender, or DNS changes:

cd /srv/silver-auth
SEQN_AUTH_CROOX_CANARY_TO=ops@example.com npm run smoke:croox-email

This sends one non-secret direct email and one OTP email through comms.seqn.in. Confirm inbox placement or provider delivery status before marking sender reputation green.

Run a non-destructive restore drill after each backup or before launch:

cd /srv/silver-auth
npm run drill:restore
npm run audit:ops

Run authenticated smoke from a trusted shell after obtaining a disposable signed-in browser session cookie:

cd /srv/silver-auth
SEQN_AUTH_SESSION_COOKIE='silver_session=...' \
SEQN_AUTH_EXPECT_PLATFORM_ADMIN=false \
npm run smoke:authenticated

For the platform admin smoke, set SEQN_AUTH_EXPECT_PLATFORM_ADMIN=true and use a SEQN-A admin session. For the mutating canary acceptance path, use a disposable org/session and set:

SEQN_AUTH_MUTATING_SMOKE=true
SEQN_AUTH_INVITE_EMAIL=canary@example.com
SEQN_AUTH_WEBHOOK_TEST_DELIVER=false
npm run smoke:authenticated

This intentionally creates a canary app, verifies its publishable/secret-key health, rotates its secret once, creates a one-time invitation, queues a webhook test event, and checks audit access without printing one-time secrets.

Trusted public smoke runners can also include canary app key health in the unauthenticated smoke:

SEQN_AUTH_PUBLISHABLE_KEY=pk_live_...
SEQN_AUTH_SECRET_KEY=sk_live_...
npm run smoke:public-mvp

Without those env vars, the public smoke still passes and reports canary key checks as not configured.

The same check can target staging or a custom docs/auth-engine host:

$env:SEQN_AUTH_BASE_URL="https://auth.seqn.in"
$env:SEQN_AUTH_DOCS_URL="https://docs.seqn.in"
$env:SEQN_AUTH_ENGINE_URL="https://accounts.seqn.in"
npm.cmd --prefix services\silver-auth-api run smoke:public-mvp

Manual equivalent:

curl -fsS https://auth.seqn.in/healthz
curl -fsS https://auth.seqn.in/v1/config
curl -i -X OPTIONS \
  -H "Origin: http://localhost:3000" \
  -H "Access-Control-Request-Method: GET" \
  -H "Access-Control-Request-Headers: x-seqn-publishable-key" \
  https://auth.seqn.in/v1/client/config
curl -fsS "https://auth.seqn.in/v1/client/config?keyless=1"
curl -fsS "https://auth.seqn.in/v1/setup/agent-context?keyless=1&framework=nextjs"
curl -i https://auth.seqn.in/v1/me
curl -i https://auth.seqn.in/v1/backend/application
curl -i https://auth.seqn.in/auth/console
curl -I https://docs.seqn.in/

Trusted runners with real keys should also run seqn-auth-smoke against a canary publishable key and secret key.

Authenticated acceptance

  • Platform admin in SEQN-A can sign in, open /auth/console, list/create projects, rotate a project secret, read audit logs, and access platform Authentik proxy resources.
  • Non-platform Google user can sign up, receives a tenant workspace, can open their own console, and cannot access platform Authentik proxy resources.
  • Logout clears the server session and protected pages redirect back to hosted sign-in.
  • Invite creation returns a one-time invite link and, once SMTP is enabled, queues/sends a sanitized email delivery.
  • Webhook test event signs payloads and records delivery/retry status without exposing whsec_.

Hardening review result

The scoped auth-boundary review for this gate covered session/OIDC handling, CORS, tenant and platform admin checks, webhook signing, email outbox safety, rate limits, and backup-secret handling. No new source bug was identified in this pass. Remaining risk is operational: credentials, restore proof, offsite backup proof, npm publishing, and authenticated live smokes.