lablup / lablup/backend.ai

Admin CLI/SDK/API for role permission management (add/remove/replace)

Open
#11,415 0 comments 0 reactions 0 assignees View on GitHub
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

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.