Revoke grants and sessions when users lose access #6

Merged
jak merged 2 commits from review/revoke-lost-access into groups-capabilities 2026-10-20 16:37:05 -04:00
Owner

Two fixes to session revocation:

  • Ended sessions when users lost their last group path. Removing a group membership, removing a group's access to an integration, or deleting a group now deletes the affected users' grants and refresh tokens for that integration in the same transaction. This applies only to users that no other group still admits. Sessions for the internal consent integration are never touched. The store contracts document the new effect.
  • Reported denied refreshes whose token was already gone. RefreshAccessToken now returns ErrAccessDenied when revoking the denied token finds it already removed, instead of ErrTokenNotFound.

Test changes: four refresh tests now register their token's integration and grant access, so they still exercise the missing or revoked token path. One test now expects grants to be deleted when access is lost.

🤖 Generated with Claude Code

Two fixes to session revocation: - **Ended sessions when users lost their last group path.** Removing a group membership, removing a group's access to an integration, or deleting a group now deletes the affected users' grants and refresh tokens for that integration in the same transaction. This applies only to users that no other group still admits. Sessions for the internal `consent` integration are never touched. The store contracts document the new effect. - **Reported denied refreshes whose token was already gone.** `RefreshAccessToken` now returns `ErrAccessDenied` when revoking the denied token finds it already removed, instead of `ErrTokenNotFound`. Test changes: four refresh tests now register their token's integration and grant access, so they still exercise the missing or revoked token path. One test now expects grants to be deleted when access is lost. 🤖 Generated with [Claude Code](https://claude.com/claude-code)
When a refresh was denied for lost access, we revoked its token. If the token
had already been removed, for example by a concurrent refresh, the caller got
ErrTokenNotFound instead of ErrAccessDenied. A missing token now counts as
revoked, and the refresh reports the denial.

Four refresh tests used tokens for unregistered audiences, so they reached the
denial branch and relied on the old error. We registered the integration and
granted the user access, so they still check that a missing or revoked token
is rejected with ErrTokenNotFound.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Removing a membership, removing a group's access to an integration, or deleting
a group could leave users with no way to reach an integration. Their scope
grants and refresh tokens stayed in place. Sessions only ended at the next
refresh, and regained access skipped the consent screen.

Each of these operations now deletes those grants and refresh tokens in the
same transaction, but only for users that no other group still admits. The
Consent integration's sessions are never touched, since users reach it without
groups.

One refresh test asserted that grants survived lost access. It now checks that
they are gone.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
jak force-pushed review/revoke-lost-access from 6ea1a4d8b0 to 379e596ef1 2026-10-20 16:17:06 -04:00 Compare
jak force-pushed review/revoke-lost-access from 379e596ef1 to 76d9230adf 2026-10-20 16:35:07 -04:00 Compare
jak merged commit 76d9230adf into groups-capabilities 2026-10-20 16:37:05 -04:00
Sign in to join this conversation.
No reviewers
No labels
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
pollinator/consent!6
No description provided.