feat(agentsts): lazy STS token exchange with per-audience scoping#1431
Open
syn-zhu wants to merge 3 commits intokagent-dev:mainfrom
Open
feat(agentsts): lazy STS token exchange with per-audience scoping#1431syn-zhu wants to merge 3 commits intokagent-dev:mainfrom
syn-zhu wants to merge 3 commits intokagent-dev:mainfrom
Conversation
Contributor
There was a problem hiding this comment.
Pull request overview
This PR updates the agentsts-adk integration to perform STS token exchange lazily at tool-call time (via before_tool_callback) instead of eagerly at invocation start (before_run_callback), caching the resulting access token per session for subsequent MCP tool calls.
Changes:
- Refactors
ADKTokenPropagationPluginsobefore_run_callbackonly extracts/stores the subject token, whilebefore_tool_callbackperforms (and caches) the STS exchange only for MCP tools. - Adds a subject-token cache (
_subject_tokens) and ensures both caches are cleared inafter_run_callback. - Updates and adds unit tests to validate the new lifecycle, including skipping non-MCP tools and no-op behavior when STS is not configured.
Reviewed changes
Copilot reviewed 2 out of 2 changed files in this pull request and generated 3 comments.
| File | Description |
|---|---|
| python/packages/agentsts-adk/src/agentsts/adk/_base.py | Moves exchange to before_tool_callback, adds subject-token caching, updates cleanup behavior. |
| python/packages/agentsts-adk/tests/test_adk_integration.py | Updates existing tests to match the new flow and adds coverage for non-MCP/no-STS scenarios. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
Move STS token exchange from before_run_callback (eager, once per invocation) to before_tool_callback (lazy, per MCP tool call). This avoids the sync/async problem in header_provider and only performs the exchange when an MCP tool is actually invoked. - before_run_callback now only extracts and stores the subject token - before_tool_callback exchanges on first McpTool call per session - Non-MCP tools (memory, AgentTool, etc.) are skipped - Cached tokens are reused for subsequent MCP calls in same session - Sets the stage for per-audience token exchange Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> Signed-off-by: Simon Zhu <simon.zhu@mongodb.com>
e8c0cff to
12afde3
Compare
Signed-off-by: Simon Zhu <simon.zhu@mongodb.com>
- Remove unused imports from _base.py (BaseAgent, LlmAgent, AuthCredential, etc.) - Remove add_to_agent method that would overwrite audience-aware closures created by create_header_provider in types.py - Remove LlmAgent import and add_to_agent test code from test_adk_integration.py - Make mock STS server include 'aud' claim in generated tokens when audience is provided, improving E2E test coverage for per-audience token exchange Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> Signed-off-by: Simon Zhu <simon.zhu@mongodb.com>
4106e87 to
cc07ac7
Compare
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
Closes #1430
This PR refactors STS token exchange in
ADKTokenPropagationPluginand adds per-audience token scoping so each MCP server can receive a differently-scoped access token.Lazy token exchange (moved from
before_run_callbacktobefore_tool_callback)before_run_callbacknow only extracts and stores the subject token from request headers -- no HTTP round-trip to the STSbefore_tool_callbackexchanges on firstMCPToolcall per (session, audience) pair; skips non-MCP tools (memory tools, AgentTool, etc.)Per-audience token exchange
STSAudiencefield onRemoteMCPServerSpec(server-level default) andMcpServerTool(per-agent override)McpServerTool.STSAudience>RemoteMCPServer.Spec.STSAudience> emptyADKTokenPropagationPlugintracksid(session_manager) -> audiencemappings viaregister_toolset()create_header_providerintypes.pycreates per-toolset closures that forward the audience to the STS header providerKAgentMcpToolsetcarriessts_audiencesoto_agent()can wire it throughCleanup
add_to_agentmethod fromADKTokenPropagationPlugin-- it would overwrite the audience-aware closures created bycreate_header_provider, causing all audience-scoped cache lookups to missBaseAgent,LlmAgent,AuthCredential,Event,Runner,BaseSessionService,Session)generateMockAccessTokennow includesaudclaim in generated tokens when audience is providedChanged files
CRD / API types (Go)
go/api/v1alpha2/agent_types.go--STSAudience *stringonMcpServerToolgo/api/v1alpha2/remotemcpserver_types.go--STSAudience *stringonRemoteMCPServerSpecgo/api/adk/types.go--STSAudienceonHttpMcpServerConfigandSseMcpServerConfiggo/api/v1alpha2/zz_generated.deepcopy.go-- generatedTranslator (Go)
go/core/internal/controller/translator/agent/adk_api_translator.go-- audience resolution + two-level overrideGolden tests (Go)
testdata/inputs/agent_with_sts_audience.yaml+ outputtestdata/inputs/agent_with_sts_audience_override.yaml+ outputsts_audiencefieldPlugin (Python)
agentsts-adk/src/agentsts/adk/_base.py--ADKTokenPropagationPluginrewriteagentsts-adk/tests/test_adk_integration.py-- comprehensive tests for all pathsADK types (Python)
kagent-adk/src/kagent/adk/types.py--create_header_providerwith audience closure,to_agentwiringkagent-adk/src/kagent/adk/_mcp_toolset.py--KAgentMcpToolset.sts_audiencekagent-adk/tests/unittests/test_header_propagation.py-- audience forwarding testsE2E test infrastructure (Go)
go/core/test/e2e/mocks/mock_sts_server.go-- audience-aware token generationTest plan
agentsts-adkunit tests pass (audience scoping, cache isolation, cleanup)agentsts-coreunit tests pass (no changes to core)kagent-adkheader propagation tests pass (audience forwarding)Co-Authored-By: Claude Opus 4.6 noreply@anthropic.com