Repository navigation
perf(mcp): cache SSO identity assertion reads on the ID-JAG path - #39348
yassin-berriai merged 7 commits into
Conversation
Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
🤖 Devin AI EngineerI'll be helping with this pull request! Here's what you should know: ✅ I will automatically:
Note: I can only respond to comments from users who have write access to this repository. ⚙️ Control Options:
|
|
|
|
PR #39348 (BerriAI/litellm, author devin-ai-integration[bot]) has no |
Greptile SummaryThe PR adds a short-lived process-local cache for SSO identity assertions used by ID-JAG credential resolution.
Confidence Score: 5/5The PR appears safe to merge. No blocking failure remains.
|
| Filename | Overview |
|---|---|
| litellm/proxy/_experimental/mcp_server/outbound_credentials/sso_assertion_store.py | Adds assertion caching and replaces finite per-user generation markers with a non-expiring process-wide epoch guard. |
| litellm/constants.py | Defines the configurable SSO assertion cache TTL with a 60-second default. |
| tests/test_litellm/proxy/_experimental/mcp_server/outbound_credentials/test_sso_assertion_store.py | Adds coverage for cache hits, login invalidation, overlapping reads, misses, expiration, and injected caches. |
| tests/test_litellm/test_router.py | Renames an existing router test without changing its behavior. |
Reviews (4): Last reviewed commit: "fix(mcp): use a process-wide epoch for s..." | Re-trigger Greptile
Codecov Report✅ All modified and coverable lines are covered by tests. 📢 Thoughts on this report? Let us know! |
…itellm_lit_5060_cache_sso_assertion_reads
Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
|
@greptileai please re-review after 709ee4c, which adds per-user generation guards against stale repopulation plus a regression test |
|
Fixed in 709ee4c: fetch records a per-user generation before the DB read and only caches if login did not bump it |
|
TTL test now persists through a second cache instead of mutating stored. The mock line is exactly 120 chars, ruff format keeps it |
…separate namespaces Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
|
@greptileai please re-review after bca1822, which moves generation markers into their own cache so user ids cannot collide with them |
…passes Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
|
@greptileai please re-review after 205e943, which replaces the per-user markers with a process-wide epoch counter |
…_assertion_reads Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
1add1b4
into
litellm_internal_staging
TLDR
Problem this solves:
How it solves it:
MCP_SSO_ASSERTION_CACHE_TTL_SECONDS, default 60s)User Flow
Before: an agent calling an
oauth2_id_jagMCP server with a LiteLLM key gets a DB read on every calltools/callfor a tool on that server, five times in a rowAfter: the same five calls hit Postgres once
tools/callfor a tool on that server, five times in a rowRelevant issues
Follow-up to #35147, where this was measured and deferred
Linear ticket
Resolves LIT-5060
Pre-Submission checklist
Please complete all items before asking a LiteLLM maintainer to review your PR
uv run pytest tests/test_litellm/<your_test_file>.py -v. Leave the suites (make test-unit-*,make test-unit) to CI: it finishes in ~15 minutes where a laptop takes an hour or more@greptileaito re-request a review after pushing changes)Delays in PR merge?
If you're seeing a delay in your PR being merged, ping the LiteLLM Team on Slack (#pr-review).
Screenshots / Proof of Fix
A live run needs an enterprise IdP that supports RFC 8693 ID-JAG exchange plus an EMA-protected MCP upstream, which this environment does not have, so the section below is the runbook a reviewer with that setup can follow. It is the same measurement used in #35147 and the ticket. Statement counts below are the expected values, not a captured run
Shared setup: a proxy with SSO configured and one MCP server with
auth_type: oauth2_id_jag, Postgres started withlog_statement='all'. Sign in once through/sso/key/generateso an assertion is stored, then runBefore (2ce4e3f)
200lines from the loopgrep -cprints5: one assertion-table read per callAfter (205e943)
200lines from the loopgrep -cprints1: the first call reads, the other four are served from the in-process cache/sso/key/generate, run one more call: the count goes to2, since the login busted the cached entryType
🚄 Infrastructure
Caveats (if any)
Medium
MCP_SSO_ASSERTION_CACHE_TTL_SECONDS(60s) after a login on another replicaLow
invalidate(user_id)on the sameSSOAssertionCacheFinal Attestation
Link to Devin session: https://app.devin.ai/sessions/4ce3dfeb377f4a91bcba8ea4c24ca5c6
Open in Devin Desktop: https://app.devin.ai/desktop/session/4ce3dfeb377f4a91bcba8ea4c24ca5c6?variant=devin
Requested by: @yassin-berriai