docs(auth): address authentication guide review
This commit is contained in:
@@ -1,44 +1,66 @@
|
||||
# Put ThothII behind Nginx
|
||||
|
||||
This example assumes Nginx runs on the Linux host, ThothII `frontend` listens only 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.
|
||||
Choose exactly one authentication mode. Direct ThothII-managed OIDC and deprecated upstream
|
||||
authentication are mutually exclusive proxy contracts; never combine their locations or headers.
|
||||
|
||||
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.
|
||||
## Direct ThothII-managed OIDC
|
||||
|
||||
## Trust boundary
|
||||
Use this mode when `auth.yaml` has `mode: oidc`. Nginx terminates TLS and proxies every request
|
||||
to loopback `frontend`. ThothII owns OIDC login, callback validation, browser sessions, and
|
||||
authorization. No external `auth_request` or authentication gateway belongs in this server.
|
||||
|
||||
Nginx is the only public listener. It terminates TLS, performs an `auth_request`, and proxies only
|
||||
to `frontend`; frontend then uses its private same-origin `/api` route to reach `core`. Never proxy
|
||||
the public listener directly to core port 8787.
|
||||
|
||||
The authentication gateway must return 2xx only after validating a real credential or session. It
|
||||
returns normalized `X-Thoth-Principal-*` and `X-Thoth-Is-Admin` response headers. Nginx clears all
|
||||
client-supplied public and private-hop identity headers and copies only those successful auth
|
||||
response values into `X-Thoth-Trusted-*` on the private hop to frontend.
|
||||
Forwarding identity headers alone does not authenticate a user.
|
||||
|
||||
Do not substitute a static header, network allowlist, or client-provided header for the
|
||||
authentication gateway. The admin value must come from reviewed identity-provider authorization,
|
||||
not from a username supplied by the browser.
|
||||
|
||||
## Example configuration
|
||||
|
||||
Install an Nginx build that includes `ngx_http_auth_request_module`. Save a reviewed version of
|
||||
this server block under the host's Nginx configuration directory:
|
||||
The `location /` block below has a `proxy_pass` without a replacement URI, so public
|
||||
`/api/auth/oidc/login` and `/api/auth/oidc/callback` are forwarded unchanged. The configured
|
||||
`publicUrl` must match the browser origin.
|
||||
|
||||
```nginx
|
||||
server {
|
||||
listen 80;
|
||||
server_name thoth.example.com;
|
||||
server_name thoth.example.invalid;
|
||||
return 301 https://$host$request_uri;
|
||||
}
|
||||
|
||||
server {
|
||||
listen 443 ssl;
|
||||
server_name thoth.example.com;
|
||||
server_name thoth.example.invalid;
|
||||
|
||||
ssl_certificate /etc/nginx/tls/thoth/fullchain.pem;
|
||||
ssl_certificate_key /etc/nginx/tls/thoth/privkey.pem;
|
||||
ssl_protocols TLSv1.2 TLSv1.3;
|
||||
|
||||
location / {
|
||||
# No auth_request and no URI rewrite: ThothII receives OIDC paths unchanged.
|
||||
proxy_set_header Host $host;
|
||||
proxy_set_header X-Forwarded-Proto https;
|
||||
proxy_set_header X-Forwarded-Host $host;
|
||||
proxy_set_header X-Forwarded-For $remote_addr;
|
||||
proxy_set_header Connection "";
|
||||
proxy_pass http://127.0.0.1:8080;
|
||||
proxy_http_version 1.1;
|
||||
proxy_buffering off;
|
||||
proxy_cache off;
|
||||
proxy_read_timeout 3600s;
|
||||
add_header X-Accel-Buffering no always;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
After reload, run Workspace Validate for static validation, `tht auth check` for live,
|
||||
non-interactive authentication diagnosis, and then Workspace Test for aggregate live validation.
|
||||
|
||||
## Deprecated upstream migration mode
|
||||
|
||||
Use this section only while the installation explicitly uses deprecated `upstream` mode. Do not
|
||||
use it with `mode: oidc` or `mode: local`. In this mode an external authentication gateway owns
|
||||
login, and Nginx applies `auth_request` before forwarding normalized private identity headers.
|
||||
|
||||
Forwarding identity headers alone does not authenticate a user. The authentication gateway returns
|
||||
2xx only after validating its own credential or session.
|
||||
|
||||
```nginx
|
||||
server {
|
||||
listen 443 ssl;
|
||||
server_name thoth.example.invalid;
|
||||
|
||||
ssl_certificate /etc/nginx/tls/thoth/fullchain.pem;
|
||||
ssl_certificate_key /etc/nginx/tls/thoth/privkey.pem;
|
||||
@@ -51,8 +73,6 @@ server {
|
||||
proxy_set_header Content-Length "";
|
||||
proxy_set_header X-Original-URI $request_uri;
|
||||
proxy_set_header X-Original-Method $request_method;
|
||||
|
||||
# The auth service derives identity from the real login/session, never these headers.
|
||||
proxy_set_header X-Authenticated-User "";
|
||||
proxy_set_header X-Thoth-Principal-Issuer "";
|
||||
proxy_set_header X-Thoth-Principal-Subject "";
|
||||
@@ -75,7 +95,6 @@ server {
|
||||
auth_request_set $thoth_is_admin
|
||||
$upstream_http_x_thoth_is_admin;
|
||||
|
||||
# Discard browser claims. Carry only successful auth-subrequest values to frontend.
|
||||
proxy_set_header X-Authenticated-User "";
|
||||
proxy_set_header X-Thoth-Principal-Issuer "";
|
||||
proxy_set_header X-Thoth-Principal-Subject "";
|
||||
@@ -85,7 +104,6 @@ server {
|
||||
proxy_set_header X-Thoth-Trusted-Principal-Subject $thoth_principal_subject;
|
||||
proxy_set_header X-Thoth-Trusted-Principal-Display-Name $thoth_principal_display_name;
|
||||
proxy_set_header X-Thoth-Trusted-Is-Admin $thoth_is_admin;
|
||||
|
||||
proxy_set_header Host $host;
|
||||
proxy_set_header X-Forwarded-Proto https;
|
||||
proxy_set_header X-Forwarded-Host $host;
|
||||
@@ -93,8 +111,6 @@ server {
|
||||
proxy_set_header Connection "";
|
||||
proxy_pass http://127.0.0.1:8080;
|
||||
proxy_http_version 1.1;
|
||||
|
||||
# SSE must reach the browser without response buffering or cache delay.
|
||||
proxy_buffering off;
|
||||
proxy_cache off;
|
||||
proxy_read_timeout 3600s;
|
||||
@@ -103,13 +119,15 @@ server {
|
||||
}
|
||||
```
|
||||
|
||||
Keep the certificate private key outside the ThothII tree. Do not log cookies, authorization
|
||||
headers, auth response bodies, or trusted identity headers.
|
||||
## Trust boundary
|
||||
|
||||
Nginx is the only public listener and proxies only to loopback `frontend`, never directly to
|
||||
`core`. Keep private keys outside the ThothII tree. Do not log cookies, authorization headers,
|
||||
OIDC callback query values, authentication bodies, or trusted identity headers.
|
||||
|
||||
## Validate and reload
|
||||
|
||||
First keep the public firewall rule closed. Confirm ThothII responds only on loopback, validate the
|
||||
full Nginx configuration, then reload without stopping existing connections:
|
||||
Keep the public firewall closed while validating:
|
||||
|
||||
```sh
|
||||
curl --fail http://127.0.0.1:8080/health
|
||||
@@ -117,20 +135,9 @@ sudo nginx -t
|
||||
sudo systemctl reload nginx
|
||||
```
|
||||
|
||||
If `nginx -t` reports that `auth_request` is unknown, install the distribution package/module that
|
||||
provides it. Do not remove authentication to make the syntax check pass.
|
||||
|
||||
## Test authentication and SSE
|
||||
|
||||
Open the firewall only after all of these pass:
|
||||
|
||||
1. An unauthenticated HTTPS request is redirected to login or returns 401/403.
|
||||
2. Supplying forged `X-Thoth-Principal-*`, `X-Thoth-Is-Admin`, or `X-Thoth-Trusted-*` request
|
||||
headers does not grant access.
|
||||
3. A real authenticated non-admin can use the application but cannot open Pi Management.
|
||||
4. A real authenticated admin can use Pi Management.
|
||||
5. A browser session receives live model updates for longer than the default proxy timeout without
|
||||
batching; a protected `curl --no-buffer` test using a real short-lived login cookie is also
|
||||
acceptable. Delete the cookie jar immediately afterward.
|
||||
|
||||
Re-run these checks after changing the identity provider, auth gateway, Nginx, or ThothII release.
|
||||
For direct OIDC, verify login redirects to the configured provider, callback traffic reaches
|
||||
ThothII unchanged, forged identity headers grant nothing, and SSE is unbuffered. For deprecated
|
||||
upstream mode, additionally verify the external gateway rejects unauthenticated traffic and only
|
||||
its 2xx response can create trusted identity headers.
|
||||
|
||||
Reference in New Issue
Block a user