Skip to content

fix(auth): revoke OIDC sessions on user access changes - #555

Merged
hedhoud merged 1 commit into
linagora:refactor/hexagonalfrom
hedhoud:fix/486-revoke-oidc-sessions
Jun 24, 2026
Merged

fix(auth): revoke OIDC sessions on user access changes#555
hedhoud merged 1 commit into
linagora:refactor/hexagonalfrom
hedhoud:fix/486-revoke-oidc-sessions

Conversation

@hedhoud

@hedhoud hedhoud commented Jun 24, 2026

Copy link
Copy Markdown
Collaborator

Why

#486 is an incident-response gap: changing a user's access should not leave their existing browser session alive until it naturally expires.

The refactor branch already had the persistence method to revoke OIDC sessions by user, but the user-management flow was not calling it.

What changed

This wires the revocation into the two access-change paths that matter here:

  • rotating a user's API token
  • demoting an admin user back to a regular user

Regular profile edits keep the current behavior and do not revoke sessions.

Closes #486.

Summary by CodeRabbit

  • New Features

    • Regenerating a user token now revokes the user’s active OIDC sessions.
    • Updating a user from admin to non-admin now revokes that user’s active OIDC sessions.
  • Bug Fixes

    • Improved missing-user handling during user updates to prevent silent failures.
    • Logging now includes the number of revoked OIDC sessions for clearer auditing.
  • Tests

    • Added and extended unit tests to verify session revocation delegation and behavior.

@coderabbitai

coderabbitai Bot commented Jun 24, 2026

Copy link
Copy Markdown

Review Change Stack

Warning

Review limit reached

@hedhoud, we couldn't start this review because you've reached your PR review rate limit.

More reviews will be available in 36 minutes and 54 seconds. Learn how PR review limits work.

Your organization has used up its prepaid credits, and credit purchases are no longer available. Enable the review add-on in the billing tab to keep reviews running — you're only billed for reviews past your plan's rate limits ($0.25/file).

⌛ How to resolve this issue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based credits.

🚦 How do rate limits work?

CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability.

For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window.

Please see our Fair Usage Limits Policy for further information.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 2b6f42a6-590c-41f4-9455-4e26524f2cab

📥 Commits

Reviewing files that changed from the base of the PR and between 0af189a and 49a0104.

📒 Files selected for processing (4)
  • openrag/services/orchestrators/auth_service.py
  • openrag/services/orchestrators/user_service.py
  • tests/unit/services/orchestrators/test_auth_service.py
  • tests/unit/services/orchestrators/test_user_service.py
📝 Walkthrough

Walkthrough

Adds OIDC session revocation to AuthService, calls it during token regeneration, and conditionally calls it during user updates when admin status is removed. Tests cover delegation and the affected user-service paths.

Changes

OIDC Session Revocation on Token Regeneration and Admin Demotion

Layer / File(s) Summary
AuthService revocation method and test
openrag/services/orchestrators/auth_service.py, tests/unit/services/orchestrators/test_auth_service.py
Adds revoke_oidc_sessions_by_user, which delegates to the session repository, logs the revoked count, and returns it. The auth service test fake records revoked users, and a new unit test verifies delegation and return value.
UserService revocation flow and tests
openrag/services/orchestrators/user_service.py, tests/unit/services/orchestrators/test_user_service.py
regenerate_token now revokes sessions before regenerating the token. update_user now reads the existing user, revokes sessions only on admin demotion, and logs the revoked-session count. Test doubles and unit tests cover revocation on regeneration, revocation on demotion, and no revocation for other updates.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Poem

🐇 Hop hop, the sessions take flight,
When tokens refresh or admins lose height.
The burrow keeps watch, the counts all align,
No stale OIDC shells left behind.

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 7.41% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly summarizes the main change: revoking OIDC sessions when user access changes.
Linked Issues check ✅ Passed The PR adds user-scoped OIDC session revocation and calls it from token regeneration and admin demotion, matching #486.
Out of Scope Changes check ✅ Passed The changes stay focused on OIDC session revocation, related update flow adjustments, and supporting tests.

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

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

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.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Caution

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

⚠️ Outside diff range comments (1)
openrag/services/orchestrators/user_service.py (1)

185-193: 🔒 Security & Privacy | 🟠 Major | 🏗️ Heavy lift

Make the access change and OIDC revocation atomic.

Line 190 and Lines 204-210 apply the user mutation before revoking browser sessions. If revoke_oidc_sessions_by_user() throws after regenerate_user_token() / update_user() has already committed, the API returns an error but the security-sensitive change is only half applied, leaving existing OIDC sessions alive. That reintroduces the exact gap this PR is meant to close for incident-response flows.

Wrap the user-row update and revoke_by_user in one transaction/unit-of-work, or add a compensating rollback before surfacing the error.

Also applies to: 194-210

🤖 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 `@openrag/services/orchestrators/user_service.py` around lines 185 - 193, The
token regeneration flow in user_service’s regenerate_token and the related
update path are not atomic because the user mutation happens before
revoke_oidc_sessions_by_user/revoke_by_user, so a failure leaves the access
change committed while sessions remain active. Update the user-row change and
OIDC/session revocation to run in one transaction or unit-of-work, or add a
rollback/compensating undo if revocation fails, so the security-sensitive
operations in UserService and _auth_service stay consistent.
🤖 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.

Outside diff comments:
In `@openrag/services/orchestrators/user_service.py`:
- Around line 185-193: The token regeneration flow in user_service’s
regenerate_token and the related update path are not atomic because the user
mutation happens before revoke_oidc_sessions_by_user/revoke_by_user, so a
failure leaves the access change committed while sessions remain active. Update
the user-row change and OIDC/session revocation to run in one transaction or
unit-of-work, or add a rollback/compensating undo if revocation fails, so the
security-sensitive operations in UserService and _auth_service stay consistent.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 8f64ea8b-d140-48a6-a41c-5fc74a37d81a

📥 Commits

Reviewing files that changed from the base of the PR and between 212cb99 and 255a449.

📒 Files selected for processing (4)
  • openrag/services/orchestrators/auth_service.py
  • openrag/services/orchestrators/user_service.py
  • tests/unit/services/orchestrators/test_auth_service.py
  • tests/unit/services/orchestrators/test_user_service.py

@hedhoud
hedhoud force-pushed the fix/486-revoke-oidc-sessions branch from 255a449 to 0af189a Compare June 24, 2026 09:11
@hedhoud

hedhoud commented Jun 24, 2026

Copy link
Copy Markdown
Collaborator Author

Addressed the valid consistency issue.

The revocation now happens before the access mutation, so a revocation failure no longer leaves a rotated token or admin demotion committed while old OIDC browser sessions remain active. This keeps the flow fail-closed without adding a larger cross-repository unit-of-work in this PR.

I also added ordering coverage around token regeneration and admin demotion.

@hedhoud hedhoud added the security Security issue label Jun 24, 2026
@hedhoud
hedhoud force-pushed the fix/486-revoke-oidc-sessions branch from 0af189a to 49a0104 Compare June 24, 2026 09:27

@Ahmath-Gadji Ahmath-Gadji left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

LGTM.
Revocation works.
I haven't tested it though with the new admin-ui to see the consequences on front

@hedhoud
hedhoud merged commit 6b9b5f5 into linagora:refactor/hexagonal Jun 24, 2026
6 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

security Security issue

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants