# Authentication API Milestone 3 uses first-party authentication only. Cairnquire does not implement OAuth in v1. ## Browser Sessions Browser users authenticate with passkeys or password fallback. Successful login sets an opaque `cairnquire_session` cookie. The raw session token is never stored; the database stores a SHA-256 hash and revocation metadata. Endpoints: - `GET /setup` - `POST /api/setup` - `GET /login` - `GET /password-reset?token=...` - `GET /account` - `GET /account/tokens/new` - `POST /api/auth/register/password` - `POST /api/auth/login/password` - `POST /api/auth/password/reset` - `POST /api/auth/logout` - `GET /api/auth/me` - `POST /api/auth/password/change` - `DELETE /api/auth/account` - `POST /api/auth/passkeys/register/begin` - `POST /api/auth/passkeys/register/finish?challengeId=...` - `POST /api/auth/passkeys/login/begin` - `POST /api/auth/passkeys/login/finish?challengeId=...` On an empty database, the one-time `/setup` wizard creates the first `admin` account and records whether public signup is enabled. Later public registrations are accepted only when that setting is enabled and always become `viewer`; role changes are admin-managed from the account screen. Public registration endpoints only create new accounts. Adding or changing credentials on an existing account requires an authenticated browser session. ## API Tokens Developer clients use bearer tokens: ```http Authorization: Bearer cq_pat__ ``` The token is shown once. The server stores the token id and SHA-256 hash of the secret. Tokens can be scoped and revoked. Browser users create tokens at `/account/tokens/new`. Endpoints: - `GET /api/tokens` - `POST /api/tokens` - `DELETE /api/tokens/{id}` Supported scopes: - `docs:read` - `docs:write` - `sync:read` - `sync:write` - `admin` Authorization is role plus scope: a token must have the required scope, and the owning user role must allow that operation. ## Account Administration Administrators update user roles and disabled-account state in one bulk form. Disabled accounts cannot authenticate with passwords, passkeys, existing sessions, or API tokens. At least one enabled administrator account must remain. Administrators can send a password-reset email to a user who cannot log in. Each click creates a fresh one-hour link and invalidates that user's earlier unused reset links. Completing a reset changes the password, consumes the link, and revokes the user's existing browser sessions. Endpoints: - `PATCH /api/admin/auth-users` - `POST /api/admin/auth-users/{id}/password-reset` - `GET /password-reset?token=...` - `POST /api/auth/password/reset` ## Device Flow CLI clients can avoid handling browser cookies by using the first-party device flow: 1. Client calls `POST /api/device/start`. 2. Server returns `deviceCode`, `userCode`, `verificationUri`, and polling interval. 3. User opens the verification URL in a browser and signs in normally. 4. User approves the code with `POST /api/device/approve`. 5. Client polls `POST /api/device/token`. 6. Server returns a normal bearer API token and consumes the device code. This is intentionally inspired by OAuth device authorization, but it is not a general OAuth provider. There are no client registrations, redirect URIs, refresh tokens, consent screens, or third-party identity dependencies. ## Route Protection - Setup-only until configured: initial setup page and endpoint. - Public: health, static assets, document reads, login and password-reset pages, password/passkey begin-login/register endpoints when signups are enabled, password-reset submission, device start/token polling. - Authenticated browser pages: account management and token creation screens. - Session or bearer token required: auth profile/logout, edit/save APIs, uploads, sync/content APIs, device approval. - Admin role required: admin APIs and API token management. WebSocket authentication is session/bearer aware through the shared middleware model. API token creation and account management require a browser session so bearer tokens cannot mint more bearer tokens.