# Put ThothII behind Caddy This example assumes Caddy runs on the Linux host, ThothII `frontend` listens only 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. ## Trust boundary Caddy is the only public listener. It provides automatic HTTPS, performs `forward_auth`, and proxies only to `frontend`; frontend then sends same-origin `/api` requests to private `core`. Never send the public reverse proxy to core port 8787. The authentication gateway must return 2xx only after validating a real credential or session. The ordered `route` below deletes every public/private Thoth identity request header before auth. Only on auth success does `copy_headers` rename normalized response claims into the private `X-Thoth-Trusted-*` headers consumed by frontend. Forwarding identity headers alone does not authenticate a user. Do not replace the authentication gateway with static `header_up` values, a network allowlist, or browser-provided identity. The admin claim must come from reviewed identity-provider authorization. ## Example configuration Save a reviewed site block in the Caddyfile. Caddy obtains and renews TLS certificates for the real DNS name; use the organization's approved ACME issuer or certificate policy. ```caddyfile thoth.example.com { route { # Remove untrusted browser claims before the auth subrequest. request_header -X-Authenticated-User request_header -X-Thoth-Principal-Issuer request_header -X-Thoth-Principal-Subject request_header -X-Thoth-Principal-Display-Name request_header -X-Thoth-Is-Admin request_header -X-Thoth-Trusted-Principal-Issuer request_header -X-Thoth-Trusted-Principal-Subject request_header -X-Thoth-Trusted-Principal-Display-Name request_header -X-Thoth-Trusted-Is-Admin forward_auth auth-gateway:4180 { uri /verify copy_headers { X-Thoth-Principal-Issuer>X-Thoth-Trusted-Principal-Issuer X-Thoth-Principal-Subject>X-Thoth-Trusted-Principal-Subject X-Thoth-Principal-Display-Name>X-Thoth-Trusted-Principal-Display-Name X-Thoth-Is-Admin>X-Thoth-Trusted-Is-Admin } } reverse_proxy 127.0.0.1:8080 { # Disable response batching so SSE reaches the browser immediately. flush_interval -1 header_up Host {host} header_up X-Forwarded-Proto https } } log { output file /var/log/caddy/thoth-access.log format json } } ``` Configure log processing to remove cookies, authorization data, query strings, and identity headers. Keep Caddy's private keys and state outside the ThothII source/operator directories. ## Validate and reload Keep the public firewall rule closed while validating. Confirm ThothII responds only on loopback, format a review copy if desired, validate the active file, then reload through the service manager: ```sh curl --fail http://127.0.0.1:8080/health caddy validate --config /etc/caddy/Caddyfile --adapter caddyfile sudo systemctl reload caddy ``` Do not remove `forward_auth` if validation fails. Correct the Caddy version, adapter syntax, authentication upstream, DNS, or certificate policy instead. ## 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 without batching; a protected `curl --no-buffer` request 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, authentication gateway, Caddy, or ThothII release.