docs: document full and embedded rendering with server authentication

This commit is contained in:
Codex
2026-09-13 17:28:10 +02:00
parent 26c5605ff7
commit 9051463654
24 changed files with 789 additions and 25 deletions
+11 -1
View File
@@ -1,6 +1,11 @@
# Local authentication
Use local mode for a standalone PC or Mac. Configure it through `tht`; passwords are entered at an
Use local mode for a standalone PC or Mac, with `shell.mode: full` and
`shell.defaultLocale: en` in the installation descriptor. Presentation and
authentication are independent: selecting full does not create accounts. Omics
embedded instead uses the [upstream guide](authentication-upstream.md), not local users.
Configure local authentication through `tht`; passwords are entered at an
echo-free prompt or read from a protected `--password-file`, never from a command argument.
## Bootstrap
@@ -56,6 +61,11 @@ machine use; JSON output is pristine on stdout.
## Session behavior and recovery
Full shows its own login form and, after login, the verified display name in its
header. The name menu contains Log out. This sends a CSRF-protected request to
`/api/auth/logout`, revokes the session and returns to login. Language/theme
preferences may remain in the browser; they are not credentials.
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
+23
View File
@@ -1,10 +1,20 @@
# 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](authentication-upstream.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
@@ -18,6 +28,9 @@ The OIDC client secret is supplied through the protected secret bundle under the
`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):
@@ -92,3 +105,13 @@ relevant diagnostic surface.
The complete closed diagnostic-code union and exact role-to-permission expansion are in the
[authentication architecture](../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](../testing/authentication-manual-acceptance.md).
+186
View File
@@ -0,0 +1,186 @@
# Autenticazione tramite portale e proxy fidato
Questa è la modalità **upstream** usata dall'integrazione Omics. Non è il login
OIDC diretto di ThothII: l'utente accede a Omics come già fa, poi sceglie
Datamart Builder e trova ThothII già autenticato. Non deve essere creato un utente
locale ThothII né effettuato un secondo scambio OIDC dall'applicazione embedded.
## Il confine di fiducia
```mermaid
sequenceDiagram
actor U as Utente già autenticato
participant N as Nginx Omics
participant D as Django Omics
participant T as Core ThothII upstream
U->>D: Apri Datamart Builder
D-->>U: Pagina autorizzata con mount React
U->>N: GET /datamart-builder/api/me (cookie Omics)
N->>D: Subrequest interna /datamart-builder/api-auth
D-->>N: 200 + identità verificata, oppure 403
N->>T: GET /me + intestazioni normalizzate (solo se autorizzato)
T-->>U: Identità e permessi applicativi, oppure rifiuto
```
L'header e l'adapter JavaScript non autenticano nessuno. Il backend accetta una
richiesta upstream solo con un'identità valida ricevuta da un percorso di rete
fidato. Gli header non sono firmati da ThothII: la protezione è il proxy che
verifica la sessione e sovrascrive l'identità, insieme all'isolamento del core.
Un core upstream direttamente raggiungibile da client non fidati è una falla,
non una modalità alternativa di accesso.
## Configurazione del core
Per Omics il descrittore pubblico deve contenere:
```yaml
shell:
mode: embedded
defaultLocale: en
adapter: omics-portal
```
Separatamente, il **processo core** deve ricevere `AUTH_MODE=upstream`. Definirlo
nell'override Compose approvato e incluso nell'installazione; una variabile nel
file di interpolazione `.env` non viene passata automaticamente al container:
```yaml
services:
core:
environment:
AUTH_MODE: upstream
```
È solo il frammento di selezione auth, non un file Compose completo né una
configurazione di rete sufficiente. Non aggiunge porte pubbliche.
Condizioni obbligatorie:
1. Nessun `auth.yaml` local/OIDC deve essere effettivamente montato al percorso
letto dal core (default `/run/thothii-auth/auth.yaml`). Se è presente insieme
ad `AUTH_MODE`, l'avvio fallisce. Non impostare `AUTH_MODE=local` o `oidc`:
questi due modi si selezionano dal file, non da quella variabile.
2. Non configurare `authentication.runtimeProjection` per questo percorso: è la
proiezione delle configurazioni cookie local/OIDC, non l'identità Omics.
Nemmeno `THT_AUTH_RUNTIME_PROJECTION_ROOT` deve attivarla nel core.
3. Il descrittore e Compose base continuano a richiedere `authentication.configDirectory`
e `THT_AUTH_CONFIG_ROOT` coerenti. Per una nuova installazione upstream usare
una directory dedicata senza `auth.yaml`, non cancellare la configurazione di
un'installazione esistente. I cambi di modalità richiedono un piano separato.
4. Non esiste `tht auth configure --mode upstream`: il CLI configura gli utenti
locali o l'OIDC diretto. Conservare il percorso proxy già operativo per Omics.
5. `profile: server`, storage delle sessioni e `THOTH_PUBLIC_EXPOSURE` hanno propri
vincoli, che rimangono attivi. La shell embedded non li soddisfa automaticamente.
Il sorgente considera upstream un percorso di compatibilità con il proxy; è
quello usato dall'integrazione Omics corrente. `none` e `mock` sono per sviluppo/test,
non soluzioni a errori di configurazione in produzione.
## Intestazioni richieste all'ingresso del core
| Header | Regola ThothII | Valore Omics |
| --- | --- | --- |
| `X-Thoth-Principal-Issuer` | Stringa stabile, obbligatoria | `portal` |
| `X-Thoth-Principal-Subject` | ID stabile dell'utente, obbligatorio | `str(user.pk)` Django |
| `X-Thoth-Principal-Display-Name` | Facoltativo, se presente non vuoto | Nome completo o username |
| `X-Thoth-Is-Admin` | Obbligatorio: `0`, `1`, `false` o `true` | Risultato di `is_authentik_admin(user)` |
Le stringhe sono ripulite degli spazi esterni, devono avere al massimo 512
caratteri e non contenere caratteri di controllo. Header mancanti o invalidi
producono 401. `false`/`0` assegna il ruolo `user`; `true`/`1` assegna `user` e
`admin`. Il core espande i permessi dal proprio catalogo, non da un array inviato
dal browser. `/me` richiede `session.use`.
La coppia `(issuer, subject)` identifica il proprietario delle sessioni.
Non sostituire il subject con un nome visualizzato o un'email modificabile; non
cambiare issuer/subject di utenti esistenti per correggere un problema grafico.
Passare da identità `portal` a identità OIDC diretta non migra la proprietà dei dati.
## Omics: percorsi e componenti esatti
| Percorso | Destinazione e funzione |
| --- | --- |
| `/kokoro/datamart-builder/` | Pagina Django con `datamart_builder.access` |
| `/datamart-builder/config.js` | Config pubblico del frontend, senza cache |
| `/datamart-builder/assets/…` | Asset frontend risolti dal manifest Vite |
| `/datamart-builder/api/…` | Nginx con `auth_request`, poi core senza il prefisso |
| `/_thothii_auth` | Location Nginx interna, non un login pubblico |
| `/datamart-builder/api-auth` | Django verifica sessione Omics e capability |
Nel repository Omics:
- `kokoro/datamart_catalog_views.py`: `DatamartBuilderView` e
`datamart_builder_api_auth`; la verifica API risponde 200 o 403, anche 403
quando la sessione è assente/scaduta. Non trasforma l'API in una pagina di login.
- `nginx/nginx.conf`: API direttamente a `thothii-core:8787`, config e asset a
`thothii-frontend:8080`; verificare alias e reti Docker effettivi sul server.
- `templates/kokoro/datamart_builder.html`: mount, config e override del prefisso.
- `kokoro/templatetags/vite.py`: manifest da
`http://thothii-frontend:8080/.vite/manifest.json`, cache Django di 30 secondi.
Nginx usa il cookie Omics nella subrequest a Django. Sulle richieste al core
sovrascrive i quattro header con i risultati della verifica e rimuove
`Cookie`, `Authorization` e `X-Authenticated-User`. Nessuna password o token del
portale deve essere copiato nel config pubblico, nello snapshot adapter o in Web Storage.
`GET /datamart-builder/api/me` restituisce l'identità e i permessi; in upstream
`session` e `csrfToken` sono `null`: non viene creata una sessione-cookie ThothII.
## Non confondere i due percorsi proxy
L'esempio generico `deploy/nginx-authenticated-proxy.conf.example` usa **due hop**:
proxy host → frontend Nginx ThothII → core. Sul tratto privato verso il frontend
trasporta `X-Thoth-Trusted-Principal-*` e `X-Thoth-Trusted-Is-Admin`; il frontend
li converte nei quattro header del core e li elimina prima dell'inoltro.
Omics usa invece **Nginx Omics → core direttamente** per le API e invia gli header
normalizzati senza `Trusted`. Non incollare l'esempio a due hop in questa location:
la famiglia di header sbagliata produce 401. In entrambi i casi i valori devono
venire dalla verifica server, mai dagli header del client. Il tratto privato del
percorso generico deve essere inaccessibile ai client non fidati.
## Origine delle richieste e stream
Browser e API devono restare sullo stesso origin. Il frontend accetta `/api` o un
prefisso same-origin come `/datamart-builder/api`, non un URL `http://core:8787`.
In upstream le scritture con `Origin` sono confrontate con protocollo e Host
percepiti dal core; non usano il token CSRF della sessione ThothII local/OIDC.
Le richieste senza Origin hanno il trattamento non-browser: l'autenticazione del
proxy rimane indispensabile anche per esse.
Nel Nginx Omics esaminato il TLS termina a monte e una mappa **esatta** converte
`https://aritmolab.policlinicosandonato.it` in
`http://aritmolab.policlinicosandonato.it` per il confronto interno. Le altre origini
rimangono invariate e devono essere negate quando non coincidono. È una scelta
specifica della topologia corrente, non un modello da estendere con wildcard,
cancellazione di Origin o riscrittura incondizionata. Verificare Host/protocollo
al core e i dinieghi cross-origin nella topologia realmente rilasciata.
La location API disabilita buffering/cache per SSE e mantiene timeout lunghi.
`auth_request` verifica ogni nuova richiesta, ma non interrompe istantaneamente
uno stream già aperto quando il portale revoca l'utente. ThothII ricontrolla `/me`
al ritorno alla pagina e alla riconnessione degli eventi; non promettere revoca
istantanea fra tutte le schede.
## Logout, rientro e diagnosi
In embedded logout e successivo login sono di Omics. ThothII non chiama
`/auth/logout`, non cancella il cookie Django e non apre un suo login.
Il rifiuto 401/403 di `/me` rimuove lo stato protetto e richiede il rientro dal
portale. Un 403 su una singola operazione non equivale al logout dell'applicazione.
| Sintomo | Controllo mirato |
| --- | --- |
| Secondo header | Config servito: deve essere embedded, non full |
| Nessuna UI e errore preferenze | Selettore Omics `data-lang` e `html data-bs-theme` |
| `/me` 401 dal core | Header obbligatori, famiglia Trusted/normalizzata, percorso proxy |
| `/me` 403 dal proxy | Sessione Omics e capability `datamart_builder.access` |
| `/me` funziona ma POST 403 | Distinguere permesso operativo da mismatch Origin/Host/protocollo |
| 502 o asset assenti | Alias/rete Docker e manifest Vite; attesa cache manifest 30 s |
| Avvio core rifiutato | Coesistenza di `auth.yaml` o runtime projection con `AUTH_MODE` |
| Logout full seguito da rientro IdP immediato | Il logout ThothII non è logout globale OIDC |
Non raccogliere cookie, token, segreti o dump completi delle configurazioni nei
report. Registrare codici HTTP, nomi dei percorsi, revisioni e risultati dei test.
Consegna e rilascio: [procedura Omics](../operations/shell-and-localization.md#verifica-prima-del-deploy-server).
Collaudo obbligatorio: [matrice di accettazione](../testing/authentication-manual-acceptance.md).
+9 -2
View File
@@ -1,7 +1,14 @@
# Authentik provider configuration
ThothII uses generic OIDC in the browser. Authentik provides the identity provider and group
catalog without adding a proprietary login flow.
For **full with direct OIDC**, ThothII uses generic OIDC in the browser. Authentik
provides the identity provider and group catalog without adding a proprietary flow.
The provider/client/group setup below applies to that case only.
For **embedded in Omics**, retain Omics's existing Authentik authentication and
configure ThothII as upstream. Omics verifies `datamart_builder.access` and
administrator status and the proxy supplies the identity; no additional ThothII
OIDC client, login or local user is required for that path. Follow the
[portal integration guide](authentication-upstream.md).
```mermaid
sequenceDiagram
@@ -3,6 +3,9 @@
# Replace every absolute placeholder. Select exactly one Git transport override.
schemaVersion: 2
profile: local
shell:
mode: full
defaultLocale: en
projectDirectory: "/absolute/path/to/ThothII"
envFile: "/absolute/path/to/ThothII/deploy/env/local.env"
workspaceRepository:
@@ -3,6 +3,11 @@
# Replace every absolute placeholder. Select exactly one Git transport override.
schemaVersion: 2
profile: server
# Standalone server with protected direct OIDC auth, not the Omics upstream path.
# For Omics use authentication-upstream.md: embedded, no auth runtime projection.
shell:
mode: full
defaultLocale: en
projectDirectory: "/absolute/path/to/ThothII"
envFile: "/absolute/path/to/thothii-server-operator/server.env"
workspaceRepository:
+13 -1
View File
@@ -24,7 +24,7 @@ version control, a URL, or a command line.
From the repository root, start the interactive setup and select the local profile:
```sh
tht setup --profile local
tht setup --profile local --shell-mode full --shell-default-locale en
```
It writes the selected non-secret descriptor below `deploy/<installation-id>/`, the associated
@@ -32,6 +32,18 @@ operator env file, and can create protected secret templates. Keep the descripto
to commands as `--installation /absolute/path/thothii-installation.yaml` when more than one
installation can be discovered.
The explicit shell options are important: compatibility defaults without them
are embedded/en/omics-portal, which expects an Omics document. The Mac's standalone
installation must use full, with English as its initial locale. Existing browser
language preferences take precedence over that initial value. Full does not
configure authentication; setup separately bootstraps local login.
For a server portal, use the [embedded/upstream procedure](authentication-upstream.md)
instead of creating a second ThothII login. For a standalone server, use full
with [direct OIDC](authentication-oidc.md). Shell mode does not follow `profile`
automatically. See [configuration and regeneration](../operations/shell-and-localization.md)
before modifying an existing installation.
If the descriptor is prepared manually instead, begin with
[`thothii-installation.local.yaml`](examples/thothii-installation.local.yaml), set mode `0600` or
`0400`, and ensure `THT_INSTALLATION_CONFIG_SOURCE` in the selected env file points to that exact