Files
ThothII/docs/install/authentication-oidc.md
T

5.3 KiB

Generic OIDC authentication

Use this guide for ThothII's own login, normally shell.mode: full on an autonomous server. It is not the integration procedure for an already logged-in Omics user. That deployment uses embedded/upstream, even when Omics's identity provider is Authentik.

OIDC mode supports a standards-based provider. The browser flow is generic: Authorization Code, PKCE S256, state, nonce, issuer/signature/audience/expiry validation, and the fixed callback <publicUrl>/api/auth/oidc/callback. The browser and API must use the same origin; configure the reverse proxy to preserve that public origin and callback path.

publicUrl is the public origin, without an application subpath. The current full OIDC browser entry and callback use /api/auth/oidc/login and /api/auth/oidc/callback; arbitrary prefixed OIDC hosting is not implemented by selecting a different backendBaseUrl.

Configure the installation with tht:

tht auth configure --mode oidc --public-url <https-public-origin> \
  --issuer <https-issuer> --client-id <client-id> \
  --authentik-base-url <https-provider-origin> \
  --user-group 'TOT Users' --admin-group 'TOT Admin'

The OIDC client secret is supplied through the protected secret bundle under the exact key THT_OIDC_CLIENT_SECRET; it is never written into auth.yaml. The default scopes are exactly openid, profile, and email.

Keep AUTH_MODE unset when using this file. A simultaneously mounted local/OIDC configuration and AUTH_MODE=upstream is an error, not a fallback chain.

The non-secret OIDC configuration has this exact shape (replace angle-bracket placeholders with operator values):

version: 1
mode: oidc
publicUrl: <https-public-origin>
session:
  regularTtlSeconds: 43200
  regularIdleSeconds: 7200
  rememberTtlSeconds: 2592000
  rememberIdleSeconds: 604800
  oidcTtlSeconds: 28800
oidc:
  issuer: <https-issuer>
  clientId: <client-id>
  clientSecretRef: THT_OIDC_CLIENT_SECRET
  scopes: [openid, profile, email]
  groupsClaim: groups
groupCatalog:
  driver: authentik
  baseUrl: <https-provider-origin>
  apiTokenRef: THT_AUTHENTIK_API_TOKEN
authorization:
  groupRoles:
    TOT Users: [user]
    TOT Admin: [admin]

The groups claim is mandatory

The ID token must contain a direct, non-empty groups array of strings. ThothII does not follow distributed claims, overage links, or indirect provider expansion. Missing or malformed claims fail closed. A browser callback exposes only HTTP 401 oidc_callback_failed; it never reveals whether the claim was missing, malformed, indirect, or overage-style. The redacted diagnostic and interactive device-flow contract uses oidc_groups_claim_invalid for invalid group-claim or device-flow identity results.

Configured group names are exact and case-sensitive. The union of matched mappings determines the Thoth roles. A token with no mapped group is authenticated but has no role and cannot use protected routes. Additional provider groups are ignored silently, without an error or warning. Group existence is separately proven by the configured catalog adapter; this is why a generic OIDC provider may authenticate while still failing installation readiness.

Checks and diagnostics

The surfaces have distinct semantics and this order is recommended:

  1. Workspace Validate performs static authentication validation without contacting the provider.
  2. tht auth check performs live, non-interactive authentication diagnosis, including discovery, issuer/JWKS, catalog credentials, and all configured mapped groups.
  3. tht auth check --interactive repeats live diagnosis and additionally validates a device-flow identity and its direct groups claim when Device Authorization is available.
  4. Installation diagnostics perform aggregate live workspace and authentication validation.

The live CLI forms are:

tht auth check
tht auth check --json

For a provider that advertises Device Authorization, tht auth check --interactive presents a verification URI and one-time user code on the terminal, waits for completion, and validates a real ID token including groups. It is an operator check, not a replacement for browser login.

tht doctor emits this exact ordered report: descriptor, files, docker, compose, configuration, authentication, services, core-http, frontend-http, workspace-registry, workflow, pi. Its authentication entry is live and non-interactive. Any authentication failure prevents activation according to the static or live scope of the relevant diagnostic surface.

The complete closed diagnostic-code union and exact role-to-permission expansion are in the authentication architecture.

Browser login and logout

ThothII redirects the browser to the provider and creates its own opaque session after validating the callback. An existing provider SSO session may avoid another password prompt, but this remains a distinct ThothII login/session, unlike Omics upstream. Full's name menu logs out of ThothII only. It does not revoke the provider session or log out other applications, so a subsequent login can return immediately through SSO. No provider token is placed in the UI adapter or browser storage. See the manual acceptance matrix.