fix(auth): restore default passthrough of Authorization header to cluster#1084
Merged
Merged
Conversation
Cali0707
reviewed
Apr 21, 2026
Collaborator
There was a problem hiding this comment.
I think this message is a little misleading with these changed, maybe we can switch to:
token exchange requires require_oauth=true (token exchange depends on OAuth-validated tokens)
Cali0707
reviewed
Apr 21, 2026
…ster the Authorization header is always forwarded to the cluster when present and kubeconfig credentials are used as fallback when absent. require_oauth controls only whether the token is mandatory and validated, not whether it is forwarded. Signed-off-by: Nader Ziada <nziada@redhat.com>
nader-ziada
force-pushed
the
fix-cluster-auth-token
branch
from
April 21, 2026 17:36
3f60782 to
d444b6d
Compare
5 tasks
4 tasks
manusa
added a commit
to marcnuri-forks/kubernetes-mcp-server
that referenced
this pull request
Apr 22, 2026
…n coverage Follow-up to containers#1084. Addresses the two items intentionally left out of that PR to keep the original fix minimal. - Restore the "oauth token required" error in Manager.Derived() when require_oauth=true and no Bearer token is in context. The HTTP middleware already rejects token-less requests with 401, so this is defense-in-depth for STDIO / internal paths and preserves the operator contract that require_oauth=true never silently falls through to kubeconfig credentials. - Revert the two kubeconfig_derived_test.go cases flipped in containers#1084 back to asserting the error. - Add an SSE counterpart to TestAuthorizationRawPassthrough: the require_oauth=false raw-token-to-backend path was only exercised on StreamableHTTP, but the middleware-extracts-then-bridges flow is what SSE depends on and is new relative to v0.0.60. - Add TestAuthorizationClusterAuthModeKubeconfigDropsClientToken: locks in the stsExchangeTokenInContext clear behavior at the HTTP level (previously only covered at the unit level). - Add two TestClusterAuthMode cases asserting token exchange settings (token_exchange_strategy / sts_audience) without require_oauth=true are rejected with the reworded "token exchange requires require_oauth=true" error. Mild API-surface note: adds IsRequireOAuth() to the BaseConfig interface via a new RequireOAuthProvider. In-tree only *StaticConfig satisfies BaseConfig (RequireOAuth already exists on it); downstream out-of-tree implementers would need to add the method. Signed-off-by: Marc Nuri <marc@marcnuri.com>
matzew
pushed a commit
that referenced
this pull request
Apr 22, 2026
…n coverage (#1088) Follow-up to #1084. Addresses the two items intentionally left out of that PR to keep the original fix minimal. - Restore the "oauth token required" error in Manager.Derived() when require_oauth=true and no Bearer token is in context. The HTTP middleware already rejects token-less requests with 401, so this is defense-in-depth for STDIO / internal paths and preserves the operator contract that require_oauth=true never silently falls through to kubeconfig credentials. - Revert the two kubeconfig_derived_test.go cases flipped in #1084 back to asserting the error. - Add an SSE counterpart to TestAuthorizationRawPassthrough: the require_oauth=false raw-token-to-backend path was only exercised on StreamableHTTP, but the middleware-extracts-then-bridges flow is what SSE depends on and is new relative to v0.0.60. - Add TestAuthorizationClusterAuthModeKubeconfigDropsClientToken: locks in the stsExchangeTokenInContext clear behavior at the HTTP level (previously only covered at the unit level). - Add two TestClusterAuthMode cases asserting token exchange settings (token_exchange_strategy / sts_audience) without require_oauth=true are rejected with the reworded "token exchange requires require_oauth=true" error. Mild API-surface note: adds IsRequireOAuth() to the BaseConfig interface via a new RequireOAuthProvider. In-tree only *StaticConfig satisfies BaseConfig (RequireOAuth already exists on it); downstream out-of-tree implementers would need to add the method. Signed-off-by: Marc Nuri <marc@marcnuri.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
This PR restores the v0.0.60 auth-forwarding behavior that regressed after the Entra ID / OBO work (#953). The Authorization header is always forwarded to the cluster when present and kubeconfig credentials are used as fallback when absent.
require_oauthcontrols only whether the token is mandatory and validated, not whether it is forwarded.Default behavior: The server forwards the Authorization header to the Kubernetes cluster when present, and uses kubeconfig credentials when absent. No configuration is needed for this.
require_oauth = true: Makes the Authorization header mandatory and validates the token (expiry, audience, and optionally OIDC signature verification ifauthorization_urlis set). Requests without a valid token are rejected.cluster_auth_mode = "kubeconfig": Forces the server to always use kubeconfig credentials, ignoring any Authorization header. Use this when cluster authentication is managed separately (e.g., via a ServiceAccount).Notes beyond strict v0.0.60 restoration
The HTTP authorization middleware now also extracts the
Authorization: Bearer …header into the request context whenrequire_oauth=false. v0.0.60 did not do this in the HTTP layer — it relied solely on the MCP middleware, which left SSE clients + raw tokens broken (SSE transport does not propagate headers viareq.GetExtra().Header). This addition is small, additive hardening that makes raw-token forwarding work for SSE clients as well, consistent with the existingrequire_oauth=truehandling of the same transport gap.Manager.Derived()no longer returns the"oauth token required"error when invoked with no Bearer token in context underrequire_oauth=true; it falls back to kubeconfig instead. In the HTTP flow this path is unreachable (the authorization middleware already returns 401 first), so dependents are unaffected. Restoring this defense-in-depth guard and broadening integration coverage is tracked as a follow-up.