Skip to content

fix: microsoft and google connector OAuth JWT validation#1907

Open
rodageve wants to merge 3 commits into
mainfrom
fix/sonarcube_jwt_validation_findings_jun10
Open

fix: microsoft and google connector OAuth JWT validation#1907
rodageve wants to merge 3 commits into
mainfrom
fix/sonarcube_jwt_validation_findings_jun10

Conversation

@rodageve

@rodageve rodageve commented Jun 16, 2026

Copy link
Copy Markdown
Collaborator

Security: Add JWT Signature Verification for OAuth Tokens

Summary

Implements full JWT signature verification for Google and Microsoft OAuth tokens to address three critical SonarQube security findings (python:S5659). All JWT tokens are now cryptographically validated.

Security Issues Fixed

  • S5659 - google_drive_acl.py:66 - Google ID token decoded without signature verification
  • S5659 - microsoft_graph_acl.py:32 - Microsoft access token decoded without signature verification
  • S5659 - microsoft_graph_acl.py:211 - Microsoft access token decoded without signature verification

Changes

New Files

  • src/utils/jwt_verification.py - JWT verification utility with JWKS caching

Modified Files

  • src/config/settings.py - Added MICROSOFT_GRAPH_OAUTH_CLIENT_ID configuration
  • src/connectors/google_drive_acl.py - Updated _email_from_id_token() with signature verification
  • src/connectors/microsoft_graph_acl.py - Updated tenant_id_from_access_token() and _decode_microsoft_user_identifiers() with signature verification

Security Improvements

All JWT tokens now undergo full validation:

  • ✅ Cryptographic signature verification (RSA-256)
  • ✅ Expiration validation
  • ✅ Issuer validation
  • ✅ Audience validation

Prevents:

  • Token forgery and tampering
  • Replay attacks with expired tokens
  • Token substitution attacks
  • Cross-tenant access violations

Summary by CodeRabbit

  • New Features

    • Added support for Microsoft Graph OAuth client ID and secret via environment-backed configuration
  • Security & Authentication

    • Improved Google ID token handling to verify signatures, audience, and issuer before using email claims
    • Improved Microsoft access token handling to verify signatures, expiration, audience, and issuer (including tenant-aware issuer validation)
    • Added centralized JWT verification with JWKS lookup and cached key retrieval, plus better failure handling and logging

@github-actions github-actions Bot added the backend 🔷 Issues related to backend services (OpenSearch, Langflow, APIs) label Jun 16, 2026
@coderabbitai

coderabbitai Bot commented Jun 16, 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

Run ID: 9f74cc44-25bf-45ea-a372-9021949e0b6a

📥 Commits

Reviewing files that changed from the base of the PR and between 87e7c96 and 10abb2e.

📒 Files selected for processing (3)
  • src/connectors/google_drive_acl.py
  • src/connectors/microsoft_graph_acl.py
  • src/utils/jwt_verification.py
💤 Files with no reviewable changes (2)
  • src/connectors/microsoft_graph_acl.py
  • src/connectors/google_drive_acl.py
🚧 Files skipped from review as they are similar to previous changes (1)
  • src/utils/jwt_verification.py

Walkthrough

Adds src/utils/jwt_verification.py with a TTL-cached JWKS fetcher, RSA signing-key resolver, custom exception hierarchy, and two public verifiers (verify_google_id_token, verify_microsoft_access_token). Updates _email_from_id_token in google_drive_acl.py and both tenant_id_from_access_token/_decode_microsoft_user_identifiers in microsoft_graph_acl.py to use these verifiers instead of unverified jwt.decode. Adds two Microsoft Graph OAuth environment settings.

Changes

JWT Signature Verification for OAuth Tokens

Layer / File(s) Summary
JWT verification utility: core infrastructure
src/utils/jwt_verification.py
Introduces the module with imports, a TTL-bounded JWKS cache, and JWKS URL constants for Google and Microsoft. Defines JWTVerificationError base exception and subclasses (InvalidSignatureError, ExpiredTokenError, InvalidAudienceError, InvalidIssuerError). Implements _fetch_jwks (cache-first HTTP fetch with timeout) and _get_signing_key (extracts kid from JWT header, selects matching JWK, and converts to RSA public key).
JWT verification utility: public verifiers and cache clearing
src/utils/jwt_verification.py
Implements verify_google_id_token (RS256 + audience/issuer validation with exception mapping) and verify_microsoft_access_token (RS256 + audience/issuer + tenant-aware issuer-prefix validation). Adds clear_jwks_cache for test support.
Google Drive ACL: integrate Google token verification
src/connectors/google_drive_acl.py
Updates _email_from_id_token to call verify_google_id_token with GOOGLE_OAUTH_CLIENT_ID, validates config presence, extracts the verified email claim, and logs verification failures appropriately. Removes unused jwt import.
Microsoft Graph ACL: integrate Microsoft token verification and settings
src/config/settings.py, src/connectors/microsoft_graph_acl.py
Adds MICROSOFT_GRAPH_OAUTH_CLIENT_ID and MICROSOFT_GRAPH_OAUTH_CLIENT_SECRET environment-backed settings. Updates tenant_id_from_access_token and _decode_microsoft_user_identifiers to call verify_microsoft_access_token with client ID and tenant ID, validate config presence, and log verification failures with fallback behavior. Removes unused jwt import from microsoft_graph_acl.py.

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Suggested reviewers

  • mfortman11
  • ricofurtado
🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The pull request title accurately summarizes the main objective: implementing JWT signature validation for OAuth tokens in both Microsoft and Google connectors to fix security issues.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.
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 fix/sonarcube_jwt_validation_findings_jun10

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

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

