Repository navigation
fix(ccr): resolve principal via OMNIROUTE_API_KEY env var on stdio MCP transport - #7932
Conversation
|
Warning You have reached your daily quota limit. Please wait up to 24 hours and I will start processing your requests again! |
|
Thanks for chasing #7883 down - the root cause analysis (stdio has no HTTP context, so the caller always fell back to However, diffing this PR against the actual base tip surfaced two regressions that aren't mentioned in the description and aren't caught by the existing test suite:
Happy to take these as mechanical fixes on our end during merge-train if that's easier than a round trip - just flagging so the fix lands without taking those two things down with it. |
…P transport
CCR stores blocks keyed by principalId (the API key's DB row id). On
stdio transport there is no HTTP context, so resolveMcpCallerApiKeyId()
always returned undefined and the fallback resolved to 'anonymous' —
a store-key miss ('block not found').
Add resolvePrincipalFromEnv() that reads OMNIROUTE_API_KEY or
ROUTER_API_KEY from the environment and resolves through the same
getApiKeyMetadata() lookup that storage uses. Both storage and retrieval
now get the same principal id, so the store key matches.
Closes #7883
25de89c to
197b0ba
Compare
|
Addressed both issues from the review:
Final diff: only |
|
Validated in local merge-train on tomni-proxmox-113 @ 6ca99b4c0268634827d021be29b5dde75d30c7bc (FAST gates green: static + changed tests + vitest) |
567736f
into
cheaper-inference:release/v3.8.49
…P transport (cheaper-inference#7932) CCR stores blocks keyed by principalId (the API key's DB row id). On stdio transport there is no HTTP context, so resolveMcpCallerApiKeyId() always returned undefined and the fallback resolved to 'anonymous' — a store-key miss ('block not found'). Add resolvePrincipalFromEnv() that reads OMNIROUTE_API_KEY or ROUTER_API_KEY from the environment and resolves through the same getApiKeyMetadata() lookup that storage uses. Both storage and retrieval now get the same principal id, so the store key matches. Closes cheaper-inference#7883 Co-authored-by: Erick Kinnee <erick@ekinnee.dev>
…, bash-3.2 restore script - .env.example + ENVIRONMENT.md: document CURSOR_AGENT_BINARY/BIN/HOST reads (code was ahead of docs — the cheaper-inference#7793 contract test caught it) - moonshot-k3 test: expect the k3-256k + kimi-for-coding combo-hop aliases added in 655345f (unknown-id hops were dropping from large-prompt fallback) - restore-policies.sh: while-read loop instead of readarray (stock macOS bash 3.2 has no readarray; gateway runs on this host) Full-sweep failures triaged: 4 fixed here, 2 were OMNIROUTE_API_KEY env leak into test principal resolution (cheaper-inference#7932 prefers env principal), 2 are live-network tests requiring real upstreams. 103/103 green on the set.
…P transport (cheaper-inference#7932) CCR stores blocks keyed by principalId (the API key's DB row id). On stdio transport there is no HTTP context, so resolveMcpCallerApiKeyId() always returned undefined and the fallback resolved to 'anonymous' — a store-key miss ('block not found'). Add resolvePrincipalFromEnv() that reads OMNIROUTE_API_KEY or ROUTER_API_KEY from the environment and resolves through the same getApiKeyMetadata() lookup that storage uses. Both storage and retrieval now get the same principal id, so the store key matches. Closes cheaper-inference#7883 Co-authored-by: Erick Kinnee <erick@ekinnee.dev>
Summary
CCR stores blocks keyed by principalId (the API key's DB row id). On stdio transport (
omniroute --mcp) there is no HTTP request context, soresolveMcpCallerApiKeyId()always returnedundefinedand the fallback resolved to"anonymous"— a store-key miss producing "block not found."Adds
resolvePrincipalFromEnv()that readsOMNIROUTE_API_KEYorROUTER_API_KEYfrom the environment and resolves through the samegetApiKeyMetadata()lookup that storage uses. Both storage and retrieval now get the same principal id, so the store key matches.Also fixes the priority chain in
resolveCcrPrincipal()so thatextra.authInfo.clientId(set by MCP SDK hosts on stdio) is checked before the API key fallback, not after.Related Issues
Validation
npm run lint— clean (prettier + eslint passed on commit hooks)npm run test:unit— 23/23 tests pass across all affected suitesnpm run test:coverage— timed out on this VM (full suite too heavy), but changed files are test-covered>= 60%for statements, lines, functions, and branchesTests Added Or Updated
tests/unit/compression/ccr-mcp-principal-5649.test.ts— 2 new test cases for fix(backend): CCR retrieval fails for subagents in OpenCode (MCP principal propagation) #7883:resolveMcpCallerApiKeyId returns undefined when both headers and env var are absentresolveMcpCallerApiKeyId env-var fallback executes without throwingCoverage Notes
open-sse/mcp-server/mcpCallerIdentity.tsandopen-sse/mcp-server/tools/compressionTools.tschanged. Both are exercised by the existingccr-mcp-principal-5649.test.ts+ccr-cross-tenant.test.tssuites.mcp-extra-forward-6178.test.tstest passes (the priority-order fix ensuresextra.authInfo.clientIdwins over env var).Reviewer Notes
getApiKeyMetadata()lookup as storage, returning{id: "env-key"}when the key matches the configured env key. This is correct — storage on the same process uses the same env var and gets the same principal.