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

3.6 KiB

Put ThothII behind Caddy

Choose exactly one authentication mode. Direct ThothII-managed OIDC and deprecated upstream authentication are mutually exclusive proxy contracts; never combine their directives.

Direct ThothII-managed OIDC

Use this mode when auth.yaml has mode: oidc. Caddy terminates TLS and proxies every request to frontend; ThothII performs login, callback validation, session creation, and authorization. Caddy must not apply forward_auth or another external authentication gateway.

The public /api/auth/oidc/login and /api/auth/oidc/callback paths pass unchanged through the same proxy as the rest of /api. The configured publicUrl must match the browser origin.

thoth.example.invalid {
	reverse_proxy 127.0.0.1:8080 {
		# No URI rewrite: OIDC login and callback paths reach frontend unchanged.
		flush_interval -1
		header_up Host {host}
		header_up X-Forwarded-Proto https
		header_up X-Forwarded-Host {host}
	}

	log {
		output file /var/log/caddy/thoth-access.log
		format json
	}
}

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. Here an external authentication gateway owns login and Caddy applies forward_auth before forwarding normalized private identity headers to frontend.

Forwarding identity headers alone does not authenticate a user. The authentication gateway returns 2xx only after validating its own credential or session. Clear browser-supplied public and trusted headers before the subrequest, and map identity only from the successful auth response.

thoth.example.invalid {
	route {
		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 {
			flush_interval -1
			header_up Host {host}
			header_up X-Forwarded-Proto https
		}
	}
}

Trust boundary

Caddy is the only public listener and proxies only to loopback frontend, never directly to core. Configure access logs to omit cookies, authorization data, query strings, and identity headers. Keep Caddy keys and state outside ThothII source and operator directories.

Validate and reload

Keep the public firewall closed while validating:

curl --fail http://127.0.0.1:8080/health
caddy validate --config /etc/caddy/Caddyfile --adapter caddyfile
sudo systemctl reload caddy

Test authentication and SSE

For direct OIDC, verify the login path redirects to the configured provider, the callback 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.