118 lines
5.4 KiB
Markdown
118 lines
5.4 KiB
Markdown
# 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](shell-and-language.md),
|
|
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`:
|
|
|
|
```sh
|
|
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):
|
|
|
|
~~~yaml
|
|
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:
|
|
|
|
```sh
|
|
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](https://git.tylconsulting.it/mptyl/ThothII/src/branch/main/docs/architecture/authentication.md).
|
|
|
|
## 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](https://git.tylconsulting.it/mptyl/ThothII/src/branch/main/docs/testing/authentication-manual-acceptance.md).
|