Refactor RBAC ops entity creator/upserter/purger: drop legacy element types and absorb scope membership
- Dominant language
- Python
- Stars
- 670
- Forks
- 183
- Avg merge
- 15h 13m
- Merged PRs (30d)
- 368
Description
### Motivation
The RBAC ops layer (manager/repositories/ops/rbac/provider.py) still exposes legacy RBACEntity creator/upserter/purger types that depend on RBACElementType / RBACElementRef, and keeps a method (assign_roles_to_user) whose responsibility should be covered by the member-addition path (add_bulk_members). Entity creation and virtual-scope membership are currently two separate steps (create_scoped + add_bulk_members), which callers must remember to combine.
### Required Features
1. Rename the {CRUD}_scoped() methods of RBACWriteOps to {CRUD}_entity() (create_entity, upsert_entity, bulk_create_entity(_partial), purge_entity, bulk_purge_entity_partial) and update all call sites.
1. Replace RBACElementType / RBACElementRef in RBACEntityCreator / RBACEntityUpserter / RBACEntityPurger with the types from ai.backend.common.data.entity.types (EntityType, ScopeType, ScopeRef, EntityRef), so these types are no longer legacy.
1. Add an optional membership scope field (scope + permission_cap) to the creator and upserter. When the field is non-null, the executed operation also enrolls the entity as a member of the given scope (entity membership in the scope's virtual scope, with the permission cap applied) — the same semantics as add_bulk_members. When null, behavior is unchanged. This also gives the upserter virtual-scope support, which it currently lacks.
1. Remove assign_roles_to_user(); its callers (e.g. create_full_user, consumers of ScopeCreationResult.auto_grant_role_ids) switch to the member-addition path, which already grants auto_assign roles.
### Impact
- manager/repositories/base/rbac (entity creator/upserter/purger types and executors)
- manager/repositories/ops/rbac/provider.py (RBACWriteOps)
- All repositories calling the {CRUD}_scoped methods or assign_roles_to_user (user, group, container_registry, scaling_group, replica_group, ...)
### Testing Scenarios
- Create/upsert with the membership scope set: row, scope association, and entity membership (with permission cap) are all created; idempotent on re-run.
- Create/upsert with the membership scope null: behavior identical to the current create_scoped/upsert_scoped.
- Purge/delete flows still remove RBAC entries as before.
- User provisioning (create_full_user) and scope creation flows still grant auto_assign roles without assign_roles_to_user.
JIRA Issue: BA-7262
Contributor guide
Research direction
Start in manager/repositories/ops/rbac/provider.py and the manager/repositories/base/rbac types and executors, then trace callers of the scoped methods and assign_roles_to_user, including create_full_user and ScopeCreationResult.auto_grant_role_ids. Use add_bulk_members as the existing membership path to understand the required semantics. Done means all listed call sites use the entity methods, legacy types and method are removed, and the create, upsert, purge, and auto-assignment scenarios still pass.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- python
- Domain
- authorization, backend
- Issue type
- Refactor
- Difficulty
- 5/5
- Estimated time
- Over a week
- Activity status
- Quiet
- Clarity
- Mostly clear
- Newbie friendliness
- 35/100