feat(agentgateway): add client-owned token cache#142
Merged
Conversation
15 tasks
cassiofariasmachado
previously approved these changes
Jun 1, 2026
NicoleMGomes
previously approved these changes
Jun 1, 2026
prashantrakheja
approved these changes
Jun 2, 2026
prashantrakheja
left a comment
Contributor
There was a problem hiding this comment.
couple of minor comments, looks good otherwise
2cb225c
cassiofariasmachado
approved these changes
Jun 2, 2026
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.
Description
Adds a per-client token cache to
AgentGatewayClientto avoid redundant IAS token requests during agentic loops. Both the customer (mTLS) and LoB (BTP Destination Service) flows are covered.Token cache (
_token_cache.py):_TokenCache- LRU-boundedOrderedDictfor system and user tokens with monotonic TTL. Expiry resolves fromexpires_at→expires_in→expJWT claim (access then id token) → config fallback TTL. Configurable buffer subtracted from all explicit expiries._GatewayUrlCache- separate LRU-boundedOrderedDictfor gateway URLs (stable within a client's lifetime, bounded to prevent memory growth in long-lived multi-tenant clients)._parse_jwt_exp- unverified JWT payload parser used only for TTL hints, never for security decisions.Customer flow (
_customer.py):_request_token_mtlsnow returns the full token response dict instead of justaccess_token, so callers can pass it tocompute_expires_at.get_system_token_mtlsandexchange_user_tokenaccept an optional_TokenCacheand short-circuit on cache hit.LoB flow (
_lob.py):fetch_system_authandfetch_user_authaccept optional_TokenCache+_GatewayUrlCacheand short-circuit on cache hit.ValueErrorif exactly one oftoken_cache/gateway_url_cacheis provided (previously the cache was silently skipped in that case).Client (
agw_client.py):AgentGatewayClient.__init__creates a_TokenCacheand_GatewayUrlCacheinstance and threads them through all auth calls.Config (
config.py):ClientConfigfields:fallback_token_ttl_seconds(300 s),token_expiry_buffer_seconds(30 s),max_system_token_cache_size(32),max_user_token_cache_size(256).Type of Change
How to Test
uv run pytest tests/agentgateway/unit/ -qAgentGatewayClient, callget_system_authtwice with the same tenant/credentials, observe only one token request is made (mock or inspect the_token_cachedirectly viaclient._token_cache).Checklist
Breaking Changes
None. All cache params are optional with
Nonedefaults. Existing callers unaffected._request_token_mtlsreturn type changed fromstrtodict, but it is a private function.Additional Notes
sha256(user_jwt + "|" + scope_key)[:16].OrderedDictops atomic, but check-then-set is not. Concurrent coroutines for the same key may both miss and both fetch - produces redundant requests, not corruption. Documented in module docstring._GatewayUrlCachedefault max size is 64 (independent ofClientConfig). Can be made configurable if needed.