diff --git a/templates/deployment.yaml b/templates/deployment.yaml index f586e49..20b1e22 100644 --- a/templates/deployment.yaml +++ b/templates/deployment.yaml @@ -14,22 +14,22 @@ port > 0, sender email set — so this never rejects a config the server accepts {{- end }} {{- end }} {{/* ---mcp-enabled requires --url, and the server EXITS at boot without it rather -than starting in a degraded mode. +--url is REQUIRED as of Authorizer 2.4.0 — unconditionally, not just with +--mcp-enabled. The server EXITS at boot without it rather than starting in a +degraded mode. -The reason is not cosmetic: every token presented at /mcp is checked against -this deployment's canonical resource identifier, /mcp. With no --url that -identifier would be derived from request headers (X-Authorizer-URL, -X-Forwarded-Host, Host), which lets a caller name the audience their own token -must match — no check at all. So the server refuses the combination. +Without it the server derives its own host from request headers +(X-Authorizer-URL, X-Forwarded-Host, Host), so a forged header makes a genuine +password-reset or verification email carry a link to an attacker-controlled +domain (CWE-640). With --mcp-enabled it is worse still: every token presented +at /mcp is checked against /mcp, so a header-derived identifier would let +a caller name the audience their own token must match — no check at all. Caught at render time for the same reason as the SMTP check above: in-cluster the failure is a CrashLoopBackOff whose cause is one line in the container log. */}} -{{- if .Values.authorizer.mcp_enabled }} - {{- if not .Values.authorizer.authorizer_url }} - {{- fail "authorizer.mcp_enabled is true but authorizer.authorizer_url is not set. The MCP surface binds access tokens to /mcp, and deriving that identifier from request headers instead would let a caller choose their own token audience — so the server exits at boot in this configuration and the pod would CrashLoopBackOff. Set authorizer.authorizer_url (e.g. https://auth.example.com), or set mcp_enabled: false." }} - {{- end }} +{{- if not .Values.authorizer.authorizer_url }} + {{- fail "authorizer.authorizer_url is required as of Authorizer 2.4.0 — the server exits at boot without it and the pod would CrashLoopBackOff. Set authorizer.authorizer_url to this deployment's own public base URL, including the scheme (e.g. https://auth.example.com); a bare hostname is rejected. Note this is NOT authorizer.allowed_origins: authorizer_url is where Authorizer itself is reachable, allowed_origins is the list of apps it may redirect to." }} {{- end }} apiVersion: apps/v1 kind: Deployment diff --git a/values.yaml b/values.yaml index f90b92d..a96348c 100644 --- a/values.yaml +++ b/values.yaml @@ -178,7 +178,15 @@ authorizer: # AWS secret access key. In case of dynamodb database_type aws_secret_access_key: null - # URL for authorizer deployment + # REQUIRED as of Authorizer 2.4.0 — this deployment's own public base URL, + # including the scheme (e.g. https://auth.example.com). The chart fails at + # render time without it, because the server exits at boot: it is the only + # source used to build verification/reset/magic-link URLs, the JWT iss claim + # and OIDC discovery URLs, and deriving those from request headers instead + # exposes host-header-injection account takeover (CWE-640). + # + # This is NOT allowed_origins: authorizer_url is where Authorizer itself is + # reachable; allowed_origins is the list of apps it may redirect to. authorizer_url: null # Serve the MCP tool surface over HTTP at POST /mcp, as an