-
Notifications
You must be signed in to change notification settings - Fork 132
Integrate token exchange middleware #2143
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
Conversation
Codecov Report❌ Patch coverage is Additional details and impacted files@@ Coverage Diff @@
## main #2143 +/- ##
==========================================
+ Coverage 49.29% 49.34% +0.05%
==========================================
Files 244 244
Lines 30920 31009 +89
==========================================
+ Hits 15241 15301 +60
- Misses 14539 14573 +34
+ Partials 1140 1135 -5 ☔ View full report in Codecov by Sentry. 🚀 New features to boost your workflow:
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pull Request Overview
Adds OAuth 2.0 Token Exchange (RFC 8693) support to both 'thv proxy' and 'thv run' commands for secure downstream token swapping.
- New token exchange configuration flags added to RemoteAuthFlags for specifying exchange endpoints, credentials, and token parameters
- Refactored secret resolution into a reusable function that supports multiple sources (flags, files, environment variables)
- Token exchange middleware integrated into both proxy and runner configurations with conditional activation
Reviewed Changes
Copilot reviewed 8 out of 8 changed files in this pull request and generated 2 comments.
Show a summary per file
File | Description |
---|---|
pkg/runner/middleware.go | Registers token exchange middleware factory in supported middleware map |
pkg/runner/config_builder.go | Adds token exchange config parameter and conditional middleware creation |
pkg/api/v1/workload_service.go | Updates API service to pass nil token exchange config (not supported via API) |
docs/cli/thv_run.md | Documents new token exchange CLI flags for run command |
docs/cli/thv_proxy.md | Documents new token exchange CLI flags for proxy command |
cmd/thv/app/run_flags.go | Integrates token exchange config creation and passes to middleware builder |
cmd/thv/app/proxy.go | Refactors secret resolution and adds token exchange middleware selection logic |
cmd/thv/app/auth_flags.go | Defines token exchange flags structure and config building logic |
Tip: Customize your code reviews with copilot-instructions.md. Create the file or learn how to get started.
@claude review this PR. When reviewing make sure to take existing patterns in the CLI and the rest of the project into account. |
Claude finished @jhrozek's task —— View job Code Review: PR #2143 - Integrate token exchange middlewareI've reviewed this PR against existing patterns in the codebase. Overall, the implementation is well-structured and follows established conventions. Here are my findings: ✅ Strengths
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
added some comments
@claude please review this PR. One of the things to take into account is the integration aspect of the middleware |
Claude finished @jhrozek's task —— View job PR Review: Token Exchange Middleware IntegrationComprehensive review of the OAuth 2.0 Token Exchange (RFC 8693) integration focusing on middleware patterns and architecture. Executive SummaryThis PR successfully integrates token exchange middleware into ToolHive's architecture using well-established patterns. The implementation demonstrates strong understanding of the existing middleware system and follows most project conventions. A few integration aspects merit attention. Middleware Integration Analysis✅ Strengths1. Consistent Factory Pattern (
|
Aspect | Auth | Telemetry | Authz | Token Exchange |
---|---|---|---|---|
Factory registration | ✅ | ✅ | ✅ | ✅ |
Conditional application | N/A (always) | ✅ | ✅ | ✅ |
Error handling | ✅ | ✅ | ✅ | ✅ |
Test coverage | ✅ | ✅ | ✅ | ✅ |
Integration tests |
Note: Integration testing is a general gap across all middlewares, not specific to token exchange.
Final Verdict
The middleware integration is well-executed and follows ToolHive's established patterns. The implementation demonstrates understanding of:
- Factory pattern for middleware registration
- Conditional middleware application
- Clean separation between CLI and middleware layers
- Dual-mode operation for different use cases
The main concerns are around documentation clarity (middleware ordering, secret resolution) and missing integration tests, but these don't block the core functionality. The architecture is sound.
Recommendation: Approve with minor documentation improvements. Consider filing follow-up issues for integration tests and secret manager unification.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pull Request Overview
Copilot reviewed 12 out of 12 changed files in this pull request and generated 3 comments.
Tip: Customize your code reviews with copilot-instructions.md. Create the file or learn how to get started.
Adds OAuth 2.0 Token Exchange (RFC 8693) support to both 'thv proxy' and 'thv run' commands for secure downstream token swapping. Changes include: - New token exchange configuration flags in RemoteAuthFlags - Refactored secret resolution into reusable resolveSecretFromSources - Token exchange middleware registration in runner config builder - Conditional middleware application based on configuration When token exchange is configured via --token-exchange-url, the middleware exchanges the user's bearer token for a downstream token suitable for backend authentication. Fixes: #2066
Make the ClientID field optional in ExchangeConfig to support token exchange endpoints that do not require client credentials. Some token exchange services like Google STS rely on trust relationships configured in the identity provider (e.g., Workload Identity Federation) rather than requiring explicit client authentication credentials. This change removes the ClientID validation requirement while keeping the field available for services that do need it.
Add support for specifying the subject token type in OAuth 2.0 token exchange requests according to RFC 8693. Changes: - Add constants for ID token and JWT token types - Add SubjectTokenType field to ExchangeConfig - Default to access_token type when not specified - Use configured type in token exchange requests This enables exchanging different token types (access tokens, ID tokens, or generic JWTs) which is required for services like Google STS that expect ID tokens rather than access tokens.
Wire SubjectTokenType through the middleware layer to support configuring token type for exchange requests. Changes: - Add SubjectTokenType field to middleware Config struct - Pass SubjectTokenType to ExchangeConfig when creating middleware - Support JSON configuration with subject_token_type field This enables configuring the subject token type (access_token, id_token, or jwt) when using token exchange middleware through configuration files or API.
Add SubjectTokenProvider parameter to enable two modes of operation: 1. Header-based mode (nil provider): Extract token from Authorization header 2. Provider-based mode (non-nil provider): Use external token source Changes: - Add SubjectTokenProvider function type - Update CreateTokenExchangeMiddlewareFromClaims to accept optional provider - Implement conditional logic to choose token source based on provider - Update all existing call sites to pass nil for backwards compatibility - Update tests to use new API This enables using the token exchange middleware with tokens from OAuth flows (like the proxy command) while maintaining compatibility with existing OIDC validation scenarios.
Integrate all token exchange improvements into the proxy command's CLI and authentication flow. Changes: - Add --token-exchange-subject-token-type CLI flag - Update BuildTokenExchangeConfig to include SubjectTokenType - Change handleOutgoingAuthentication to return full OAuthFlowResult - Extract ID token from OAuth flow results - Create SubjectTokenProvider based on token type configuration - Pass provider to CreateTokenExchangeMiddlewareFromClaims This enables the proxy command to exchange ID tokens (for Google STS) or access tokens based on the configured subject token type, completing support for Google Cloud Workload Identity Federation and similar services. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <[email protected]>
Allow users to specify token types using short, intuitive names instead of requiring full URN syntax. This improves the user experience by reducing verbosity and making the flag easier to use correctly. Changes: - Add NormalizeTokenType() function to accept both short forms (access_token, id_token, jwt) and full URNs - Update BuildTokenExchangeConfig() to normalize user input at CLI layer - Update flag help text to show accepted short forms - Add comprehensive tests covering normalization and error cases - Regenerate CLI documentation with new flag description Users can now write: --token-exchange-subject-token-type id_token Instead of: --token-exchange-subject-token-type urn:ietf:params:oauth:token-type:id_token The implementation maintains backward compatibility by accepting full URNs, ensuring existing configurations and scripts continue to work unchanged.
…ave a usecase It's not exposed from the CLI anyway.
…lient (#2167) * reuse the same code for secrets in remote client and token exchange client Closes: #2166 * use constant --------- Co-authored-by: taskbot <[email protected]>
When using token exchange flags (--token-exchange-url, etc.) without --remote-auth, the token exchange middleware was not being created due to the condition `tokenExchangeConfig != nil && tokenSource != nil` in addExternalTokenMiddleware. The tokenSource is nil when the proxy doesn't perform outgoing OAuth authentication (--remote-auth is not used). However, the token exchange middleware is designed to work in this scenario by extracting the subject token from the incoming request's Authorization header. Changes: - Add CreateMiddlewareFromHeader function that creates token exchange middleware without a tokenSource, allowing it to extract tokens from the Authorization header - Update addExternalTokenMiddleware to handle both cases: * tokenSource != nil: Use CreateMiddlewareFromTokenSource * tokenSource == nil: Use CreateMiddlewareFromHeader - Add early return with warning if tokenExchangeConfig is nil despite token exchange URL being provided This fixes the use case where thv proxy receives authenticated requests and needs to exchange those tokens for backend access, without performing its own OAuth flow.
Adds OAuth 2.0 Token Exchange (RFC 8693) support to both 'thv proxy' and 'thv run' commands for secure downstream token swapping.
Changes include:
- New token exchange configuration flags in RemoteAuthFlags
- Refactored secret resolution into reusable resolveSecretFromSources
- Token exchange middleware registration in runner config builder
- Conditional middleware application based on configuration
When token exchange is configured via --token-exchange-url, the
middleware exchanges the user's bearer token for a downstream token
suitable for backend authentication.
Fixes: #2066