feat(auth): require sign-in on every install - #440
Merged
Merged
Conversation
Fox used to open straight into the workspace on a personal install, and a multi-user server let anyone register. Now every install signs in, and only an administrator creates accounts. - First launch is setup: it creates the admin, or on an install used before claims the existing local account so connections and history stay. A bound APP_USER_EMAIL is used as-is. - Setup from another machine (anything not a direct loopback request, so a reverse proxy or the Vite proxy counts as remote) needs a one-time code printed to the server log. Setup closes once an account can sign in, and a server already running multi-user is never offered it. - /api/auth/register answers 403; admins add users (POST /api/admin/users and an Add user form). SSO signs in existing accounts only. - Sign-in is rate-limited to 20 per 15 minutes. - users.password_set (migration 19) records who can sign in. - AUTH_REQUIRED is gone; LOCAL_SINGLE_USER now only marks a personal install for machine-level routes. The CLI resolves the same owner account. - e2e suites sign in through a cached session (apps/e2e/.env); the nightly cloud workflow makes a password per run. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Contributor
Bugbot couldn't run - usage limit reachedBugbot is counted against Cursor usage for this user or team, and this run hit a usage or spend limit. A user or team admin can review and increase usage limits in the Cursor dashboard. (requestId: serverGenReqId_9a431d8d-1a91-4ec6-9111-587711f1dfb1) |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What changes
Every install now requires sign-in, and only an administrator creates accounts.
POST /api/auth/register→ 403; admins use Add user (POST /api/admin/users)Upgrade: on an install used before, setup claims the existing local account (or the bound
APP_USER_EMAIL), so saved connections, history and workflows stay. A server already running withLOCAL_SINGLE_USER=falsekeeps its accounts and is never offered setup.Setup code: a request from the machine Fox runs on (raw loopback socket, no forwarding headers) needs only a password. Anything else, including a reverse proxy, Docker port mapping, or the Vite dev proxy (now
xfwd: true), must also enter a one-time code printed to the server log. The code is compared in constant time and stops working once setup is done; concurrent setups are serialized.AUTH_REQUIREDis removed.LOCAL_SINGLE_USERnow only marks a personal install, which gates machine-level routes (driver install, updates, host cloud credentials). The CLI resolves the same owner account throughownerAccount(). Metadata migration 19 addsusers.password_set; it is append-only.Verification
apps/webtsc, CLI tsc, e2e tsc: clean.npm run lint,lint:securityandbuildall pass.npx vitest run: 426 files, 5058 passed.auth.setup.test.ts: claim, bound email, race, explicit multi-user, CLI owner.setup.routes.test.ts(real listener): a proxied caller needs the code; wrong code 403; right code works once, then 409; register 403; admin add-user, where a viewer gets 403 and no session gets 401.AuthPage.test.tsx.npm run dev:🤖 Generated with Claude Code
Note
High Risk
Mandatory authentication on all deployments changes default access for every user and install; setup claiming, session guards, and closed registration are security-critical paths that affect upgrades and exposed servers.
Overview
Every install now requires sign-in. The old open single-user mode and
AUTH_REQUIREDare gone; all API routes use the session guard except public auth, signup, and health endpoints.First-run setup replaces anonymous boot and self-registration:
GET/POST /api/auth/setupcreates or claims the legacylocal@foxschema.appaccount so existing connections and history survive upgrades. Remote or proxied callers (Docker, reverse proxy, Vitexfwd) must enter a one-time setup code from the server log.POST /api/auth/registerreturns 403; admins add users viaPOST /api/admin/usersand a new Add user form in Access control. SSO only signs in pre-provisioned accounts. Sign-in/setup is rate-limited (20 per 15 min).LOCAL_SINGLE_USERnow only gates machine-level actions (drivers, updates), not whether login is required. The CLI usesownerAccount()to align with the claimed install owner. The UI auth flow drops the fake local user: setup vs login onAuthPage, Sign out always visible. E2E and CI sign in via a cached session helper hitting the API port directly. Migration 19 addsusers.password_setto track when setup can close.Reviewed by Cursor Bugbot for commit 917ad58. Bugbot is set up for automated code reviews on this repo. Configure here.