-
Notifications
You must be signed in to change notification settings - Fork 1.1k
Add UpstreamHostOverride support for plugins and enhance reverse proxy handling #7289
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Conversation
…y handling - Introduced UpstreamHostOverride constant in ctx package for plugin use. - Implemented logic in reverse_proxy.go to allow plugins to override upstream host or URL. - Added a new test file for URL redirect plugin to demonstrate UpstreamHostOverride functionality.
A JIRA Issue ID is missing from your branch name, PR title and PR description! 🦄 Your branch: feat/add-dynamic-host-rewrite-from-plugins Your PR title: Add UpstreamHostOverride support for plugins and enhance reverse proxy handling Your PR description: - Introduced UpstreamHostOverride constant in ctx package for plugin use. - Implemented logic in reverse_proxy.go to allow plugins to override upstream host or URL. - Added a new test file for URL redirect plugin to demonstrate UpstreamHostOverride functionality. DescriptionAdds a new context that is settable from custom go plugin. THis allows URL overwrites. Motivation and Context
How This Has Been TestedUnit Tests and Manual testing of scenario. The included custom plugin example is set and used. Types of changes
Checklist
If this is your first time contributing to this repository - welcome! Please refer to jira-lint to get started. Without the JIRA Issue ID in your branch name you would lose out on automatic updates to JIRA via SCM; some GitHub status checks might fail. Valid sample branch names:‣ feature/shiny-new-feature--mojo-10' |
PR Reviewer Guide 🔍Here are some key observations to aid the review process:
|
API Changes --- prev.txt 2025-08-09 14:36:48.489103326 +0000
+++ current.txt 2025-08-09 14:36:38.361060913 +0000
@@ -3286,13 +3286,6 @@
}
JSVMEvent represents a JavaScript VM event configuration for event handlers.
-type JTIValidation struct {
- // Enabled indicates whether JWT ID claim is required.
- // When true, tokens must include a 'jti' claim.
- Enabled bool `bson:"enabled" json:"enabled"`
-}
- JTIValidation contains the configuration for the validation of the JWT ID.
-
type JWT struct {
// Enabled activates the basic authentication mode.
//
@@ -3321,10 +3314,6 @@
// Tyk classic API definition: `jwt_identity_base_field`
IdentityBaseField string `bson:"identityBaseField,omitempty" json:"identityBaseField,omitempty"`
- // SubjectClaims specifies a list of claims that can be used to identity the subject of the JWT.
- // The field is an OAS only field and is only used in OAS APIs.
- SubjectClaims []string `bson:"subjectClaims,omitempty" json:"subjectClaims,omitempty"`
-
// SkipKid controls skipping using the `kid` claim from a JWT (default behaviour).
// When this is true, the field configured in IdentityBaseField is checked first.
//
@@ -3337,11 +3326,6 @@
// Tyk classic API definition: `jwt_policy_field_name`
PolicyFieldName string `bson:"policyFieldName,omitempty" json:"policyFieldName,omitempty"`
- // BasePolicyClaims specifies a list of claims from which the base PolicyID is extracted.
- // The policy is applied to the session as a base policy.
- // The field is an OAS only field and is only used in OAS APIs.
- BasePolicyClaims []string `bson:"basePolicyClaims,omitempty" json:"basePolicyClaims,omitempty"`
-
// ClientBaseField is used when PolicyFieldName is not provided. It will get
// a session key and use the policies from that. The field ensures that requests
// use the same session.
@@ -3372,21 +3356,6 @@
// Tyk classic API definition: `jwt_expires_at_validation_skew`.
ExpiresAtValidationSkew uint64 `bson:"expiresAtValidationSkew,omitempty" json:"expiresAtValidationSkew,omitempty"`
- // AllowedIssuers contains a list of accepted issuers for JWT validation.
- // When configured, the JWT's issuer claim must match one of these values.
- AllowedIssuers []string `bson:"allowedIssuers,omitempty" json:"allowedIssuers,omitempty"`
-
- // AllowedAudiences contains a list of accepted audiences for JWT validation.
- // When configured, the JWT's audience claim must match one of these values.
- AllowedAudiences []string `bson:"allowedAudiences,omitempty" json:"allowedAudiences,omitempty"`
-
- // JTIValidation contains the configuration for the validation of the JWT ID.
- JTIValidation JTIValidation `bson:"jtiValidation,omitempty" json:"jtiValidation,omitempty"`
-
- // AllowedSubjects contains a list of accepted subjects for JWT validation.
- // When configured, the subject from kid/identityBaseField/sub must match one of these values.
- AllowedSubjects []string `bson:"allowedSubjects,omitempty" json:"allowedSubjects,omitempty"`
-
// IDPClientIDMappingDisabled prevents Tyk from automatically detecting the use of certain IDPs based on standard claims
// that they include in the JWT: `client_id`, `cid`, `clientId`. Setting this flag to `true` disables the mapping and avoids
// accidentally misidentifying the use of one of these IDPs if one of their standard values is configured in your JWT.
@@ -3611,8 +3580,6 @@
func (s *OAS) Fill(api apidef.APIDefinition)
Fill fills *OAS definition from apidef.APIDefinition.
-func (s *OAS) GetJWTConfiguration() *JWT
-
func (s *OAS) GetTykExtension() *XTykAPIGateway
GetTykExtension returns our OAS schema extension from inside *OAS.
@@ -4200,11 +4167,6 @@
// - For JWT: `scopes.jwt.scope_claim_name`
ClaimName string `bson:"claimName,omitempty" json:"claimName,omitempty"`
- // Claims contains a list of claims that contains the claim name.
- // The first match from the list of claims in the token is used.
- // OAS only field applied to OAS apis.
- Claims []string `bson:"claims,omitempty" json:"claims,omitempty"`
-
// ScopeToPolicyMapping contains the mappings of scopes to policy IDs.
//
// Tyk classic API definition:
@@ -4784,7 +4746,7 @@
// Negate is a boolean negation operator. Setting it to true inverts the matching behaviour
// such that the rewrite will be triggered if the value does not match the `pattern` for this rule.
- Negate bool `bson:"negate,omitempty" json:"negate,omitempty"`
+ Negate bool `bson:"negate" json:"negate"`
}
URLRewriteRule represents a rewrite
matching rules. Tyk classic API definition:
@@ -7809,6 +7771,8 @@
CacheOptions
OASDefinition
SelfLooping
+ // Used by plugins to override the upstream host
+ UpstreamHostOverride
)
# Package: ./dlpython
@@ -8545,9 +8509,6 @@
HMACSign = "hmac"
RSASign = "rsa"
ECDSASign = "ecdsa"
- ISS = "iss"
- AUD = "aud"
- JTI = "jti"
)
const (
ErrOAuthAuthorizationFieldMissing = "oauth.auth_field_missing"
@@ -8634,7 +8595,6 @@
var (
ErrNoSuitableUserIDClaimFound = errors.New("no suitable claims for user ID were found")
ErrEmptyUserIDInSubClaim = errors.New("found an empty user ID in sub claim")
- ErrEmptyUserIDInClaim = errors.New("found an empty user ID in predefined base claim")
)
var (
ErrSyncResourceNotKnown = errors.New("unknown resource to sync")
@@ -13599,6 +13559,7 @@
FUNCTIONS
+func HeaderBasedRedirect(rw http.ResponseWriter, r *http.Request)
func MyAnalyticsPluginDeleteHeader(record *analytics.AnalyticsRecord)
func MyAnalyticsPluginMaskJSONLoginBody(record *analytics.AnalyticsRecord)
func MyPluginAccessingOASAPI(rw http.ResponseWriter, r *http.Request) |
PR Code Suggestions ✨Explore these optional code suggestions:
|
📦 Impact Review Snapshot
## Impact AssessmentThis PR adds a new context key ## Required UpdatesNo immediate updates required in downstream repositories as this is an additive feature that doesn't break existing functionality. However, documentation should be updated to reflect this new capability for plugin developers. ## Compatibility ConcernsThe feature is implemented in a backward-compatible way. Existing plugins will continue to work as before, and only plugins that explicitly use the new context key will leverage this functionality. The implementation preserves the Host header behavior based on the PreserveHostHeader setting, maintaining compatibility with existing configurations. ## Summary & Recommendations
Tip: Mention me again using |
🛡️ Security Snapshot
## Security Impact AnalysisThis PR introduces a new context key The implementation lacks critical safeguards such as host validation, allowlisting, or network restrictions, which are essential when implementing dynamic routing capabilities. The sample plugin demonstrates using an HTTP header value directly to control routing, which compounds the risk by exposing this control to potentially untrusted client input. ## Identified VulnerabilitiesHigh Severity:
Medium Severity:
Low Severity:
## Security Recommendations
## OWASP Compliance
## Summary
Tip: Mention me again using |
🚦 Connectivity Review Snapshot
## Connectivity Assessment
## Test Coverage Validation
## Security & Performance Impact
## Summary & Recommendations
Tip: Mention me again using |
🚀 Performance Snapshot
## Performance Impact AnalysisThe PR introduces a context-based mechanism for plugins to override upstream hosts/URLs. This adds a context lookup in the reverse proxy director function, which is in the critical path for all requests. When the context value is present, additional string operations and potentially URL parsing are performed. The impact is minimal for requests without the override, but could be noticeable for high-throughput APIs using this feature, especially with complex URL overrides requiring parsing. ## Critical AreasThe main performance-sensitive area is the reverse proxy director function, which handles every request. The added code introduces conditional logic that executes for all requests (context lookup) with additional processing when the override is present. URL parsing is particularly expensive if performed frequently, though it only occurs when full URLs with schemes are provided as overrides. ## Optimization Recommendations
## Summary
Tip: Mention me again using |
User description
Description
Adds a new context that is settable from custom go plugin. THis allows URL overwrites.
Motivation and Context
How This Has Been Tested
Unit Tests and Manual testing of scenario. The included custom plugin example is set and used.
Types of changes
Checklist
PR Type
Enhancement, Tests
Description
Add context key
UpstreamHostOverride
Allow plugins to override upstream host/URL
Preserve host header based on overridden URL
Add sample plugin for header-based routing
Diagram Walkthrough
File Walkthrough
ctx.go
Introduce UpstreamHostOverride context key
ctx/ctx.go
UpstreamHostOverride
context key.reverse_proxy.go
Reverse proxy supports context-based upstream override
gateway/reverse_proxy.go
ctx.UpstreamHostOverride
from request context.url_redirect_plugin.go
Example plugin for header-based upstream override
test/goplugins/url_redirect_plugin.go
X-Route-To
header.ctx.UpstreamHostOverride
in request context.