Admin CLI/SDK/API for role permission management (add/remove/replace)
- Dominant language
- Python
- Stars
- 670
- Forks
- 183
- Avg merge
- 15h 13m
- Merged PRs (30d)
- 368
Description
## Background
Roles can end up with incomplete permission rows on a Backend.AI deployment when the seed fixture or a data migration omits entries for one or more entity types. BA-5722 is a recent example — fresh installs leave the `permissions` table without rows for `session`, `agent`, `image`, `keypair`, `container_registry`, `resource_group`, `artifact`, `artifact_registry`, `app_config`, `notification_channel`, `notification_rule`, `model_deployment`, `model_card`, blocking non-superadmin users from basic operations. Today the only recovery options are raw SQL or fixture re-population, both of which are error-prone and blunt.
## Goal
Provide an admin-facing API/SDK/CLI to manage permissions on a specific role with bulk operations:
- \***add**\* — add the standard operation set for one or more entity types to a role, deriving the (scope_type, scope_id) and the operation set from the role's existing rows and the canonical session-migration rule.
- \***remove**\* — remove all permission rows for one or more entity types from a role.
- \***replace**\* — replace the role's entire permission set with a JSON payload (typically extracted from a fixture).
## Scope
- \***API**\*: REST v2 endpoints under `/admin/rbac/role/{role_id}/permissions` (or equivalent).
- \***SDK**\*: typed v2 client methods.
- \***CLI**\*: `./bai admin rbac role permission add | remove | replace`.
## Behavior
- Role identification: UUID by default; `--by-name ` option for human-friendly use.
- Operation derivation rule (for `add`), aligned with BEP-1012:
- role name ending with `member` at scope=`domain` → rejected (domain-member roles do not receive resource permissions).
- role name ending with `member` (non-domain scope) → `read` only.
- other roles → `create, read, update, soft-delete, hard-delete` (grant:\* not emitted, per BEP-1012 design decision to use Role Assignment).
- `add` infers the role's (scope_type, scope_id) from existing permission rows; rejects roles with no prior permissions.
- `replace` accepts a JSON file or string in the same shape as the fixture's `permissions` array (`{role_id, scope_type, scope_id, entity_type, operation, id?}`).
- Safety: `--dry-run` flag; interactive confirmation prompt before `replace`/`remove`; superadmin-only authorization.
## Non-Goals
- Per-(scope, operation) granular editing — bulk-by-entity_type only.
- Role creation/deletion — this Epic targets permissions on existing roles only.
- Modifying the migration generator script `scripts/generate-rbac-fixture-permissions.py` from BA-5722.
## Sub-tasks (to be split into Stories/Tasks)
- API: REST v2 endpoints + DTOs (request/response models, adapter, processor).
- SDK: typed v2 client domain (`client/v2/domains_v2/rbac.py` or similar).
- CLI: `./bai admin rbac role permission ...` commands.
- Tests: unit + integration coverage for each operation and the rule-based derivation.
## Related
- BA-5722 — motivating symptom (fresh-install permission gap).
- BEP-1012 — RBAC spec; standard operation set definition.
- BEP-1048 — RBAC entity-relationship model.
JIRA Issue: BA-5905
Contributor guide
Assessment
This issue has not been assessed yet.