Skip to content

Add SetOrganizationMemberRole RPC to replace client-side policy manipulation #1459

@whoAbhishekSah

Description

@whoAbhishekSah

Problem

Changing a member's role in an org requires the SDK to do raw policy CRUD:

listPolicies → deletePolicy x N → createPolicy

Every other member operation (invite, remove, list) uses a single high-level RPC that handles policies server-side. Role change is the only one that doesn't — and it causes bugs:

  • No minimum owner check — last owner can be demoted, leaving org with zero owners
  • Non-atomic — if delete succeeds but create fails, user has zero roles
  • SDK swallows errors — React SDK uses Promise.allSettled for deletes, silently ignores PermissionDenied
  • Permission mismatch — SDK gates UI on update permission, backend checks policymanage
  • Stale UI — permissions checked once on page load, never refreshed after role changes

Proposal

Add a single RPC:

rpc SetOrganizationMemberRole(SetOrganizationMemberRoleRequest) returns (SetOrganizationMemberRoleResponse);

message SetOrganizationMemberRoleRequest {
    string org_id = 1;
    string user_id = 2;
    string role_id = 3;
}

Backend handles: validate role, check minimum owner, delete old policies, create new policy — atomically. This sits at the service layer and calls the policy service internally, same as RemoveOrganizationUser does today.

SDK goes from 3 calls to 1:

await setOrganizationMemberRole({ orgId, userId, roleId });

Goal: remove policy management from SDK

The aim is to eliminate direct policy manipulation (listPolicies, deletePolicy, createPolicy) from the SDK entirely for member management. The SDK should only work with high-level role-based RPCs:

Operation Current Target
List members listOrganizationUsers(withRoles) No change
Invite member createOrganizationInvitation(roleIds) No change
Change role listPolicies → deletePolicy x N → createPolicy setOrganizationMemberRole(orgId, userId, roleId)
Remove member removeOrganizationUser No change

This keeps the UI lean and pushes policy logic where it belongs — the server.

UpdatePolicy RPC

The proto already defines UpdatePolicy but the handler is unimplemented. It should be implemented separately as a general-purpose building block for other clients (CLI, admin scripts, custom integrations). But it operates on policy IDs and doesn't enforce business rules like minimum owner — so the SDK should use SetOrganizationMemberRole instead.

Additional fixes

  • Add minimum owner check to DeletePolicy service layer (defense in depth)
  • Fix RemoveOrganizationUser — current check doesn't handle zero-admin edge case
  • SDK: gate role-change UI on policymanage instead of update
  • SDK: refresh permissions after role changes
  • SDK: role-change dropdown missing custom org roles (listOrganizationRoles not called on members page)

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions