Files
cairnquire/.project/specs/authentication-api.md
2026-05-28 08:35:25 -04:00

2.8 KiB

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 /login
  • GET /account
  • POST /api/auth/register/password
  • POST /api/auth/login/password
  • 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=...

The first registered user bootstraps as admin. Later public registrations 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:

Authorization: Bearer cq_pat_<id>_<secret>

The token is shown once. The server stores the token id and SHA-256 hash of the secret. Tokens can be scoped and revoked.

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.

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

  • Public: health, static assets, document reads, login/account entry pages, password/passkey begin-login/register endpoints, device start/token polling.
  • 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.