Skip to content

feat: enforce PAT scope intersection on ByCurrentUser queries#1447

Merged
AmanGIT07 merged 1 commit intomainfrom
feat/pat-scope-listbyuser
Mar 13, 2026
Merged

feat: enforce PAT scope intersection on ByCurrentUser queries#1447
AmanGIT07 merged 1 commit intomainfrom
feat/pat-scope-listbyuser

Conversation

@AmanGIT07
Copy link
Contributor

@AmanGIT07 AmanGIT07 commented Mar 12, 2026

Description

When a request is authenticated via a Personal Access Token (PAT), the *ByCurrentUser RPCs (ListOrganizationsByCurrentUser, ListCurrentUserGroups, ListProjectsByCurrentUser) now enforce the PAT's resource scope. The ListByUser service methods resolve the PAT to its underlying user for SpiceDB lookups, then intersect the results with the PAT's scoped resources — returning only what's accessible by both the user and the PAT.

Changes

  • Add ResolveSubject() method on authenticate.Principal that resolves PAT principals to their underlying user ID and type.
  • Update organization.ListByUser to resolve PAT to user, then intersect results with PAT.OrgID.
  • Update group.ListByUser to resolve PAT to user, then intersect with PAT's group scope via a second LookupResources call. Signature changed from (principalID, principalType
    string) to (principal authenticate.Principal).
  • Update project.ListByUser with the same signature change and PAT scope intersection. Extract listNonInheritedProjectIDs helper for the NonInherited code path.
  • Add intersectPATScope private helper to group and project services to encapsulate the PAT scope lookup + intersection pattern.
  • Update all interfaces (4) and callers (6) across v1beta1connect, invitation, and project packages to match new signatures.

Tests

  • Manual test done by calling the respective ByCurrentUser RPCs and verifying result only contains the intersection items.
  • All existing unit tests updated and passing across all affected packages.
  • e2e tests passing.

@vercel
Copy link

vercel bot commented Mar 12, 2026

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

Project Deployment Actions Updated (UTC)
frontier Ready Ready Preview, Comment Mar 12, 2026 10:41am

@coderabbitai
Copy link

coderabbitai bot commented Mar 12, 2026

📝 Walkthrough

Summary by CodeRabbit

  • Bug Fixes

    • Fixed Personal Access Token (PAT) scope enforcement for groups, projects, and organizations to ensure tokens can only access resources within their granted permissions.
  • Improvements

    • Improved principal identity resolution for more consistent authorization behavior across different authentication methods.

Walkthrough

The PR refactors principal handling by introducing a ResolveSubject() method on the Principal type to normalize PAT-backed principals to their underlying user, and updates service method signatures to accept a single Principal parameter instead of separate ID and type strings. PAT scope intersection logic is added to restrict results based on PAT-based permissions.

Changes

