Skip to content

Configure Caddy

Caddy is a convenient front end for gotifacts: it obtains TLS certificates automatically and has first-class forward_auth support. This page shows the routing split; adapt the SSO backend to your provider.

A complete, commented example lives in the repo at examples/caddy/Caddyfile. The essentials:

# SECURITY: never trust a client-supplied identity header.
(strip_identity) {
request_header -Remote-User
}
# Apex: portal + management + ingest.
example.com {
import strip_identity
# Ingest plane: forward-auth OFF (API key enforced by gotifacts).
handle /ingest/* {
request_body {
max_size 64MB
}
reverse_proxy gotifacts:8080
}
# Management plane: forward-auth ON.
handle {
forward_auth your-sso-backend:9091 {
uri /api/verify?rd=https://auth.example.com
copy_headers Remote-User # inject the authenticated user
}
reverse_proxy gotifacts:8080
}
}

Caddy wildcards match a single label, so one and two label levels need separate blocks. Both strip the identity header and add the framing policy for portal thumbnails:

*.example.com,
*.*.example.com {
import strip_identity
reverse_proxy gotifacts:8080
header Content-Security-Policy "frame-ancestors https://example.com"
}

Keep the frame-ancestors value pointed at the canonical GOTIFACTS_BASE_DOMAIN, since the portal is served from there.

To serve the instance on additional alias domains, list them in GOTIFACTS_ALIAS_DOMAINS and duplicate the apex + wildcard blocks for each domain. gotifacts serves the same sites under every domain.

If you enable the MCP connector, add a handle that bypasses forward-auth for the machine endpoints, while /mcp/oauth/authorize falls through to the authenticated catch-all. A handle takes at most one matcher token, so list the paths in a named matcher rather than inline:

@mcp_machine path /mcp /mcp/oauth/token /mcp/oauth/register /.well-known/oauth-*
handle @mcp_machine {
reverse_proxy gotifacts:8080
}