Skip to content

tests: add OAuth2 issuance, JWT verification, consent, discovery, sessions, and MCP auth unit tests#4523

Open
Pratham-Mishra04 wants to merge 1 commit into
06-18-docs_adds_docs_for_mcp_oauth_serverfrom
06-18-feat_adds_unit_tests_for_mcp_oauth_server
Open

tests: add OAuth2 issuance, JWT verification, consent, discovery, sessions, and MCP auth unit tests#4523
Pratham-Mishra04 wants to merge 1 commit into
06-18-docs_adds_docs_for_mcp_oauth_serverfrom
06-18-feat_adds_unit_tests_for_mcp_oauth_server

Conversation

@Pratham-Mishra04

Copy link
Copy Markdown
Collaborator

Summary

Adds a comprehensive test suite for the OAuth2/MCP authentication layer, covering the configstore persistence layer, HTTP handler logic, JWT issuance and verification, consent flows, session management, and discovery endpoints.

Changes

  • Added configstore tests validating the OAuth2 signing key auto-generation and stability, authorize request atomic state transitions (pending → consented → code_issued), single-use code enforcement, expired code rejection, refresh token rotation and replay detection, family-wide revocation, token and client sweep/GC behavior, and the identity filter OR-group parenthesization in ListOauthUserTokens.
  • Added handler tests for getMCPServerForRequest covering the JWT path (vk/user/session modes, active/inactive VK checks, session validation matching, auth enforcement gating) and the header/anonymous path (header VK acceptance and rejection, anonymous fallback, OAuth strict mode WWW-Authenticate responses).
  • Added JWT verification tests covering all valid modes, a full matrix of rejection cases (expired, nbf in future, missing claims, issuer/audience mismatch, wrong kid, wrong signing key, non-RS256 algorithms, alg:none, malformed tokens), and infrastructure fault isolation (nil store, unavailable signing key).
  • Added consent flow tests for flowDetail (pending, missing, empty id, expired, already-consented) and flowSubmit across VK (active, inactive, unknown, empty, double-submit), session (enforced vs. not enforced), user (no resolver, resolved, no session), and VK-to-user upgrade binding (matching owner, mismatched owner, not signed in).
  • Added OAuth2 issuance handler tests for DCR registration, the authorize endpoint (happy path, loopback port flexibility, unknown client, unregistered redirect, protocol error redirects), token endpoint authorization code exchange (happy path, PKCE mismatch, single-use, expired, client_id mismatch, missing fields, unsupported grant), and refresh token rotation and replay guard.
  • Added session management handler tests for listing grants and revoking grants with identity-gated authorization (vk mode unrestricted, user mode caller-match, mismatch, unauthenticated).
  • Added discovery handler tests verifying that headers mode returns 404 on all discovery endpoints, while oauth and both modes serve PRM, AS metadata, and JWKS with correct field values.
  • Added utility tests for matchRedirectURI (exact match, loopback port flexibility, path/scheme enforcement, malformed input), oauth2IssuerURL (configured vs. request-host fallback), and oauth2ServerCfg default TTL values.
  • Introduced shared test infrastructure: mockOAuth2Store, newTestSigningKey, newTestOAuth2Config, mintTestToken, newTestMCPHandler, and real SQLite-backed store helpers for issuance tests that require actual atomic semantics.

Type of change

  • Bug fix
  • Feature
  • Refactor
  • Documentation
  • Chore/CI

Affected areas

  • Core (Go)
  • Transports (HTTP)
  • Providers/Integrations
  • Plugins
  • UI (React)
  • Docs

How to test

go test ./framework/configstore/... ./transports/bifrost-http/handlers/...

All new test files are self-contained and use in-memory SQLite or mock stores; no external services are required.

Screenshots/Recordings

N/A

Breaking changes

  • No

Related issues

N/A

Security considerations

Tests explicitly cover security-critical paths: JWT algorithm confusion (alg:none, HS256, RS384), replay detection for authorization codes and refresh tokens, family-wide token revocation on replay, inactive VK rejection, identity mismatch on session revocation, and WWW-Authenticate header presence on OAuth strict mode rejections.

Checklist

  • I read docs/contributing/README.md and followed the guidelines
  • I added/updated tests where appropriate
  • I updated documentation where needed
  • I verified builds succeed (Go and UI)
  • I verified the CI pipeline passes locally if applicable

@CLAassistant

Copy link
Copy Markdown

CLA assistant check
Thank you for your submission! We really appreciate it. Like many open source projects, we ask that you sign our Contributor License Agreement before we can accept your contribution.
You have signed the CLA already but the status is still pending? Let us recheck it.

Pratham-Mishra04 commented Jun 18, 2026

Copy link
Copy Markdown
Collaborator Author

@coderabbitai

coderabbitai Bot commented Jun 18, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro Plus

Run ID: 1b93a4e9-4dbb-431f-b21d-f728e03ea6a0

📥 Commits

Reviewing files that changed from the base of the PR and between 7cae97e and ce7bb1b.

📒 Files selected for processing (9)
  • framework/configstore/rdb_mcp_sessions_identity_test.go
  • framework/configstore/rdb_oauth2_test.go
  • transports/bifrost-http/handlers/mcpserver_auth_test.go
  • transports/bifrost-http/handlers/oauth2_consent_test.go
  • transports/bifrost-http/handlers/oauth2_discovery_test.go
  • transports/bifrost-http/handlers/oauth2_issuance_test.go
  • transports/bifrost-http/handlers/oauth2_jwt_test.go
  • transports/bifrost-http/handlers/oauth2_sessions_test.go
  • transports/bifrost-http/handlers/oauth2_utils_test.go

📝 Walkthrough

Summary by CodeRabbit

  • Tests
    • Added comprehensive test coverage for OAuth2 authentication and token management, including authorization code flow, refresh token rotation, session handling, and JWT verification.
    • Added tests for MCP server authentication across multiple auth modes and identity resolution.
    • Added tests for OAuth2 discovery and consent flow endpoints with various configuration scenarios.

Walkthrough

Adds nine new test files providing coverage for the OAuth2 and MCP authentication stack: RDB store operations (signing key, consent/consume lifecycle, token rotation, sweeps, session listing), HTTP handler logic (JWT extraction and verification, redirect URI matching, discovery endpoints, consent flow, DCR registration and token issuance, session management), and MCP server auth request routing.

Changes

ConfigStore OAuth2 and MCP Sessions Tests

Layer / File(s) Summary
OAuth2 store setup and seed helpers
framework/configstore/rdb_oauth2_test.go
Defines the OAuth2 test store via AutoMigrate and adds helpers to seed authorize-request and refresh-token rows used across all OAuth2 store tests.
Signing key, consent, and authorize-request consumption tests
framework/configstore/rdb_oauth2_test.go
Tests GetOAuth2SigningKey stability, ConsentOAuth2AuthorizeRequest atomic pending→consented transition and double-consent guard, and ConsumeOAuth2AuthorizeRequest single-use and expiry rejection.
Refresh token rotation, revocation, and sweep tests
framework/configstore/rdb_oauth2_test.go
Tests RotateOAuth2RefreshToken rotation and replay guard, RevokeOAuth2RefreshTokensByFamilyID cross-family isolation, SweepOAuth2RefreshTokens stale deletion and noop for non-positive retention, and RevokeOAuth2RefreshTokensByMode mode-scoped revocation.
Client/authorize-request sweeps, session listing, and convergence
framework/configstore/rdb_oauth2_test.go
Tests SweepOrphanedOAuth2Clients grace-window behavior, SweepExpiredOAuth2AuthorizeRequests status-selective deletion, ListOAuth2Sessions VK join and revoked-session exclusion, and sweep-convergence ordering.
MCP sessions identity filter and auth-mode composition
framework/configstore/rdb_mcp_sessions_identity_test.go
Tests ListOauthUserTokens identity exact-match and correct composition of the identity OR-group with the AuthModes filter.

HTTP Handler OAuth2 Tests

Layer / File(s) Summary
mockOAuth2Store, RSA key helpers, and JWT minting
transports/bifrost-http/handlers/oauth2_jwt_test.go
Defines mockOAuth2Store implementing minimal config-store behavior, RSA keypair generation helpers, and a JWT minting helper with claim mutation support.
Bearer extraction, JWT verification, and context injection tests
transports/bifrost-http/handlers/oauth2_jwt_test.go
Table-driven tests for extractBearerJWT, verifyMCPJWT acceptance and rejection across all failure modes, config-fault error labeling, and injectJWTContext field injection per bf_mode.
Redirect URI matching, issuer URL, and server config defaults
transports/bifrost-http/handlers/oauth2_utils_test.go
Tests matchRedirectURI loopback/exact/negative cases, oauth2IssuerURL configured-vs-fallback behavior, and oauth2ServerCfg default TTL population.
OAuth2 discovery endpoint tests
transports/bifrost-http/handlers/oauth2_discovery_test.go
Tests auth-mode gating (404 for Headers, 200 for OAuth/Both), PRM and AS metadata JSON fields, and JWKS single RSA key attributes.
Consent handler: flow detail, available modes, and submit tests
transports/bifrost-http/handlers/oauth2_consent_test.go
Introduces fakeResolver and helpers; tests flowDetail status/payload, availableModes under different configs, and flowSubmit for VK, session, user, and VK→user binding upgrade modes.
Token issuance handler: SQLite store, DCR, authorize, and token exchange
transports/bifrost-http/handlers/oauth2_issuance_test.go
SQLite-backed integration tests for DCR registration, authorize redirects, authorization-code token exchange with JWT verification and PKCE/expiry/single-use rejection, and refresh token rotation with family replay revocation.
Session list and revoke handler tests
transports/bifrost-http/handlers/oauth2_sessions_test.go
Tests listSessions 200/500 paths and revokeSession across vk/user mode authorization, caller-identity matching, and 403/404/400 error mapping.
MCP server auth routing: JWT and header/anon path tests
transports/bifrost-http/handlers/mcpserver_auth_test.go
Tests getMCPServerForRequest JWT-path outcomes across auth modes, enforcement toggles, JWT-vs-header precedence, header-VK behavior, anonymous access, and WWW-Authenticate setting.

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~60 minutes

Possibly related PRs

  • maximhq/bifrost#3565: Directly related to the per-user OAuth/MCP token identity and auth-mode refactor that the new TestListOauthUserTokens_IdentityExactMatch and TestListOauthUserTokens_IdentityComposesWithAuthMode tests exercise at the SQL level.
  • maximhq/bifrost#3824: Centers on ListOauthUserTokens filtering via applyMCPSessionFilters, which is the exact store method the new identity/auth-mode composition tests validate.

Suggested reviewers

  • akshaydeo
  • danpiths

Poem

🐇 Hop, hop through the OAuth maze,
Consent flows tested, tokens ablaze!
Sweep the stale ones, rotate the rest,
JWT claims put through every test.
From SQLite seeds to mock store play,
The rabbit's code is bug-free today! 🎉

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Title check ✅ Passed The title accurately and specifically summarizes the main change: comprehensive unit tests for OAuth2 issuance, JWT verification, consent, discovery, sessions, and MCP auth.
Description check ✅ Passed The description comprehensively covers all required template sections including summary, detailed changes, type of change, affected areas, test instructions, breaking changes status, security considerations, and checklist completion.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch 06-18-feat_adds_unit_tests_for_mcp_oauth_server

Warning

There were issues while running some tools. Please review the errors and either fix the tool's configuration or disable the tool if it's a critical failure.

🔧 golangci-lint (2.12.2)

