Instruction file imported from ryamiller-amergis/Apex (
.cursor/rules/rbac-governance.mdc). Copyright stays with the author.
RBAC Governance
For every UI feature being added, modified, or removed, work through the checklist below before writing any code.
Evaluation Checklist
Adding or modifying a feature:
- Does the feature expose a capability that should be access-controlled (e.g. a new page, action button, data view, or admin function)?
- Is there already a matching key in the permission catalog below that covers it?
- Yes → wire the existing key via
can('key')in the component; no migration needed. - No → load the
rbac-managementskill and follow the Add a Permission workflow.
- Yes → wire the existing key via
- Does the feature belong to an existing category (
admin,chat,deployments,workitems,wiki,skills,cost)?- No → the new permission likely needs a new category; flag this when loading the skill.
Removing a feature:
- Does the removed UI code contain a
can('...')call or reference a permission key? - If yes, search for ALL other usages of that key:
requirePermission,requireAnyPermission,can(across the entire codebase. - If zero usages remain after removal → load the
rbac-managementskill and follow the Remove a Permission workflow.
Current Permission Catalog
| Key | Category | Roles |
|---|---|---|
admin:roles |
admin | admin |
admin:users |
admin | admin |
adr:view |
adr | admin, member, viewer |
api-keys:manage |
api-keys | admin |
adr:create |
adr | admin, member |
adr:edit |
adr | admin, member |
adr:delete |
adr | admin, member |
adr:review |
adr | admin, member |
analytics:ai-cost:view |
analytics | admin |
backlog:view |
backlog | admin, member |
calendar:view |
calendar | admin, member |
chat:create |
chat | admin, member |
chat:view |
chat | admin, member |
chat:view_all |
chat | admin |
home:view |
chat | admin, member, viewer |
cost:view |
cost | admin, viewer |
diagram:view |
diagram | admin, member, viewer |
diagram:create |
diagram | admin, member |
diagram:edit |
diagram | admin, member |
diagram:delete |
diagram | admin, member |
diagram:share |
diagram | admin, member |
load-test:view |
load-test | admin, member, viewer |
load-test:run |
load-test | admin, member |
load-test:manage |
load-test | admin, member |
deployments:create |
deployments | admin, member |
deployments:manage |
deployments | admin |
design-docs:review |
design-docs | admin, member |
design-module:manage |
design-module | admin |
design-module:regenerate |
design-module | admin |
design-module:view |
design-module | admin, member, viewer |
planning:view |
planning | admin, member, viewer |
planning:devstats |
planning | admin, member |
planning:qa |
planning | admin, member |
planning:ai-analysis |
planning | admin, member |
planning:roadmap |
planning | admin, member |
planning:releases |
planning | admin, member |
playbooks:view |
playbooks | admin, member, viewer |
playbooks:run |
playbooks | admin, member |
playbooks:author |
playbooks | (no default roles — assign explicitly) |
playbooks:admin |
playbooks | admin |
prds:review |
prds | admin, member |
skills:manage |
skills | admin |
wiki:write |
wiki | admin, member |
work-board:view |
work-board | admin, member, viewer |
work-board:manage |
work-board | admin, member |
work-board:admin |
work-board | admin, member |
workflow-evaluation:view |
workflow-evaluation | admin, member |
workflow-evaluation:submit |
workflow-evaluation | admin, member |
workitems:write |
workitems | admin, member |
Client Gating Pattern
// Pull can() from useAppShell — no separate import needed
const { can } = useAppShell();
// Gate rendering
{can('skills:manage') && <ManageSkillsButton />}
// Gate navigation
if (!can('admin:roles')) return <Navigate to="/" />;
When to Load the Skill
Load the rbac-management skill (.cursor/skills/rbac-management/SKILL.md) when:
- A new permission key must be added (migration + middleware + client wiring)
- An orphaned key must be removed (migration + cleanup)
- Role-permission assignments need updating
