Problem
Service users now get an app_organization_viewer role when created (#1570), but there's no way to change that role through the API. An admin who wants to promote a service user to app_organization_manager or app_organization_owner cannot do so — the SetOrganizationMemberRole RPC only accepts user_id, hardcoded to schema.UserPrincipal.
The service layer already supports service user role changes (validated in unit tests). Only the proto + handler need updating.
What needs to change
Proto (raystack/proton): Update SetOrganizationMemberRoleRequest to accept principal_id + principal_type instead of (or in addition to) user_id.
Handler (organization.go): Pass the principal type from the request instead of hardcoding schema.UserPrincipal.
How service user membership works today
For reference, here's the current state after the membership migration:
| Operation |
How it works |
| Create |
CreateServiceUser → AddOrganizationMember(viewer) — gets policy + relation + identity link |
| Delete |
DeleteServiceUser → RemoveOrganizationMember (cascade) → bulk relation delete → DB delete |
| Role change |
Not possible via RPC — this issue |
| Remove from org |
RemoveOrganizationMember rejects app/serviceuser at the handler — callers must use DeleteServiceUser (SUs are bound to one org) |
| Add to org |
Only via CreateServiceUser — SUs are created within an org, not added to one after the fact |
References
- Parent: #1478
- Service user membership migration: #1570
Problem
Service users now get an
app_organization_viewerrole when created (#1570), but there's no way to change that role through the API. An admin who wants to promote a service user toapp_organization_managerorapp_organization_ownercannot do so — theSetOrganizationMemberRoleRPC only acceptsuser_id, hardcoded toschema.UserPrincipal.The service layer already supports service user role changes (validated in unit tests). Only the proto + handler need updating.
What needs to change
Proto (
raystack/proton): UpdateSetOrganizationMemberRoleRequestto acceptprincipal_id+principal_typeinstead of (or in addition to)user_id.Handler (
organization.go): Pass the principal type from the request instead of hardcodingschema.UserPrincipal.How service user membership works today
For reference, here's the current state after the membership migration:
CreateServiceUser→AddOrganizationMember(viewer)— gets policy + relation + identity linkDeleteServiceUser→RemoveOrganizationMember(cascade) → bulk relation delete → DB deleteRemoveOrganizationMemberrejectsapp/serviceuserat the handler — callers must useDeleteServiceUser(SUs are bound to one org)CreateServiceUser— SUs are created within an org, not added to one after the factReferences