level=error msg="[linters_context] typechecking error: pattern ./...: directory prefix . does not contain main module or its selected dependencies"


Comment @coderabbitai help to get the list of available commands and usage tips.

@greptile-apps

greptile-apps Bot commented Jun 18, 2026

Copy link
Copy Markdown
Contributor

Confidence Score: 5/5

Test-only PR with no production code changes; all new files are self-contained and safe to merge.

Every changed file is a new test. The tests correctly reflect the production code (verified against oauth2_jwt.go, the real store migrations, and the mock implementations), cover the security-critical JWT rejection matrix in full, and use real SQLite semantics for the atomic issuance paths. No regressions are possible since production code is untouched.

No files require special attention; all test logic is self-contained with clear seeding helpers and isolated per-subtest stores.

Important Files Changed

Filename Overview
framework/configstore/rdb_oauth2_test.go Adds SQLite-backed configstore tests for signing key stability, authorize-request state machine, single-use enforcement, expired code rejection, refresh-token rotation and replay guard, family-wide revocation, and GC sweep ordering.
framework/configstore/rdb_mcp_sessions_identity_test.go Pins the OR-group parenthesization in ListOauthUserTokens with exact identity match and cross-mode AND/OR interaction tests.
transports/bifrost-http/handlers/oauth2_jwt_test.go Defines shared test infrastructure and covers verifyMCPJWT with a full rejection matrix including alg:none, HS256, RS384, and infrastructure fault isolation.
transports/bifrost-http/handlers/oauth2_issuance_test.go Uses a real SQLite-backed store to test DCR, authorize, token exchange (PKCE mismatch, single-use, expired, client_id mismatch), and refresh token rotation/replay.
transports/bifrost-http/handlers/oauth2_consent_test.go Tests flowDetail and flowSubmit across VK, session, user, and VK-to-user upgrade binding modes. Missing explicit coverage for code_issued status in flowDetail.
transports/bifrost-http/handlers/mcpserver_auth_test.go Tests getMCPServerForRequest across JWT and header/anonymous paths with per-subtest store isolation.
transports/bifrost-http/handlers/oauth2_discovery_test.go Tests discovery gating by auth mode and verifies PRM, AS metadata, and JWKS field values.
transports/bifrost-http/handlers/oauth2_sessions_test.go Tests listSessions and revokeSession with identity-gated authorization for vk and user modes.
transports/bifrost-http/handlers/oauth2_utils_test.go Tests matchRedirectURI, oauth2IssuerURL, and oauth2ServerCfg default TTL values with table-driven coverage.

Sequence Diagram

%%{init: {'theme': 'neutral'}}%%
sequenceDiagram
    participant Client
    participant IssuanceHandler
    participant ConsentHandler
    participant MCPServerHandler
    participant Store

    Client->>IssuanceHandler: POST /oauth2/register (DCR)
    IssuanceHandler->>Store: CreateOAuth2Client
    IssuanceHandler-->>Client: 201 client_id

    Client->>IssuanceHandler: GET /oauth2/authorize
    IssuanceHandler->>Store: CreateOAuth2AuthorizeRequest (pending)
    IssuanceHandler-->>Client: 302 consent page

    Client->>ConsentHandler: "POST flowSubmit (mode=vk)"
    ConsentHandler->>Store: "ConsentOAuth2AuthorizeRequest (pending->consented)"
    ConsentHandler-->>Client: 200 redirect with code

    Client->>IssuanceHandler: POST /oauth2/token (authorization_code)
    IssuanceHandler->>Store: GetOAuth2AuthorizeRequestByCodeHash
    IssuanceHandler->>Store: "ConsumeOAuth2AuthorizeRequest (consented->code_issued)"
    IssuanceHandler-->>Client: 200 access_token + refresh_token

    Client->>MCPServerHandler: POST /mcp Bearer JWT
    MCPServerHandler->>Store: GetOAuth2SigningKey
    Note over MCPServerHandler: RS256 pin, iss, aud, exp, iat, kid
    MCPServerHandler-->>Client: MCP response

    Client->>IssuanceHandler: POST /oauth2/token (refresh_token)
    IssuanceHandler->>Store: RotateOAuth2RefreshToken
    IssuanceHandler-->>Client: 200 new token pair