@rodageve rodageve changed the title Microsoft and google connector OAuth JWT validation fix: microsoft and google connector OAuth JWT validation Jun 16, 2026
@github-actions github-actions Bot added the bug 🔴 Something isn't working. label Jun 16, 2026
@github-actions github-actions Bot added bug 🔴 Something isn't working. and removed bug 🔴 Something isn't working. labels Jun 16, 2026

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 3

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (2)
src/connectors/google_drive_acl.py (1)

8-8: ⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Remove unused jwt import.

The jwt module is no longer used directly after refactoring to use verify_google_id_token.

🔧 Proposed fix
-import jwt
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/connectors/google_drive_acl.py` at line 8, Remove the unused `import jwt`
statement from the imports section of the file. The jwt module is no longer
needed since the code has been refactored to use verify_google_id_token instead
of jwt operations.

Source: Pipeline failures

src/connectors/microsoft_graph_acl.py (1)

9-9: ⚠️ Potential issue | 🟡 Minor

Remove the unused jwt import.

The jwt module is imported on line 9 but never used directly in this file. Token verification is handled through verify_microsoft_access_token from utils.jwt_verification, making the top-level jwt import unnecessary.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/connectors/microsoft_graph_acl.py` at line 9, The jwt module is imported
at the top of the file but is never used directly since token verification is
handled through the verify_microsoft_access_token function imported from
utils.jwt_verification. Remove the unused import statement `import jwt` from the
file to clean up the imports and eliminate the unnecessary dependency.
🧹 Nitpick comments (1)
src/utils/jwt_verification.py (1)

246-252: 💤 Low value

verify_iss=True has no effect without an issuer argument.

PyJWT requires the issuer parameter to actually validate the issuer claim. Setting verify_iss=True without passing issuer results in no validation. The manual check at lines 255-262 does validate correctly, but the option here is misleading.

Either remove verify_iss: True from options (since validation is manual), or pass a validator. For Microsoft tokens where the issuer varies by tenant, the manual check is appropriate.

🔧 Suggested clarification
             options={
                 "verify_signature": True,
                 "verify_exp": True,
                 "verify_aud": True,
-                "verify_iss": True,
+                "verify_iss": False,  # Validated manually below due to tenant-specific issuers
             },
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/utils/jwt_verification.py` around lines 246 - 252, The `verify_iss: True`
option in the options dictionary passed to jwt.decode() has no effect without an
accompanying `issuer` parameter, making it misleading. Since the code performs
manual issuer validation in the subsequent check (lines 255-262), which is
appropriate for Microsoft tokens with tenant-specific issuers, remove the
`verify_iss: True` entry from the options dictionary to accurately reflect that
issuer validation is being handled manually rather than by PyJWT's built-in
mechanism.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@src/utils/jwt_verification.py`:
- Around line 84-86: The exception raised in the except block at lines 84-86 and
also at lines 120-121 is missing exception chaining. Modify both raise
statements to use the `from e` syntax (e.g., `raise
JWTVerificationError(f"Failed to fetch JWKS: {e}") from e`) to preserve the
original exception traceback and maintain the exception chain for better
debugging context.
- Around line 267-283: Add `from e` to all exception re-raise statements in the
jwt_verification.py exception handling block to preserve exception chains for
proper traceback debugging. Specifically, modify the raise statements for
InvalidSignatureError, ExpiredTokenError, InvalidAudienceError,
InvalidIssuerError, and JWTVerificationError to use the syntax `raise
CustomError(...) from e` instead of `raise CustomError(...)`. This ensures the
original exception context is maintained throughout the pipeline for better
error investigation.
- Around line 176-192: The exception re-raises in the JWT verification error
handling block are not preserving the exception chain, which is required by the
pipeline linting standards. Add `from e` to each of the raise statements for
InvalidSignatureError, ExpiredTokenError, InvalidAudienceError,
InvalidIssuerError, and JWTVerificationError to maintain the full traceback
chain. This allows the original exception context to be preserved for better
debugging.

---

Outside diff comments:
In `@src/connectors/google_drive_acl.py`:
- Line 8: Remove the unused `import jwt` statement from the imports section of
the file. The jwt module is no longer needed since the code has been refactored
to use verify_google_id_token instead of jwt operations.

In `@src/connectors/microsoft_graph_acl.py`:
- Line 9: The jwt module is imported at the top of the file but is never used
directly since token verification is handled through the
verify_microsoft_access_token function imported from utils.jwt_verification.
Remove the unused import statement `import jwt` from the file to clean up the
imports and eliminate the unnecessary dependency.

---

Nitpick comments:
In `@src/utils/jwt_verification.py`:
- Around line 246-252: The `verify_iss: True` option in the options dictionary
passed to jwt.decode() has no effect without an accompanying `issuer` parameter,
making it misleading. Since the code performs manual issuer validation in the
subsequent check (lines 255-262), which is appropriate for Microsoft tokens with
tenant-specific issuers, remove the `verify_iss: True` entry from the options
dictionary to accurately reflect that issuer validation is being handled
manually rather than by PyJWT's built-in mechanism.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 51730932-d615-4451-83cf-40e3164e6f8f

📥 Commits

Reviewing files that changed from the base of the PR and between 89e0400 and 87e7c96.

📒 Files selected for processing (4)
  • src/config/settings.py
  • src/connectors/google_drive_acl.py
  • src/connectors/microsoft_graph_acl.py
  • src/utils/jwt_verification.py

Comment thread src/utils/jwt_verification.py Outdated
Comment thread src/utils/jwt_verification.py Outdated
Comment thread src/utils/jwt_verification.py Outdated
@github-actions github-actions Bot added bug 🔴 Something isn't working. and removed bug 🔴 Something isn't working. labels Jun 16, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

backend 🔷 Issues related to backend services (OpenSearch, Langflow, APIs) bug 🔴 Something isn't working.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant