Files
cameleer-server/examples/RBAC/rbac-ui-spec.md
2026-03-17 16:21:25 +01:00

12 KiB
Raw Permalink Blame History

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:

  • OverviewDashboard (system summary + inheritance model diagram)
  • IdentityUsers, Groups, Roles (the three core entity types)
  • AuditAudit 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 parentchild 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

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

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

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
}

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 splitEntityListPane, 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.