Loading
%%{init: {'theme': 'base', 'themeVariables': {"darkMode": true, "background": "#0d1117", "primaryColor": "#21262d", "primaryTextColor": "#e6edf3", "primaryBorderColor": "#8b949e", "lineColor": "#8b949e", "textColor": "#e6edf3", "edgeLabelBackground": "#161b22", "actorBkg": "#21262d", "actorBorder": "#8b949e", "actorTextColor": "#e6edf3", "actorLineColor": "#8b949e", "signalColor": "#8b949e", "signalTextColor": "#e6edf3", "noteBkgColor": "#373320", "noteBorderColor": "#d4a72c", "noteTextColor": "#f0e6c0", "labelBoxBkgColor": "#21262d", "labelBoxBorderColor": "#8b949e", "labelTextColor": "#e6edf3", "loopTextColor": "#e6edf3", "activationBkgColor": "#30363d", "activationBorderColor": "#8b949e"}}}%%
sequenceDiagram
    participant Client
    participant IssuanceHandler
    participant ConsentHandler
    participant MCPServerHandler
    participant Store

    Client->>IssuanceHandler: POST /oauth2/register (DCR)
    IssuanceHandler->>Store: CreateOAuth2Client
    IssuanceHandler-->>Client: 201 client_id

    Client->>IssuanceHandler: GET /oauth2/authorize
    IssuanceHandler->>Store: CreateOAuth2AuthorizeRequest (pending)
    IssuanceHandler-->>Client: 302 consent page

    Client->>ConsentHandler: "POST flowSubmit (mode=vk)"
    ConsentHandler->>Store: "ConsentOAuth2AuthorizeRequest (pending->consented)"
    ConsentHandler-->>Client: 200 redirect with code

    Client->>IssuanceHandler: POST /oauth2/token (authorization_code)
    IssuanceHandler->>Store: GetOAuth2AuthorizeRequestByCodeHash
    IssuanceHandler->>Store: "ConsumeOAuth2AuthorizeRequest (consented->code_issued)"
    IssuanceHandler-->>Client: 200 access_token + refresh_token

    Client->>MCPServerHandler: POST /mcp Bearer JWT
    MCPServerHandler->>Store: GetOAuth2SigningKey
    Note over MCPServerHandler: RS256 pin, iss, aud, exp, iat, kid
    MCPServerHandler-->>Client: MCP response

    Client->>IssuanceHandler: POST /oauth2/token (refresh_token)
    IssuanceHandler->>Store: RotateOAuth2RefreshToken
    IssuanceHandler-->>Client: 200 new token pair
Loading

Reviews (3): Last reviewed commit: "feat: adds unit tests for mcp oauth serv..." | Re-trigger Greptile

@Pratham-Mishra04 Pratham-Mishra04 force-pushed the 06-18-feat_adds_unit_tests_for_mcp_oauth_server branch from 5e5e90a to 5ee117b Compare June 18, 2026 12:22
@Pratham-Mishra04 Pratham-Mishra04 force-pushed the 06-18-docs_adds_docs_for_mcp_oauth_server branch from 91623fa to 045411d Compare June 18, 2026 12:22
@Pratham-Mishra04 Pratham-Mishra04 force-pushed the 06-18-feat_adds_unit_tests_for_mcp_oauth_server branch from 5ee117b to ce7bb1b Compare June 18, 2026 12:47
@Pratham-Mishra04 Pratham-Mishra04 force-pushed the 06-18-docs_adds_docs_for_mcp_oauth_server branch from 045411d to 7cae97e Compare June 18, 2026 12:47
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.

2 participants