Repository navigation
Authorize tools from trusted identities - #7827
Merged
Merged
Conversation
Contributor
Author
|
P0-02 |
This was referenced Oct 19, 2026
Aias00
approved these changes
Oct 20, 2026
Aias00
left a comment
Contributor
There was a problem hiding this comment.
Reviewed the full diff (21 files, +3052 / -5). This is a well-engineered, security-focused feature with strong design and excellent test coverage. A few non-blocking suggestions below.
Strengths
- Fail-closed by default. Feature disabled by default, frozen at startup, strict validation (length/count limits, no wildcards,
ignoreUnknownFields = false), and one immutable authorization snapshot shared bytools/listandtools/call. - Strong request isolation.
KeyAuthAuthenticationis a credential-free reference bound to the request's ReactorContextand verified againstexchange.getAttributes(); it cannot be borrowed across requests or inherited by disabled/unmatched key-auth execution. TheMono.defer+contextWritecomposition (outerclear, innerput) is correct. - No secret leakage.
KeyAuthAuthenticationdoes not overridetoString, and tests assert the API key never appears in output; forged headers/attributes are ignored. Adapter never logs tokens/claims or copies inbound identity into outbound credentials. - Optional dependency hygiene.
shenyu-plugin-key-authand the Spring Security modules areoptional, guarded by@ConditionalOnClass/ClassUtils.isPresentto avoid hard classpath coupling. Exaclty-one-resolver enforcement (>1throws) prevents conflicting authorities. - Excellent tests. Real loopback HTTP (JSON + SSE), concurrent tenant isolation, key rotation, cross-request isolation, error/cancellation, conflicting key-auth/principal sources, and
scopevsscpconflicts are all covered.
Non-blocking suggestions
audsingle-string handling.tokenAuthoritycallsPrincipalMcpSecurityResolver.names(attributes.get("aud"), false). RFC 7519 allowsaudto be a string or array, and Spring Security'sgetTokenAttributes().get("aud")can be a singleString; in that casenames(...)throws and the predicate fails closed, silently rejecting a valid token. Consider accepting bothStringandCollectionforaud(andiss).- OAuth2-login
subvs principal name.PrincipalMcpSecurityResolver.resolverequiressubject == authentication.getName(). ForOAuth2AuthenticationTokenthe name defaults to thenameattribute, which may differ from thesubclaim in some IdPs. This is documented, but an explicit attribute-name mapping forsubon the login source would avoid silent rejection. AgentMcpIdentityconstructor ergonomics. Two public constructors with different parameter orders ((subject, grants)vs(tenant, subject, grants, denials)) are easy to confuse. Consider a single builder, or@Deprecatedon the legacy 2-arg constructor with a clear note on which callers need the tenant.- Hardcoded FQCN strings.
AgentGatewayPluginConfiguration.agentGatewayPluginmixes"org.apache...PrincipalMcpSecurityResolver".equals(resolver.getClass().getName())withinstanceof KeyAuthMcpSecurityResolver. Useinstanceofconsistently for readability and refactor safety.
None of these are correctness or security blockers. The change is safe to merge once the maintainers are comfortable with the aud/sub behaviour for their IdP setups.
Approved.
4 tasks
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.
Background
The Agent Gateway MCP endpoint can list and call configured tools, but it does not yet bind tool access to a gateway-verified identity. An authenticated request therefore cannot receive tenant- or subject-specific tool grants, and applications cannot reuse their existing Spring Security authentication result for MCP authorization.
Changes
KeyAuthAuthenticationresult for successful API-key authentication, with request binding and rule attribution.(grants - denials) intersect rule allowedTools, with denial taking precedence and one immutable authorization snapshot shared bytools/listandtools/call.Verification
./mvnw clean verifyforshenyu-plugin-security/shenyu-plugin-key-auth,shenyu-plugin/shenyu-plugin-agent-gateway, and their Spring Boot starter: 659 tests, 0 failures, 0 errors, 0 skipped; Checkstyle and RAT passed../mvnw clean verifyfor the same three-module reactor: 659 tests, 0 failures, 0 errors, 0 skipped; Checkstyle and RAT passed.git diff --check: passed.