Skip to content

Auth API

Endpoints for OIDC authentication, trusted-proxy authentication, and local session management. These endpoints are only available after setup is complete (instance state is ready). Calling them before setup returns 409 Conflict with code setup_incomplete.

OIDC Start

Initiate an OIDC authorization code flow. Returns an authorization URL to redirect the user to.

GET /v1/auth/oidc/start

Authentication: None (public)

Query parameters

ParameterRequiredDescription
redirect_uriNoCustom redirect URI (defaults to standard callback)

Response 200 OK

json
{
  "authorization_url": "https://accounts.google.com/o/oauth2/v2/auth?client_id=...&redirect_uri=...&state=...&nonce=...",
  "state": "abc123-csrf-state-token"
}
FieldTypeDescription
authorization_urlstringFull authorization URL to redirect the user to
statestringCSRF state token for validating the callback

The daemon generates a PKCE challenge (S256), CSRF state token, and nonce internally. Pending auth entries expire after 10 minutes.

Error responses

StatusCodeDescription
409setup_incompleteSetup is not yet complete
429too_many_pendingToo many pending auth requests (limit: 1000)
500oidc_not_configuredOIDC configuration is missing
502oidc_discovery_errorFailed to perform OIDC discovery

OIDC Callback

Complete the OIDC authorization code flow. Exchanges the authorization code for tokens, verifies the ID token, and creates a user session.

POST /v1/auth/oidc/callback

Authentication: None (public)

Request body

json
{
  "code": "4/0AX4XfWh...",
  "state": "abc123-csrf-state-token"
}
FieldTypeRequiredDescription
codestringYesAuthorization code from the IdP callback
statestringYesCSRF state token (must match the value from oidc/start)

Response 200 OK

json
{
  "session_token": "user_session_abc123...",
  "expires_at": 1738886400,
  "user": {
    "email": "dev@example.com",
    "oidc_subject": "110123456789012345678",
    "user_id": "user_def456",
    "role": "developer",
    "avatar_url": "https://lh3.googleusercontent.com/..."
  }
}
FieldTypeDescription
session_tokenstringUser session token (24-hour TTL)
expires_atintegerSession expiry as Unix epoch (seconds)
userobjectAuthenticated user details

Error responses

StatusCodeDescription
400invalid_stateUnknown or expired OIDC state parameter
400auth_expiredOIDC authorization request expired (10-minute TTL)
403user_not_foundNo user account for this email/identity
409setup_incompleteSetup is not yet complete
500decryption_errorFailed to decrypt stored OIDC client secret
500session_errorFailed to create session
500store_errorDatabase operation failed
502oidc_discovery_errorFailed to perform OIDC discovery
502token_exchange_errorFailed to exchange authorization code
502missing_id_tokenIdP did not return an ID token
502id_token_verification_errorID token verification failed
502missing_emailID token missing email claim

INFO

Users must be invited before they can sign in. If a user authenticates successfully with the OIDC provider but has no account in Oore CI, the callback returns 403 with code user_not_found.


Local Login

Create a loopback-only local session without OIDC.

POST /v1/auth/local/login

Authentication: None (public)

Request body

json
{
  "email": "owner@example.com"
}

email is optional when exactly one active user exists.

Response 200 OK

Returns LocalLoginResponse.

Error responses

StatusCodeDescription
400email_requiredMultiple active users exist and email was omitted
403mode_restrictedSetup is incomplete while runtime mode is remote
403local_login_loopback_requiredLocal login attempted from non-loopback source
403user_not_foundNo active user matched the provided email

WARNING

Local login is always loopback-only. Any non-loopback access path must use External Access (runtime_mode=remote) with either OIDC or Trusted Proxy.


Trusted Proxy Login

Create a user session from identity headers asserted by a trusted upstream proxy such as Warpgate.

POST /v1/auth/trusted-proxy/login

Authentication: None (public)

Request body

No request body.

Required proxy headers

By default, Oore expects the user email in:

text
X-Warpgate-Username

The exact identity header name can be changed in trusted-proxy configuration. If a shared secret is configured, the proxy must also send:

text
X-Oore-Trusted-Proxy-Secret

Response 200 OK

Returns LocalLoginResponse.

Error responses

StatusCodeDescription
403mode_restrictedInstance is not in runtime_mode=remote with remote_auth_mode=trusted_proxy
403trusted_proxy_peer_not_allowedRequest did not come from a trusted proxy peer
401trusted_proxy_shared_secret_missingTrusted proxy shared secret header is required but missing
401trusted_proxy_shared_secret_invalidTrusted proxy shared secret header does not match
401trusted_proxy_identity_missingTrusted proxy identity header is missing
401trusted_proxy_identity_invalidTrusted proxy identity header is not a valid email
403user_not_foundNo active user matched the forwarded email

INFO

Trusted Proxy mode keeps authentication at the upstream proxy boundary while preserving normal Oore sessions, RBAC, and audit attribution.


Logout

Invalidate the current user session.

POST /v1/auth/logout

Authentication: User session (Bearer)

Response 200 OK

json
{
  "ok": true
}

Error responses

StatusCodeDescription
401missing_authAuthorization header not provided
401invalid_sessionSession token is invalid or already expired

Self-hosted mobile CI, built for Flutter.