docs(auth): document local OIDC and Authentik operation
This commit is contained in:
@@ -0,0 +1,83 @@
|
||||
# Generic OIDC authentication
|
||||
|
||||
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.
|
||||
|
||||
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`.
|
||||
|
||||
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 with `oidc_groups_claim_invalid`.
|
||||
|
||||
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
|
||||
|
||||
Run the static check first:
|
||||
|
||||
```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.
|
||||
|
||||
Static checks cover configuration, secret references, group mappings, file safety, and session
|
||||
storage. Live checks then cover discovery, issuer/JWKS, provider access, and configured groups.
|
||||
`tht doctor` runs the authentication check after configuration and before service/workspace checks.
|
||||
Workspace validation includes static authentication readiness; workspace Test adds live OIDC and
|
||||
group-catalog checks. Any authentication failure makes the workspace non-activatable.
|
||||
|
||||
The redacted diagnostic codes include `oidc_secret_missing`, `oidc_discovery_unreachable`,
|
||||
`oidc_issuer_mismatch`, `oidc_jwks_unreachable`, `oidc_groups_claim_invalid`,
|
||||
`oidc_mapped_group_missing`, and `oidc_mapped_group_ambiguous`.
|
||||
Reference in New Issue
Block a user