Skip to main content

Authentication

Base path: /auth

GET /auth/:provider/start​

Begin an OAuth flow for the given provider (e.g. discord, local).

Auth: None required (public) Tenant: Resolved from x-tenant-id header, tenantId query param, body field, or session

Query Parameters​

ParameterTypeRequiredDescription
redirectUristringNoOAuth redirect URI override; falls back to server config
modestringNojson (default) returns JSON with the authorization URL; redirect issues a 302 redirect
postLoginRedirectstringNoRelative path (/…) to redirect to after login completes
tenantIdstringNoTenant identifier (alternative to header)

Response — mode json (200)​

{
"authorizationUrl": "https://discord.com/oauth2/authorize?...",
"state": "<opaque>"
}

Response — mode redirect (302)​

Redirects the browser to the provider's authorization URL.

Errors​

StatusCondition
400Auth provider not configured, missing redirectUri, or provider error
404Auth provider configuration not found for the given tenant/provider

GET /auth/:provider/callback​

OAuth callback endpoint. Exchanges the authorization code for tokens, creates or links the user identity, and issues a session.

Auth: None required (called by the OAuth provider) Tenant: Recovered from the OAuth state token

Query Parameters​

ParameterTypeRequiredDescription
codestringYesAuthorization code from the OAuth provider
statestringYesOpaque state token issued during /start

Behavior​

  1. Validates and consumes the OAuth state token.
  2. Exchanges the authorization code for access/refresh tokens via the provider.
  3. Creates or retrieves a user and identity record.
  4. For Discord providers, grants TenantAdmin to the first user in a tenant with no existing permissions.
  5. Issues a session cookie. If the original /start included a postLoginRedirect, the response is a 302 redirect; otherwise returns JSON.

Response (200)​

{
"session": { "sessionId": "...", "user": { "userId": "...", "tenantId": "...", "displayName": "...", "email": "..." }, "permissionKeys": [...] }
}

Response (302)​

Redirects to the postLoginRedirect path when one was provided in the original /start call.

Errors​

StatusCondition
400Missing code/state, invalid or expired state, provider mismatch, missing tenantId, missing redirectUri, or exchange error
404Auth provider configuration not found

POST /auth/:provider/login​

Authenticate with username and password for credential-based providers (e.g. local).

Auth: None required Tenant: Resolved from x-tenant-id header, tenantId query/body, or session

Request Body​

FieldTypeRequiredDescription
usernamestringYesLogin username
passwordstringYesLogin password
tenantIdstringNoTenant identifier (alternative to header)

Behavior​

  1. Resolves the provider configuration for the tenant.
  2. Delegates authentication to the provider adapter.
  3. Creates or retrieves a user and identity record.
  4. For the local provider, automatically grants the TenantAdmin role to the default admin user.
  5. Issues a session cookie and returns the session object.

Response (200)​

{
"session": { "sessionId": "...", "user": { "userId": "...", "tenantId": "...", "displayName": "...", "email": "..." }, "permissionKeys": [...] }
}

Errors​

StatusCondition
400Missing username/password, missing tenantId, invalid credentials, or provider error
404Auth provider configuration not found

POST /auth/logout​

Log out the current session (JSON response).

Auth: Session cookie (optional — clears whatever session exists)

Request Body​

None.

Response (200)​

{ "ok": true }

GET /auth/logout​

Log out the current session and redirect.

Auth: Session cookie (optional)

Query Parameters​

ParameterTypeRequiredDescription
redirectTostringNoSame-origin path to redirect to after logout. Must start with / and must not contain //. Defaults to /.

Response (302)​

Clears the session cookie and redirects to the validated redirectTo path (or /).


GET /auth/me​

Return the current authenticated session.

Auth: Session cookie required

Response (200)​

{
"session": {
"sessionId": "...",
"user": { "userId": "...", "tenantId": "..." },
"permissionKeys": [...]
}
}

Errors​

StatusCondition
401No active session (unauthenticated)

POST /auth/tenant​

Switch the active tenant for the current session. Re-issues the session with permissions for the new tenant.

Auth: Session cookie required

Request Body​

FieldTypeRequiredDescription
tenantIdstringYesTarget tenant identifier

Response (200)​

{
"session": { "sessionId": "...", "user": { "userId": "...", "tenantId": "...", "displayName": "...", "email": "..." }, "permissionKeys": [...] }
}

Errors​

StatusCondition
400Missing tenantId or error resolving permissions
401Unauthenticated