fix: honor top-level originRequest.access (default Access config) in ingress JWT validation#1695
Open
mvanhorn wants to merge 1 commit into
Open
Conversation
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.
Summary
A top-level
originRequest.accessblock now actually enforces Access JWT validation on every ingress rule. Previously it was silently ignored: validation only ran when theaccessblock was placed under an individual ingress rule, so operators who used the documented top-level form believed enforcement was active when it was not.Why this matters
The reporter of #784 traced the root cause in 2022 and it is unchanged on current master:
setConfig(viasetAccessiningress/config.go) correctly merges the global access config into each rule's effectiveOriginRequestConfig, butvalidateIngressiningress/ingress.goattaches themiddleware.NewJWTValidatorhandler from the raw per-ruler.OriginRequest.Accesspointer, so the merged value is computed and never used. A comment from 2026-07-10 confirms the bug still reproduces on 2026.7.1 with a minimal A/B test: the same block returns an unauthenticated 200 at top level and a 403 per-rule. Two later commenters flagged this as a live security risk because the failure is silent.Changes
validateIngressnow builds the Access handler from the mergedcfg.Access(the config returned bysetConfig(defaults, r.OriginRequest)) instead of the raw per-rule pointer. Because the merged field is a value type, the handler is gated on a non-zero merged config before callingvalidateAccessConfigurationand attaching the JWT validator.accessblock still overrides the global one through the existingsetAccessmerge. A 2022 comment called per-hostname placement "largely intended", but the code's own merge path and the origin-configuration docs both present the top-level block as supported; this change makes behavior match both.Testing
Extended
ingress/ingress_test.go: global-only access config attaches a validator to every rule; a per-rule block overrides the global teamName/audTag; per-rule-only behavior is unchanged; no access config anywhere attaches nothing; and a global block withrequired: truebut a blank teamName now fails at startup with the existing "access.TeamName cannot be blank" error instead of being silently ignored.go test ./ingress/...passes.Fixes #784