Skip to content

fix(deleter): user delete removes every policy the user holds - #2022

Merged
AmanGIT07 merged 2 commits into
mainfrom
fix/user-delete-removes-every-policy
Oct 27, 2026
Merged

AmanGIT07 merged 2 commits into
mainfrom
fix/user-delete-removes-every-policy

Conversation

@AmanGIT07

Copy link
Copy Markdown
Contributor

Summary

DeleteUser now deletes every live policy the user holds before it deletes the user. Before, it only removed the user from the orgs where it held an org-level policy, so these policies stayed live and kept naming a user that no longer exists:

  • a policy on a disabled project;
  • the group member policy on a disabled group;
  • a policy on a project in an org where the user has no org-level policy (CreatePolicy does not check org membership);
  • a policy on a resource inside a disabled project;
  • policies left by an earlier attempt that failed partway. The org policy is deleted first, so a retry no longer visits that org.

Changes

  • core/deleter/service.go: after the org removals, DeleteUser calls RemovePrincipalPolicies for the user, before it deletes the PATs and the user. A failure stops the delete and leaves the user in place; a retry deletes the rest.
  • core/deleter/mocks/membership_service.go: regenerated for the new interface method.

Technical Details

  • membership.Service.RemovePrincipalPolicies lists the live policies by principal, on any resource type and in any org, and deletes each one with policy.Service.Delete: the role binding relations first, then the row. The service user delete uses the same call.
  • The org removals stay, so each org still gets its member-removed audit record. ForceRemoveOrganizationMember is unchanged.
  • The leftover policies granted no access, because user.Service.Delete already removes every relation whose subject is the user, which includes each policy's bearer relation. They still showed in ListPolicies and GetPolicy.

Test Plan

  • core/deleter/service_test.go TestDeleteUser: the user is removed from each org, then its remaining policies are deleted, then its PATs, then the user. An org removal failure stops the delete before the policy step, and a policy step failure stops it before the PATs and the user. The cases fail without the policy step, with its error only logged, or with it after the PAT step.
  • e2e TestUserDeleteLeavesNoAccessAndNoLivePolicy: a user holds policies on an org, a disabled project, a disabled group, a project in another org, and an order inside the disabled project. After DeleteUser, no live policy names the user (checked per resource in the database and with ListPolicies), the user can get none of them, and ListOrganizationUsers names the user in neither users nor role_pairs. Without the policy step, the policies on the disabled project, the disabled group, the other org's project and the order stay live.
  • go test ./core/deleter/... passes.
  • go test ./test/e2e/... passes.
  • golangci-lint run ./core/deleter/... ./test/e2e/regression/... reports no issues.

DeleteUser deletes every live policy of the user after the org removals and before the PATs and the user row. Policies on disabled projects and groups, on projects in orgs where the user has no org-level policy, and on resources in disabled projects stayed live before.
@vercel

vercel Bot commented Oct 25, 2026 •

Copy link
Copy Markdown

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

Project Deployment Actions Updated
frontier Ready Ready Preview Oct 27, 2026 10:15am UTC

@coderabbitai

coderabbitai Bot commented Oct 25, 2026 •

Copy link
Copy Markdown
Contributor

Review in Change Stack →

No actionable comments were generated in the recent review.

Recent review info
Run configuration
Commits

Reviewing files that changed from the base of the PR and between 08ae2bc and 8993025.

Files selected for processing: 2
  • core/membership/service.go
  • core/membership/service_test.go

Included review availability: This review used your included allowance. Your plan provides up to 2 included reviews per hour; 0 remain after this review.

📝 Summary

Summary by CodeRabbit

  • Bug Fixes
    • Deleting a user now also removes their remaining access policies, including policies for resources outside their organization memberships.
    • If organization removal or policy cleanup fails, deletion stops before removing the user’s personal access tokens or account.
    • Policy cleanup now succeeds when a policy has already been removed, while still reporting other cleanup errors.

User deletion now removes principal policies after organization memberships and before personal access tokens. Policy cleanup treats already-absent policies as success. Unit and end-to-end tests cover deletion order, failures, remaining policies, and resource access.

Changes: User deletion policy cleanup

Layer / File(s) Summary
Policy cleanup contract and implementation
core/deleter/service.go, core/deleter/mocks/membership_service.go, core/membership/service.go, core/membership/service_test.go
MembershipService adds RemovePrincipalPolicies. Policy deletion treats policy.ErrNotExist as success. The mock and membership test cover the new operation.
Deletion flow and unit coverage
core/deleter/service.go, core/deleter/service_test.go
DeleteUser removes principal policies after organization membership removal and before personal access token cleanup. Unit tests cover this order and verify that errors stop later deletion steps.
End-to-end deletion regression
test/e2e/regression/api_test.go
The regression test checks that user deletion removes live policies and resource access, and removes the user from organization users and role pairs.

Priority: Normal

Estimated code review effort: 3 (Moderate) | ~20 minutes

Change: Bug fix

Suggested reviewers: whoabhisheksah

Merge Risk: Minimal · up to 89930

No merge-blocking issue was identified in the policy cleanup or user-deletion flow.

Pre-merge checks: Passed 2
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.
  • Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

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.

@coveralls

coveralls commented Oct 25, 2026 •

Copy link
Copy Markdown

Coverage Report for CI Build 40487021232

Warning

Build has drifted: This PR's base is out of sync with its target branch, so coverage data may include unrelated changes.
Quick fix: rebase this PR. Learn more →

Coverage increased (+0.02%) to 55.746%

Details

  • Coverage increased (+0.02%) from the base build.
  • Patch coverage: 4 of 4 lines across 2 files are fully covered (100%).
  • 68 coverage regressions across 2 files.

Uncovered Changes

No uncovered changes found.

Coverage Regressions

68 previously-covered lines in 2 files lost coverage.

File Lines Losing Coverage Coverage
internal/api/v1beta1connect/organization.go 36 63.35%
internal/store/postgres/organization_repository.go 32 79.31%

Coverage Stats

Coverage Status
Relevant Lines: 41940
Covered Lines: 23380
Line Coverage: 55.75%
Coverage Strength: 19.51 hits per line

💛 - Coveralls

@rohilsurana rohilsurana left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

The comment on DeleteUser (core/deleter/service.go:557) says the org loop is there so userService.Delete does not leave policy rows behind. The new policy step does that now, so please update or drop that comment.

Comment thread core/deleter/service.go Resolved
removePoliciesByFilter stopped at a policy that someone else deleted between the list and the delete, so a user, service user or PAT delete failed until it was retried. It now skips a policy that is already gone, like the other delete loops.
@AmanGIT07
AmanGIT07 merged commit 977eaee into main Oct 27, 2026
8 checks passed
@AmanGIT07
AmanGIT07 deleted the fix/user-delete-removes-every-policy branch October 27, 2026 11:48

This branch was successfully deployed

1 active deployment
Preview — 89930252 Deployed Oct 27, 2026 by vercel[bot]
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