Skip to content

oauth/cimd: PR #119 post-merge review nits#120

Merged
BorisTyshkevich merged 1 commit into
mainfrom
oauth/cimd-pkj-post-merge-nits
May 16, 2026
Merged

oauth/cimd: PR #119 post-merge review nits#120
BorisTyshkevich merged 1 commit into
mainfrom
oauth/cimd-pkj-post-merge-nits

Conversation

@BorisTyshkevich
Copy link
Copy Markdown
Collaborator

Follow-up to merged #119. Five items from the post-merge review, no wire-protocol changes.

Fixes

  • audienceMatches doc/code mismatch. verifyClientAssertion comment said we'd accept AS-base-URL fallback for aud — the function only does byte-equal. Drop the misleading comment; document the byte-equal contract.
  • selectJWK use=sig filter. Direct kid hit on a use: enc key now returns nil; kid-empty fallback skips enc-only keys. RFC 7517 §4.2 separates signing vs encryption use.
  • Dead-code cleanup. Remove var _ = fmt.Sprintf placeholder and unused fmt import in client_assertion_test.go.
  • SECURITY: marker on no-jti decision. Inline note for future maintainers — replay window is bounded by the downstream JWE single-use today; if that invariant is ever weakened, we need the jti LRU.

New tests

  • TestAudienceMatches — direct unit coverage (exact / one-of-many / origin rejected / trailing-slash rejected / empty / unrelated).
  • TestSelectJWK_EncKeyRejected — kid hit on use=enc returns nil; kid fallback picks the use=sig key.
  • TestHandleOAuthTokenAuthCode_LenientPrivateKeyJWT — guards the parser-side accept of private_key_jwt against a future revert to strict-only.
  • TestParseCIMDMetadata_ClientSecretRejectedForPrivateKeyJWT — doc declaring private_key_jwt must not also carry client_secret.
  • TestFetchJWKS_SSRFBlocked — link-local jwks_uri allowed at parse, rejected at dial; resolver's SSRF blocklist fires through the JWKS fetcher.

Test plan

ok  	github.com/altinity/altinity-mcp/cmd/altinity-mcp	8.632s
ok  	github.com/altinity/altinity-mcp/pkg/clickhouse	2.249s
ok  	github.com/altinity/altinity-mcp/pkg/config	0.015s
ok  	github.com/altinity/altinity-mcp/pkg/jwe_auth	0.009s
ok  	github.com/altinity/altinity-mcp/pkg/server	16.936s
  • Rebuild image (only selectJWK use=sig filter is a runtime behaviour change — narrowing).
  • Roll to otel-google-mcp, otel-google-gating-mcp, github-mcp, antalya-mcp.
  • claude.ai + ChatGPT E2E smoke on one MCP each (no regression for none+PKCE; ChatGPT still accepted because it didn't ship client_assertion anyway).

Five items from the post-merge review of #119:

* `audienceMatches` doc/code mismatch — the verifyClientAssertion comment
  claimed we'd accept an AS-base-URL fallback for `aud`, but the function
  only does byte-equal. Drop the misleading comment; document the
  byte-equal contract explicitly with a forward note for when a
  real-world client ever needs origin-fallback.

* `selectJWK` filters out `use: enc` keys. The kid path now rejects an
  enc-purpose key even on direct kid hit; the kid-empty fallback skips
  enc-only keys. RFC 7517 §4.2 distinguishes signing vs encryption use
  and our verifier must never use an enc key to verify a JWS.

* Drop the dead `var _ = fmt.Sprintf` and the unused `fmt` import that
  was placeholder for stub helpers. `goimports` clean.

* SECURITY: marker on the no-jti decision in client_assertion.go. Today's
  replay bound is the JWE auth-code single-use guarantee; if that
  invariant is ever weakened, the assertion's full exp window becomes
  the replay surface. Inline plan for adding the LRU keyed by jti+kid+iss.

* 4 missing tests called out in review:
  - TestAudienceMatches: direct unit coverage (exact, one-of-many, origin
    rejected, trailing-slash rejected, empty, unrelated).
  - TestSelectJWK_EncKeyRejected: kid hit on use=enc returns nil; kid
    fallback skips enc-only and picks sig.
  - TestHandleOAuthTokenAuthCode_LenientPrivateKeyJWT: guards the parser
    accept of private_key_jwt against a future revert.
  - TestParseCIMDMetadata_ClientSecretRejectedForPrivateKeyJWT: doc
    declaring private_key_jwt MUST NOT also carry client_secret.
  - TestFetchJWKS_SSRFBlocked: link-local jwks_uri is allowed at parse
    but rejected at dial; confirms the resolver's blocklist actually
    fires for the JWKS fetch path.

No behaviour change at the wire for claude.ai or ChatGPT.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
@BorisTyshkevich BorisTyshkevich merged commit 43d1934 into main May 16, 2026
4 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant