# RBAC Management UI — Design Specification ## Overview This document describes the Monitor RBAC management interface: its layout, navigation, entity model, visual conventions, badge/chip meanings, and inheritance behaviour. It is intended as a handoff reference for developers implementing the production version. --- ## Application layout The app is a two-column shell with a fixed top bar. ``` ┌─────────────────────────────────────────────────┐ │ Top bar (brand + environment badge + avatar) │ ├──────────────┬──────────────────────────────────┤ │ │ │ │ Sidebar │ Main panel │ │ (200px) │ (fills remaining width) │ │ │ │ └──────────────┴──────────────────────────────────┘ ``` ### Top bar | Element | Purpose | |---|---| | Brand dot (green) | Indicates a live/healthy connection to the monitoring backend | | `Monitor RBAC` wordmark | App name | | Environment badge (`production`, `staging`, etc.) | Reminds operators which environment they are modifying — destructive changes in production are intentional | | User avatar circle | Current operator identity; initials derived from name | ### Sidebar Three navigation sections: - **Overview** — `Dashboard` (system summary + inheritance model diagram) - **Identity** — `Users`, `Groups`, `Roles` (the three core entity types) - **Audit** — `Audit log` (change history, out of scope for this spec) Each identity nav item shows a **count badge** (e.g. `8`, `5`, `6`) reflecting the total number of entities of that type. The active item is indicated by a green left border accent and bold label. --- ## Panels ### Dashboard (Overview) Displays three **stat cards** at the top: | Card | Content | |---|---| | Users | Total user count + active sub-count | | Groups | Total group count + max nesting depth | | Roles | Total role count + note about direct vs inherited | Below the stat cards is an **inheritance model diagram** — a three-column schematic showing how Groups → Roles on groups → Users form the inheritance chain. This is a read-only orientation aid, not interactive. A note block (green left border) explains the inheritance rule in plain language. --- ### Users panel Split into a **list pane** (left, ~52% width) and a **detail pane** (right). #### List pane Each row is a user card containing: | Element | Description | |---|---| | Avatar circle | Two-letter initials; background colour varies by user for visual distinction | | Name | Full display name | | Meta line | Email address · primary group path (e.g. `Engineering → Backend`) | | Tag row | Compact role and group badges (see Badge reference below) | | Status dot | Green = active, grey = inactive/suspended | A search input at the top filters rows by any visible text (name, email, group, role). Clicking a row selects it (blue tint) and loads the detail pane. #### Detail pane — user Shows full user information organised into sections: | Section | Contents | |---|---| | Header | Avatar, full name, email address | | Fields | Status, internal ID (truncated), created date | | Group membership | Chips for every group the user directly belongs to. Sub-groups are also shown if membership was inherited via a parent group, with a small `via GroupName` annotation. | | Effective roles | All roles the user holds — both direct assignments and roles inherited through group membership (see Role chips below) | | Group tree | A visual indented tree showing the ancestry path of the user's groups | --- ### Groups panel Same split layout as Users. #### List pane — group cards | Element | Description | |---|---| | Avatar square (rounded) | Two-letter abbreviation; colour indicates domain (green = engineering, amber = ops, red = admin) | | Name | Group display name | | Meta line | Parent group (if nested) · member count | | Tag row | Roles assigned directly to this group; inherited roles shown with italic/faded styling | #### Detail pane — group | Section | Contents | |---|---| | Header | Avatar, group name, hierarchy level label | | Fields | Internal ID | | Members (direct) | Name chips for users who are direct members of this group | | Child groups | Chips for any groups nested inside this one | | Assigned roles | Roles directly assigned to this group — what all members will inherit | | Inheritance note | Plain-language explanation of how roles propagate to children | | Group hierarchy | Indented tree showing parent → this group → children | --- ### Roles panel Same split layout. #### List pane — role cards | Element | Description | |---|---| | Avatar square | Two-letter abbreviation of the role name | | Name | Role identifier (lowercase slug) | | Meta line | Short description of access level · assignment count | | Tag row | Groups and/or users the role is directly assigned to | #### Detail pane — role | Section | Contents | |---|---| | Header | Avatar, role name, description | | Fields | Internal ID, scope | | Assigned to groups | Group chips where this role is directly configured | | Assigned to users (direct) | User chips that hold this role outside of any group | | Effective principals | All principals (users) who effectively have this role, whether directly or via group inheritance | | Inheritance note | Explains direct vs inherited assignments | --- ## Badge and chip reference ### Role tags (amber / orange) Appear on user and group list rows to show which roles apply. | Style | Meaning | |---|---| | Solid amber background, normal text | **Direct assignment** — the role is explicitly assigned to this entity | | Faded / italic text, dashed border | **Inherited role** — the role flows from a parent group, not assigned directly | In the detail pane, inherited role chips include a small `↑ GroupName` annotation identifying the source group. ### Group tags (green) Appear on user list rows and role detail panes. | Style | Meaning | |---|---| | Solid green background | The entity belongs to or is assigned to this group directly | ### Status dot | Colour | Meaning | |---|---| | Green (filled) | User account is active | | Grey (filled) | User account is inactive or suspended | ### Environment badge (top bar) | Value | Meaning | |---|---| | `production` | Live system — changes are immediate and real | | `staging` | Pre-production — safe for testing | ### Count badge (sidebar nav) Small pill next to each nav label showing the total number of entities of that type. Updates to reflect search/filter state when implemented. --- ## Inheritance model The RBAC system implements **two inheritance axes**: ### 1. Group → child group Groups can be nested to any depth. A child group inherits all roles assigned to its parent group. This is transitive — a role on `Engineering` propagates to `Backend` and `Frontend`, and would continue to any groups nested inside those. ``` Engineering (role: viewer) ├── Backend (role: editor, inherits: viewer) └── Frontend (role: editor, inherits: viewer) ``` ### 2. Group → member users All roles effective on a group (direct + inherited from parent groups) are inherited by every user who is a member of that group. ``` User: Alice Direct member of: Engineering, Backend Effective roles: - admin (direct on Alice) - viewer (inherited via Engineering) - editor (inherited via Backend) ``` ### Role resolution When checking if a user has a given role, the system should: 1. Check direct role assignments on the user. 2. For each group the user belongs to (directly or transitively), check all roles on that group. 3. Union the full set — **no role negation** in the base model (roles only grant, never deny). This makes effective role computation a union of all reachable role sets across the user's group membership graph. --- ## Visual conventions | Convention | Meaning | |---|---| | Dashed chip border | Inherited / transitive — not directly configured here | | `↑ GroupName` annotation | Points to the source of an inherited permission | | Green left border on nav item | Currently active section | | Indented tree with corner connector | Shows parent–child group hierarchy | | Green note block (left border) | Contextual explanation of inheritance behaviour — appears wherever inherited permissions could be confusing | | Blue tint on selected list row | Currently selected entity; detail pane reflects this entity | --- ## Entity data model (for implementation reference) ### User ```ts interface User { id: string; // e.g. "usr_01HX…4AF" name: string; email: string; status: "active" | "inactive"; createdAt: string; // ISO date directGroups: string[]; // group IDs — direct membership only directRoles: string[]; // role IDs — assigned directly to this user // Computed at read time: effectiveGroups: string[]; // all groups including transitive effectiveRoles: string[]; // all roles including inherited } ``` ### Group ```ts interface Group { id: string; // e.g. "grp_02KX…9BC" name: string; parentGroupId?: string; // null for top-level groups directRoles: string[]; // role IDs assigned to this group // Computed at read time: effectiveRoles: string[]; // direct + inherited from parent chain memberUserIds: string[]; // direct members only childGroupIds: string[]; // direct children only } ``` ### Role ```ts interface Role { id: string; // e.g. "rol_00AA…1F2" name: string; // slug, e.g. "admin", "viewer" description: string; scope: string; // e.g. "system-wide", "monitoring:read" // Computed at read time: directGroupIds: string[]; // groups this role is assigned to directUserIds: string[]; // users this role is assigned to directly effectivePrincipalIds: string[]; // all users who hold this role } ``` --- ## Recommended API surface | Method | Path | Description | |---|---|---| | `GET` | `/users` | List all users with effectiveRoles and effectiveGroups | | `GET` | `/users/:id` | Single user detail | | `POST` | `/users/:id/roles` | Assign a role directly to a user | | `DELETE` | `/users/:id/roles/:roleId` | Remove a direct role from a user | | `POST` | `/users/:id/groups` | Add user to a group | | `DELETE` | `/users/:id/groups/:groupId` | Remove user from a group | | `GET` | `/groups` | List all groups with hierarchy | | `GET` | `/groups/:id` | Single group detail | | `POST` | `/groups/:id/roles` | Assign a role to a group | | `POST` | `/groups/:id/children` | Nest a child group | | `GET` | `/roles` | List all roles with effective principals | | `GET` | `/roles/:id` | Single role detail | --- ## Handoff notes for Claude Code When implementing this in a production stack: - **State management** — effective roles and groups should be computed server-side and returned in API responses. Do not compute inheritance chains in the frontend. - **Component split** — `EntityListPane`, `UserDetail`, `GroupDetail`, `RoleDetail`, `InheritanceChip`, `GroupTree` are the natural component boundaries. - **CSS tokens** — all colours use CSS variables (`--color-background-primary`, `--color-border-tertiary`, etc.) that map to the design system. Replace with your own token layer (Tailwind, CSS Modules, etc.). - **Search** — currently client-side string matching. For large deployments, wire to a server-side search endpoint. - **Inheritance note blocks** — always render these wherever inherited permissions are displayed. They prevent operator confusion when a user has a role they didn't expect.