Files
ThothII/docs/install/reverse-proxy-nginx.md
T

144 lines
5.6 KiB
Markdown

# Put ThothII behind Nginx
Choose exactly one authentication mode. Direct ThothII-managed OIDC and deprecated upstream
authentication are mutually exclusive proxy contracts; never combine their locations or headers.
## Direct ThothII-managed OIDC
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.
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.invalid;
return 301 https://$host$request_uri;
}
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;
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;
ssl_protocols TLSv1.2 TLSv1.3;
location = /_authenticate {
internal;
proxy_pass http://auth-gateway:4180/verify;
proxy_pass_request_body off;
proxy_set_header Content-Length "";
proxy_set_header X-Original-URI $request_uri;
proxy_set_header X-Original-Method $request_method;
proxy_set_header X-Authenticated-User "";
proxy_set_header X-Thoth-Principal-Issuer "";
proxy_set_header X-Thoth-Principal-Subject "";
proxy_set_header X-Thoth-Principal-Display-Name "";
proxy_set_header X-Thoth-Is-Admin "";
proxy_set_header X-Thoth-Trusted-Principal-Issuer "";
proxy_set_header X-Thoth-Trusted-Principal-Subject "";
proxy_set_header X-Thoth-Trusted-Principal-Display-Name "";
proxy_set_header X-Thoth-Trusted-Is-Admin "";
}
location / {
auth_request /_authenticate;
auth_request_set $thoth_principal_issuer
$upstream_http_x_thoth_principal_issuer;
auth_request_set $thoth_principal_subject
$upstream_http_x_thoth_principal_subject;
auth_request_set $thoth_principal_display_name
$upstream_http_x_thoth_principal_display_name;
auth_request_set $thoth_is_admin
$upstream_http_x_thoth_is_admin;
proxy_set_header X-Authenticated-User "";
proxy_set_header X-Thoth-Principal-Issuer "";
proxy_set_header X-Thoth-Principal-Subject "";
proxy_set_header X-Thoth-Principal-Display-Name "";
proxy_set_header X-Thoth-Is-Admin "";
proxy_set_header X-Thoth-Trusted-Principal-Issuer $thoth_principal_issuer;
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;
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;
}
}
```
## 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
Keep the public firewall closed while validating:
```sh
curl --fail http://127.0.0.1:8080/health
sudo nginx -t
sudo systemctl reload nginx
```
## Test authentication and SSE
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.