Cohort / File(s) Summary
Core Authentication
core/authenticate/authenticate.go
Adds ResolveSubject() method to Principal type that returns underlying user ID and type for PAT-backed principals, normalizing subject resolution.
Group & Organization Services
core/group/service.go, core/organization/service.go
Updates ListByUser signature from separate principalID/principalType strings to single Principal parameter. Adds PAT scope intersection logic to filter results by PAT-based permissions. Derives subjectID/subjectType from resolved principal.
Project Service
core/project/service.go
Updates ListByUser signature to accept Principal instead of separate strings. Adds listNonInheritedProjectIDs and intersectPATScope helpers. Refactors logic to resolve subject from principal and filter results by PAT scope.
Service Tests
core/group/service_test.go, core/organization/service_test.go, core/project/service_test.go
Adds test coverage for PAT principal resolution, PAT scope intersection with user memberships, and regular principal handling. Introduces PAT model imports and mock service setups.
Interface Definitions
internal/api/v1beta1connect/interfaces.go
Updates GroupService and ProjectService interface method signatures for ListByUser to accept Principal instead of separate principalId/principalType parameters.
API Layer Call Sites
internal/api/v1beta1connect/user.go, internal/api/v1beta1connect/serviceuser.go
Updates all ListByUser call sites to pass composite authenticate.Principal object with ID and Type instead of separate string parameters. Affects ListUserGroups, ListCurrentUserGroups, ListProjectsByUser, and ListProjectsByCurrentUser handlers.
API Tests
internal/api/v1beta1connect/user_test.go, internal/api/v1beta1connect/serviceuser_test.go
Updates test expectations and mock setup to pass authenticate.Principal objects instead of raw user ID strings when calling ListByUser.
Service Interface
core/invitation/service.go
Updates GroupService interface definition and call site in Service.Accept to use Principal parameter instead of separate principalID/principalType strings.
Mock Services
core/invitation/mocks/group_service.go, core/project/mocks/group_service.go, internal/api/v1beta1connect/mocks/group_service.go, internal/api/v1beta1connect/mocks/project_service.go
Updates all ListByUser mock method signatures, type assertions, and call handlers to accept authenticate.Principal instead of separate string parameters. Updates Run/RunAndReturn signatures and internal dispatch logic.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Possibly related PRs

  • PR #1401: Introduces PAT support with PATPrincipal, PAT schema, and PAT service wiring—this PR builds on that foundation by updating ListByUser flows to handle PAT-backed principals and implement PAT scope intersection logic.

Suggested reviewers

  • rohilsurana

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.

@coveralls
Copy link

Pull Request Test Coverage Report for Build 22997983984

Details

  • 81 of 104 (77.88%) changed or added relevant lines in 7 files are covered.
  • 1 unchanged line in 1 file lost coverage.
  • Overall coverage increased (+0.2%) to 40.523%

Changes Missing Coverage Covered Lines Changed/Added Lines %
core/invitation/service.go 0 3 0.0%
core/group/service.go 17 21 80.95%
core/authenticate/authenticate.go 0 5 0.0%
core/project/service.go 47 58 81.03%
Files with Coverage Reduction New Missed Lines %
core/project/service.go 1 76.45%
Totals Coverage Status
Change from base Build 22947180652: 0.2%
Covered Lines: 14075
Relevant Lines: 34733

💛 - Coveralls

Copy link

@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: 3

🧹 Nitpick comments (1)
core/project/service_test.go (1)

601-603: Add a non-empty group case to this PAT + NonInherited test.

Returning []group.Group{} here means this scenario only covers direct user policies. It still doesn't pin the new branch where non-inherited project IDs come from the resolved user's group memberships and are intersected with PAT scope afterward, so a regression there would still pass.


ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: fd1b06f2-940c-445d-8eca-7d1b3116a4fb

📥 Commits

Reviewing files that changed from the base of the PR and between 53fbdbe and 7722551.

📒 Files selected for processing (17)
  • core/authenticate/authenticate.go
  • core/group/service.go
  • core/group/service_test.go
  • core/invitation/mocks/group_service.go
  • core/invitation/service.go
  • core/organization/service.go
  • core/organization/service_test.go
  • core/project/mocks/group_service.go
  • core/project/service.go
  • core/project/service_test.go
  • internal/api/v1beta1connect/interfaces.go
  • internal/api/v1beta1connect/mocks/group_service.go
  • internal/api/v1beta1connect/mocks/project_service.go
  • internal/api/v1beta1connect/serviceuser.go
  • internal/api/v1beta1connect/serviceuser_test.go
  • internal/api/v1beta1connect/user.go
  • internal/api/v1beta1connect/user_test.go

@AmanGIT07 AmanGIT07 changed the title feat: enforce PAT scope intersection on ListByUser queries feat: enforce PAT scope intersection on ByCurrentUser queries Mar 12, 2026
@AmanGIT07 AmanGIT07 merged commit 79323c0 into main Mar 13, 2026
8 checks passed
@AmanGIT07 AmanGIT07 deleted the feat/pat-scope-listbyuser branch March 13, 2026 06:54
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