Skip to content

fix(deleter): cascade PAT cleanup on user delete#1672

Merged
AmanGIT07 merged 3 commits into
mainfrom
fix/cascade-pat-cleanup-on-user-delete
Jun 4, 2026
Merged

fix(deleter): cascade PAT cleanup on user delete#1672
AmanGIT07 merged 3 commits into
mainfrom
fix/cascade-pat-cleanup-on-user-delete

Conversation

@AmanGIT07
Copy link
Copy Markdown
Contributor

@AmanGIT07 AmanGIT07 commented Jun 3, 2026

Summary

  • DeleteUser cascades to the user's PATs before removing the user row, cleaning policies rows and SpiceDB rolebinding tuples that were previously orphaned.
  • New userpat.Service.DeleteAllByUser reuses the existing per-PAT delete cascade.
  • New repo method ListByUser returns active PATs for a user across all orgs.

Test plan

  • go test ./core/userpat/... ./core/deleter/...
  • go test ./internal/store/postgres/...
  • make lint
  • Delete a user with PATs; confirm policies rows for those PATs are gone and no rolebinding tuples for the PATs remain in SpiceDB.

Addresses (#1660)

User delete dropped user_pats rows via ON DELETE CASCADE but left
their policies entries and SpiceDB rolebinding tuples orphaned.
DeleteUser now invokes userpat.Service.DeleteAllByUser before the
user row is removed so each PAT's authorization data is cleaned via
the existing per-PAT delete cascade.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@vercel
Copy link
Copy Markdown

vercel Bot commented Jun 3, 2026

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
frontier Ready Ready Preview, Comment Jun 3, 2026 3:02pm

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented Jun 3, 2026

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: 070c088a-733b-4f21-9d0f-5ef8bda9edb5

📥 Commits

Reviewing files that changed from the base of the PR and between 1c06840 and 1f68903.

📒 Files selected for processing (1)
  • core/userpat/service.go
🚧 Files skipped from review as they are similar to previous changes (1)
  • core/userpat/service.go

📝 Walkthrough

Summary by CodeRabbit

  • New Features

    • User deletion now automatically removes all associated Personal Access Tokens (PATs).
    • Added ability to list a user’s active PATs across organizations and bulk-delete them.
    • PAT deletion now always performs policy revocation when a token is deleted.
  • Bug Fixes

    • Cascade user deletion will stop and report an error if PAT cleanup fails.
  • Tests

    • Expanded coverage for PAT listing, bulk deletion, and cascade deletion scenarios (including error/edge cases).

Walkthrough

This PR adds Repository.ListByUser and UserPATService.DeleteAllByUser, implements Postgres ListByUser, implements DeleteAllByUser in the PAT service (and adjusts Delete), wires UserPATService into the cascade deleter (calling PAT cleanup before user deletion), updates mocks and tests, and threads the dependency through bootstrap wiring.

Changes

User PAT Cascade Deletion on Account Removal

Layer / File(s) Summary
PAT Repository ListByUser Contract and Implementation
core/userpat/userpat.go, internal/store/postgres/userpat_repository.go, core/userpat/mocks/repository.go, internal/store/postgres/userpat_repository_test.go
Adds Repository.ListByUser(ctx, userID) ([]models.PAT, error); Postgres repo implements it filtering out soft-deleted rows. Adds mock support and tests verifying active-PAT retrieval across orgs and empty results.
PAT Service DeleteAllByUser Implementation
core/userpat/service.go, core/userpat/service_test.go
Adds Service.DeleteAllByUser(ctx, userID) which lists a user’s PATs and deletes each via existing per-PAT Delete, returning the first encountered error; adjusts Delete behavior and adds tests for list-failure, empty, success, and per-token failure scenarios.
Cascade Deleter UserPATService Integration and DeleteUser Ordering
core/deleter/service.go, core/deleter/mocks/user_pat_service.go, core/deleter/service_test.go
Introduces UserPATService interface, updates NewCascadeDeleter and Service to accept/wire userPATService, calls DeleteAllByUser in DeleteUser before userService.Delete, and updates tests/mocks across cascade-delete cases to include PAT cleanup expectations and failure propagation checks.
Bootstrap Service PAT Dependency Wiring
cmd/serve.go
Passes userPATService into bootstrap.NewBootstrapService(...) call to wire the dependency during bootstrap.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Possibly related issues

Possibly related PRs

  • raystack/frontier#1446: Previously touched cmd/serve.go bootstrap wiring for PAT-related dependencies.
  • raystack/frontier#1401: Related bootstrap/service wiring changes that extended constructor arguments for PAT bootstrap plumbing.
  • raystack/frontier#1586: Also modifies cascade deleter wiring to thread additional cleanup dependencies.

Suggested reviewers

  • rohilsurana
  • whoAbhishekSah
🚥 Pre-merge checks | ✅ 2
✅ Passed checks (2 passed)
Check name Status Explanation
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.


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.

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1


ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: aac181e7-782b-4d7c-a2f1-f0728e4d65c7

📥 Commits

Reviewing files that changed from the base of the PR and between c2f9a2c and 452fbe6.

📒 Files selected for processing (10)
  • cmd/serve.go
  • core/deleter/mocks/user_pat_service.go
  • core/deleter/service.go
  • core/deleter/service_test.go
  • core/userpat/mocks/repository.go
  • core/userpat/service.go
  • core/userpat/service_test.go
  • core/userpat/userpat.go
  • internal/store/postgres/userpat_repository.go
  • internal/store/postgres/userpat_repository_test.go

Comment thread core/userpat/service.go Outdated
@coveralls
Copy link
Copy Markdown

coveralls commented Jun 3, 2026

Coverage Report for CI Build 26893496588

Coverage increased (+0.08%) to 43.236%

Details

  • Coverage increased (+0.08%) from the base build.
  • Patch coverage: 8 uncovered changes across 2 files (30 of 38 lines covered, 78.95%).
  • No coverage regressions found.

Uncovered Changes

File Changed Covered %
internal/store/postgres/userpat_repository.go 22 16 72.73%
cmd/serve.go 2 0 0.0%
Total (4 files) 38 30 78.95%

Coverage Regressions

No coverage regressions found.


Coverage Stats

Coverage Status
Relevant Lines: 38033
Covered Lines: 16444
Line Coverage: 43.24%
Coverage Strength: 12.14 hits per line

💛 - Coveralls

Both gates short-circuited the cascade user-delete path: with PATs
created while enabled and later disabled, DeleteAllByUser bailed and
user_pats rows were cascade-removed without their policies or SpiceDB
tuples. Revocation should always work regardless of feature exposure.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@AmanGIT07
Copy link
Copy Markdown
Contributor Author

Test results

  • go test ./core/userpat/... ./core/deleter/...TestService_DeleteAllByUser (5 subtests) and TestDeleteUser (2 subtests) pass
  • go test -run TestUserPATRepository/TestListByUser ./internal/store/postgres/...TestListByUser_EmptyWhenNoTokens and TestListByUser_ReturnsActivePATsAcrossOrgs pass
  • make lint — 0 issues
  • End-to-end: created user + 2 PATs, then called FrontierService/DeleteUser
    • Pre: 2 user_pats rows, 2 policies rows (principal_type=app/pat), 2 alive SpiceDB app/rolebindingapp/pat tuples
    • Post: 0 rows in user_pats, policies, users for the deleted user; both SpiceDB tuples tombstoned (deleted_xid set, no alive entries)

@rohilsurana rohilsurana self-requested a review June 4, 2026 04:33
@AmanGIT07 AmanGIT07 merged commit 6583806 into main Jun 4, 2026
8 checks passed
@AmanGIT07 AmanGIT07 deleted the fix/cascade-pat-cleanup-on-user-delete branch June 4, 2026 07:28
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.

3 participants