docs(auth): document local OIDC and Authentik operation
This commit is contained in:
@@ -0,0 +1,55 @@
|
||||
# Authentication architecture
|
||||
|
||||
ThothII has two production authentication modes: `local` and generic `oidc`. The host operator
|
||||
surface is one CLI, `tht`; there is no separate authentication executable. The backend owns
|
||||
opaque browser sessions and authorization, while `tht` owns protected configuration and local-user
|
||||
files.
|
||||
|
||||
## Configuration and trust boundaries
|
||||
|
||||
The installation descriptor points to an operator-controlled authentication directory. It contains
|
||||
non-secret `auth.yaml` and, for local mode, `users.yaml`. POSIX installations use a private
|
||||
directory and owner-only regular files; Windows uses equivalent owner-only ACLs. Secret values are
|
||||
read from the mounted secret bundle and are never placed in YAML, command arguments, logs, JSON
|
||||
diagnostics, or browser storage.
|
||||
|
||||
Local users have Argon2id password hashes, stable IDs, enabled state, roles, and `authRevision`.
|
||||
The stable roles are `user` and `admin`; `admin` inherits `user` and adds installation, session,
|
||||
Pi, workspace, secret-management, and diagnostic permissions.
|
||||
|
||||
OIDC is provider-neutral at the browser protocol boundary. Authorization Code + PKCE, issuer,
|
||||
signature, audience, expiry, state, and nonce are validated before a principal is created.
|
||||
Authentik is the first certified group-catalog adapter, not a special browser login mode.
|
||||
|
||||
## Group authorization
|
||||
|
||||
OIDC must return a direct, non-empty `groups` claim whose value is a JSON array of strings.
|
||||
Missing, malformed, indirect, or overage-style claims fail closed with
|
||||
`oidc_groups_claim_invalid`. Exact configured external group names map to Thoth roles and then to
|
||||
permissions. A user with no mapped group is authenticated but receives no role and gets `403` from
|
||||
protected routes. Unmapped upstream groups are ignored silently, without an error or warning.
|
||||
|
||||
Every configured mapping is checked by the configured group-catalog adapter. Authentik checks the
|
||||
exact group name and reports `oidc_mapped_group_missing` when it cannot find it. The dedicated
|
||||
Authentik API service account has group-view-only privilege; it is separate from the OIDC client.
|
||||
|
||||
## Browser sessions
|
||||
|
||||
The browser receives only an opaque `HttpOnly`, `SameSite=Lax` cookie named `thothii_session`.
|
||||
State-changing cookie requests require the in-memory CSRF token, same-origin `Origin`, and Fetch
|
||||
Metadata checks when present. The frontend never stores bearer tokens or session secrets in Web
|
||||
Storage.
|
||||
|
||||
- Ordinary local sessions: 2-hour idle and 12-hour absolute expiry; closing the browser removes
|
||||
the non-persistent cookie.
|
||||
- **Remember me** local sessions: 7-day idle and 30-day absolute expiry; they survive browser and
|
||||
ThothII restarts.
|
||||
- OIDC sessions: at most 8 hours and never beyond the validated ID-token expiry.
|
||||
|
||||
Local password, role, enabled-state, and logout-all changes increment `authRevision` and invalidate
|
||||
affected sessions. Authentication configuration revision changes invalidate all sessions after
|
||||
reload. Logout deletes the server record. Backup restore excludes active sessions and OIDC state,
|
||||
recreates empty private auth-state directories, and therefore forces reauthentication.
|
||||
|
||||
See the [local guide](../install/authentication-local.md), [generic OIDC guide](../install/authentication-oidc.md),
|
||||
and [Authentik guide](../install/authentik.md) for operator procedures.
|
||||
@@ -4,6 +4,9 @@
|
||||
|
||||
ThothII è un **datamart builder human-in-the-loop**: trasforma una domanda in linguaggio naturale in SQL validato (ed eventualmente un datamart dbt) attraverso un **workflow deterministico a 8 fasi NL→SQL**, in cui il modello *propone* e un revisore umano *decide* ai gate.
|
||||
|
||||
L'autenticazione di produzione usa local oppure OIDC generico; il solo CLI operatore è tht.
|
||||
Per sessioni, ruoli, gruppi, diagnostica e ripristino vedere la [documentazione autenticazione](authentication.md).
|
||||
|
||||
## I tre progetti indipendenti
|
||||
|
||||
```
|
||||
|
||||
@@ -1,5 +1,8 @@
|
||||
# ThothII — Guida utente
|
||||
|
||||
Per login, **Remember me**, ruoli, invalidazione delle sessioni, gruppi OIDC e ripristino, vedere
|
||||
la [guida autenticazione locale](install/authentication-local.md) e la [guida OIDC generica](install/authentication-oidc.md).
|
||||
|
||||
Questa guida accompagna passo-passo chi deve **preparare** il repository dei workspace, **usare
|
||||
gli strumenti** ThothII per quel repository e **usare l'applicazione** per fare domande in
|
||||
linguaggio naturale e ottenere SQL validato. Usa parole semplici ed esempi; i dettagli tecnici
|
||||
|
||||
@@ -8,6 +8,8 @@ La documentazione è divisa in due aree:
|
||||
|
||||
Come funziona il sistema: architettura, specifiche di design delle singole funzionalità, piani di implementazione, report di test. Parte da qui: [Panoramica dell'architettura](architecture/overview.md).
|
||||
|
||||
Per autenticazione locale, OIDC generico, Authentik e accettazione PSD: [documentazione autenticazione](architecture/authentication.md).
|
||||
|
||||
Per installare l'applicazione in Docker nei quattro contesti operativi, usando il file env,
|
||||
`compose.yaml`, l'overlay locale/server e il bundle di secret montato:
|
||||
[Installazione Docker nei quattro contesti](installazione-docker-4-contesti.md).
|
||||
|
||||
@@ -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.
|
||||
@@ -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`.
|
||||
@@ -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.
|
||||
@@ -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
|
||||
|
||||
@@ -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,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,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
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -0,0 +1,46 @@
|
||||
# Authentication manual acceptance
|
||||
|
||||
This is a release-gate checklist, not evidence. Use one ordinary PSD test identity and one admin
|
||||
PSD test identity supplied through the approved test-identity process. Record only sanitized
|
||||
pass/fail results, timestamps, build identity, and diagnostic codes. Do not record names, internal
|
||||
URLs, directory/LDAP details, tokens, passwords, hashes, cookies, or realistic secret examples.
|
||||
|
||||
## Preconditions and ordering
|
||||
|
||||
1. Resolve the two parked Task 13 restore preconditions before certification: acquire the lifecycle
|
||||
lock before any target-dependent preflight and stage/revalidate archive bytes and hashes inside
|
||||
that lock immediately before extraction; replace convention-only
|
||||
`createWithDependenciesLockHeld` with an opaque installation-bound transaction capability or
|
||||
closure so lock-held primitives cannot be called without the capability.
|
||||
2. Run `tht auth check`, then `tht auth check --interactive` where Device Authorization is
|
||||
available, then workspace Validate and workspace Test. Run `tht doctor --json` and confirm its
|
||||
`authentication` check precedes service and workspace checks.
|
||||
3. Confirm the exact direct `groups` claim for both identities and the mappings `TOT Users → user`
|
||||
and `TOT Admin → admin`. Confirm extra upstream groups are ignored without warning.
|
||||
|
||||
## Matrix
|
||||
|
||||
| Scenario | Expected result |
|
||||
|---|---|
|
||||
| Ordinary identity opens its own application/session routes | Allowed; admin-only routes return `403`. |
|
||||
| Admin identity opens admin routes | Allowed according to the `admin` permission set. |
|
||||
| Token omits `groups` | Authentication fails closed with `oidc_groups_claim_invalid`. |
|
||||
| Token has malformed, indirect, or overage groups | Authentication fails closed with `oidc_groups_claim_invalid`. |
|
||||
| Token has no mapped group | Principal has no role; protected routes return `403`; no warning is emitted. |
|
||||
| A configured group is absent from Authentik | Check fails with `oidc_mapped_group_missing`. |
|
||||
| Catalog token is wrong or lacks group-view-only access | Check fails redacted as catalog unavailable/unauthorized. |
|
||||
| Mapped group is renamed | The next check fails closed until configuration and provider agree. |
|
||||
| Token adds an unrelated group | Login and authorization are unchanged; no warning is emitted. |
|
||||
| Backend restarts with Remember me | Remembered local session survives within its TTL. |
|
||||
| Password/role/enable revision changes | Affected local sessions are rejected and reauthentication is required. |
|
||||
| CSRF or cross-origin mutation is attempted | Request is rejected. |
|
||||
| Logout | Cookie expires and the server session is deleted. |
|
||||
| Provider outage | Live check and OIDC login fail closed; no credential is exposed. |
|
||||
| Restore is completed | Sessions and OIDC state are absent; all users must reauthenticate. |
|
||||
|
||||
## Status at Task 14
|
||||
|
||||
Documentation and deterministic contract checks are the Task 14 scope. Browser OIDC callback E2E,
|
||||
native Windows behavioral execution, the two parked restore-lock preconditions above, PSD/manual
|
||||
identities, and any external L2 execution remain pending Task 15/release gates. Do not mark this
|
||||
matrix PASS until those gates have actual retained evidence.
|
||||
Reference in New Issue
Block a user