docs(auth): document local OIDC and Authentik operation

This commit is contained in:
2026-08-18 03:07:33 +02:00
parent 6ec5b76c54
commit f4f38717e1
17 changed files with 407 additions and 0 deletions
+70
View File
@@ -0,0 +1,70 @@
# Local authentication
Use local mode for a standalone PC or Mac. Configure it through `tht`; passwords are entered at an
echo-free prompt or read from a protected `--password-file`, never from a command argument.
## Bootstrap
After the installation descriptor and protected secret bundle exist, configure the first enabled
administrator:
```sh
tht --installation /absolute/path/thothii-installation.yaml auth configure \
--mode local --public-url http://127.0.0.1:8080 \
--admin-user <operator-user> --admin-display-name <display-name> \
--password-file /absolute/path/protected-password-file
```
The password file is temporary operator input: keep it private and remove it after configuration.
The resulting `users.yaml` contains Argon2id hashes, never plaintext passwords. To use prompts,
omit the admin and password options in an interactive terminal. `tht setup` performs the same
bootstrap before it starts the stack.
The non-secret local `auth.yaml` has this exact shape:
~~~yaml
version: 1
mode: local
publicUrl: http://127.0.0.1:8080
session:
regularTtlSeconds: 43200
regularIdleSeconds: 7200
rememberTtlSeconds: 2592000
rememberIdleSeconds: 604800
oidcTtlSeconds: 28800
local:
usersFile: users.yaml
~~~
## User administration
```sh
tht auth user list [--json]
tht auth user add <username> --role user|admin [--display-name <name>] [--password-file <file>]
tht auth user set-password <username> [--password-file <file>]
tht auth user enable <username>
tht auth user disable <username>
tht auth user grant <username> --role user|admin
tht auth user revoke <username> --role user|admin
tht auth user logout-all <username> --yes
```
User commands are unavailable in OIDC mode. The last enabled administrator cannot be disabled or
demoted. Every password, role, enabled-state, and `logout-all` change increments the user’s
`authRevision`, invalidating its sessions. `tht auth status --json` is redacted and suitable for
machine use; JSON output is pristine on stdout.
## Session behavior and recovery
An ordinary login expires after 2 hours idle or 12 hours absolute. Selecting **Remember me** makes
the cookie persistent and changes the limits to 7 days idle or 30 days absolute. Remembered
sessions survive a browser and backend restart, but not a user revision change, configuration
revision change, logout, or restore. Restore does not include sessions or OIDC state and requires
every user to authenticate again.
If access is lost, use `tht auth user set-password`, `enable`, role changes, or `logout-all` as
appropriate, then log in again. Do not copy passwords, hashes, cookies, CSRF values, or secret
values into tickets, logs, or evidence.
Check readiness with `tht auth check`; add `--json` for the machine contract. Use
`tht doctor --json` for the aggregate installation report.
+83
View File
@@ -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`.
+34
View File
@@ -0,0 +1,34 @@
# Authentik provider setup
Authentik is the first certified provider for PSD acceptance. The ThothII browser protocol remains
generic OIDC; these steps configure the provider-specific group catalog only.
1. Create an OAuth2/OIDC application and provider in Authentik. Register exactly
`<publicUrl>/api/auth/oidc/callback` as the callback and enable `openid`, `profile`, and `email`.
2. Configure the provider so the ID token contains a direct `groups` array of strings. Verify the
claim with a disposable test identity before running acceptance.
3. Create a dedicated API service account for the group catalog. Grant group-view-only privilege;
do not grant write, user-management, or directory-administration privilege. Put its bearer value
in the protected bundle under `THT_AUTHENTIK_API_TOKEN`.
4. Create or confirm the exact groups `TOT Users` and `TOT Admin`. Map them explicitly in
`auth.yaml` to `user` and `admin`, respectively. Keep other upstream groups out of the mapping.
5. Run the static check and then the live interactive check:
```sh
tht auth check
tht auth check --interactive
tht doctor --json
```
6. Run workspace Validate and then workspace Test. Test must prove discovery/JWKS, catalog access,
and every configured group. The diagnostic result must contain no secret values.
Only configured exact group names are queried. Additional Authentik or directory groups are ignored
silently, without a warning. A mapped group absent from Authentik fails closed with
`oidc_mapped_group_missing`; an ambiguous exact-name result uses
`oidc_mapped_group_ambiguous`. A group visible only in an upstream directory but not represented
in Authentik is missing from ThothII’s catalog and must not be treated as present.
Rotate the two credentials independently through the protected secret-file procedure, then repeat
`tht auth check` and workspace Test. Never put either value in this guide, YAML, shell history,
diagnostic output, or acceptance evidence.
+11
View File
@@ -169,6 +169,17 @@ services; retain TLS and authentication even when co-located.
## Build ThothII and thothctl
The canonical local Compose smoke uses the base file plus the local profile. Keep this exact
base+profile command available for install verification:
~~~sh
docker compose --env-file deploy/env/local.env + -f compose.yaml -f deploy/compose.local.yaml up --build -d
~~~
After the stack is ready, configure and check authentication with the single host CLI tht; see
the [local authentication guide](authentication-local.md). Authentication configuration is
installation-global and is checked before workspace tests.
From the repository root, macOS/Linux/WSL2 users run:
```sh
+7
View File
@@ -1,5 +1,12 @@
# Policlinico San Donato — setup workspace (nuova gestione)
Authentication acceptance is documented in the [manual authentication matrix](../testing/authentication-manual-acceptance.md).
Use generic OIDC with Authentik as the certified group catalog, map only the exact TOT Users and
TOT Admin groups, then run tht auth check, tht auth check --interactive, workspace Validate,
and workspace Test in that order. Browser callback E2E, native Windows execution, approved PSD
manual identities, external L2, and the two parked restore-lock preconditions remain pending the
Task 15/release gates.
Guida operativa per collegare ThothII al DWH di PSD con il nuovo sistema (registry Git + descriptor
v3 + `thothctl`).
+4
View File
@@ -4,6 +4,10 @@ This example assumes Caddy runs on the Linux host, ThothII `frontend` listens on
`127.0.0.1:8080`, public DNS points to the host, and a separate authentication gateway validates
the user's real login/session. Replace the domain and auth-gateway address.
For ThothII-managed generic OIDC, preserve the configured public origin and the exact callback
`/api/auth/oidc/callback`; the browser and API remain one same-origin surface. Run
`tht auth check` and workspace Test after proxy changes.
## Trust boundary
Caddy is the only public listener. It provides automatic HTTPS, performs `forward_auth`, and
+4
View File
@@ -4,6 +4,10 @@ This example assumes Nginx runs on the Linux host, ThothII `frontend` listens on
`127.0.0.1:8080`, and a separate authentication gateway validates the user's real login/session.
Replace the documentation domain, certificate paths, and auth-gateway address.
For ThothII-managed generic OIDC, preserve the configured public origin and the exact callback
`/api/auth/oidc/callback`; the browser and API remain one same-origin surface. Run
`tht auth check` and workspace Test after proxy changes.
## Trust boundary
Nginx is the only public listener. It terminates TLS, performs an `auth_request`, and proxies only
+5
View File
@@ -1,5 +1,10 @@
# Install ThothII on a Linux server
Server authentication uses generic OIDC with the reverse proxy preserving the configured public
origin and callback path. Follow the [OIDC guide](authentication-oidc.md), [Authentik guide](authentik.md)
when applicable, and the [authentication acceptance matrix](../testing/authentication-manual-acceptance.md).
The host authentication CLI is tht; use tht auth check before workspace Validate/Test.
This guide is for an installer with basic Linux administration and very basic Docker knowledge.
It deploys the same Compose distribution used on a local PC: the mandatory application is exactly
`frontend` plus `core`, and pinned Pi is inside `core`. The server does not need host Pi, Node.js,