From d5814d7fb5f2c43bde934a31e92897e2e42c76f8 Mon Sep 17 00:00:00 2001 From: Lakhan Samani Date: Fri, 14 Aug 2026 10:43:03 +0530 Subject: [PATCH] fix: require authorizer_url unconditionally MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit #764 made --url mandatory in Authorizer 2.4.0 — the server exits at boot without it. This deploy path passed the flag but treated the value as optional, so a default deploy produces a server that will not start. The render-time guard only fired when mcp_enabled was set, so a default helm install rendered cleanly and then CrashLoopBackOffed with the cause one line deep in the container log. Now fails at render like the SMTP check, with the allowed_origins distinction spelled out. --- templates/deployment.yaml | 22 +++++++++++----------- values.yaml | 10 +++++++++- 2 files changed, 20 insertions(+), 12 deletions(-) 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