Skip to content

[dev] [Marfuen] fix/custom-role-rbac-bugs#2831

Merged
Marfuen merged 10 commits into
mainfrom
fix/custom-role-rbac-bugs
May 13, 2026
Merged

[dev] [Marfuen] fix/custom-role-rbac-bugs#2831
Marfuen merged 10 commits into
mainfrom
fix/custom-role-rbac-bugs

Conversation

@github-actions
Copy link
Copy Markdown
Contributor

@github-actions github-actions Bot commented May 13, 2026

This is an automated pull request to merge fix/custom-role-rbac-bugs into dev.
It was created by the [Auto Pull Request] action.


Summary by cubic

Tightened RBAC for app/portal access and the member invite flow to prevent privilege escalation and align UI/API behavior with permissions. Users now need explicit app:read to use the app, portal access is gated by portal or compliance, and invites use permission guards with server-side checks on assignable roles.

  • Bug Fixes

    • App access: require app:read; removed implicit resource fallback.
    • Portal access: added hasPortalAccess (checks portal or compliance via @trycompai/auth + @db); enforced on the org portal page.
    • Member invites: controller guard @RequirePermission (member:create); server resolves caller member actions (built-in + custom) and enforces assignment—write-level (CRUD) can assign any role; others only employee/contractor and custom.
    • Permissions-driven UI: canInviteUsers/canManageMembers use member:create/member:update; People page computes allowedBuiltInRoles with the same write-level rule and passes to the invite modal.
  • Refactors

    • @trycompai/auth: added parseRolePermissions/parseRoleObligations (safe JSON parsing) and isRestrictedRole; exported helpers and RolePermissions and used across API/portal for consistent role parsing and portal-access checks.
    • Added .claude/skills/cleanup and updated the PostToolUse hook to remind running the cleanup skill and typecheck for all TS files in apps/ and packages/.

Written for commit 6ab7095. Summary will update on new commits.

…r invites, gate portal

Remove the APP_IMPLYING_RESOURCES fallback that let custom roles bypass
the App Access toggle. Replace hardcoded role string checks in the member
invite flow with RBAC permission checks (member:create/update), and add
privilege escalation prevention for non-admin callers. Add portal:read /
compliance-obligation check to the portal so unapproved roles are
redirected.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@vercel
Copy link
Copy Markdown

vercel Bot commented May 13, 2026

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
app Ready Ready Preview, Comment May 13, 2026 5:11pm
comp-framework-editor Ready Ready Preview, Comment May 13, 2026 5:11pm
portal Ready Ready Preview, Comment May 13, 2026 5:11pm

Request Review

Copy link
Copy Markdown
Contributor

@cubic-dev-ai cubic-dev-ai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No issues found across 6 files

Confidence score: 5/5

  • Automated review surfaced no issues in the provided summaries.
  • No files require special attention.

…e checks

Replace role string matching (isAdmin/isAuditor) with actual RBAC
permission resolution — resolves the caller's member actions from both
built-in and custom roles via BUILT_IN_ROLE_PERMISSIONS + DB lookup.
Uses member:delete as the signal for full control (can assign any role)
vs restricted (can only assign employee/contractor/custom roles).

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Remove redundant validateAssignableRoles — the @RequirePermission guard
on the controller already checks member:create. If the admin gave a
custom role Members: Write, that role can invite. No second layer of
role-string checks needed.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@vercel vercel Bot temporarily deployed to Preview – portal May 13, 2026 16:33 Inactive
@vercel vercel Bot temporarily deployed to Preview – app May 13, 2026 16:33 Inactive
Copy link
Copy Markdown
Contributor

@cubic-dev-ai cubic-dev-ai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

1 issue found across 1 file (changes from recent commits).

Prompt for AI agents (unresolved issues)

Check if these issues are valid — if so, understand the root cause of each and fix them. If appropriate, use sub-agents to investigate and fix each issue separately.


<file name="apps/api/src/people/people-invite.service.ts">

<violation number="1" location="apps/api/src/people/people-invite.service.ts:447">
P1: Auditors can no longer invite other auditors. The new generic privilege check treats `auditor` as a privileged role (it's a built-in, non-restricted role), so any caller without `member:delete` — including auditors who only have `member:create,read` — is blocked from assigning it. This contradicts the permissions definition comment ("Can invite other auditors") and the PR description ("auditors can only invite auditors").

Consider adding a same-role exception: callers should be allowed to assign roles they themselves hold, or add explicit logic for the auditor self-invite case.</violation>
</file>

Reply with feedback, questions, or to request a fix. Tag @cubic-dev-ai to re-run a review, or fix all with cubic.

Comment thread apps/api/src/people/people-invite.service.ts Outdated
… permission level

Resolve the caller's member actions from RBAC (built-in + custom roles).
Write-level access (all CRUD) can assign any role. Partial access (e.g.
auditor with create+read only) can only assign restricted roles
(employee/contractor) and custom roles — cannot assign privileged
built-in roles.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Replace hardcoded isAdminOrOwner/isAuditor role string checks with
Write-level member permission check (all CRUD actions). Mirrors the
backend validation logic.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Extract the repeated typeof/JSON.parse pattern for OrganizationRole
fields into typed helpers in the auth package. Replaces verbose
defensive checks with one-liner calls that return typed objects.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Copy link
Copy Markdown
Contributor

@cubic-dev-ai cubic-dev-ai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

1 issue found across 4 files (changes from recent commits).

Prompt for AI agents (unresolved issues)

Check if these issues are valid — if so, understand the root cause of each and fix them. If appropriate, use sub-agents to investigate and fix each issue separately.


<file name="packages/auth/src/permissions.ts">

<violation number="1" location="packages/auth/src/permissions.ts:269">
P1: `JSON.parse` can throw on malformed input. Since these helpers parse user-defined DB data and are otherwise written defensively, wrap the parse in a try-catch to return the safe fallback (`null` / `{}`) instead of crashing the caller.</violation>
</file>

Tip: Review your code locally with the cubic CLI to iterate faster.
Fix all with cubic

Comment thread packages/auth/src/permissions.ts Outdated
Add try/catch to JSON parse helpers, extract generic parseJsonField,
add isRestrictedRole() to eliminate verbose readonly casts, and
make portal-access checks consistent.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Committed to the repo so all Claude agents working in this codebase
will have it available and are required to run it after writing code.
Checks for verbose patterns, inconsistent idioms, missing error
handling, and readability issues.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@Marfuen
Copy link
Copy Markdown
Contributor

Marfuen commented May 13, 2026

@cubic-dev-ai review this

@cubic-dev-ai
Copy link
Copy Markdown
Contributor

cubic-dev-ai Bot commented May 13, 2026

@cubic-dev-ai review this

@Marfuen I have started the AI code review. It will take a few minutes to complete.

The hook now fires for all TS files in apps/ and packages/ and reminds
agents to run the cleanup skill before committing.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@Marfuen Marfuen merged commit d47cd5d into main May 13, 2026
9 checks passed
@Marfuen Marfuen deleted the fix/custom-role-rbac-bugs branch May 13, 2026 17:11
Copy link
Copy Markdown
Contributor

@cubic-dev-ai cubic-dev-ai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No issues found across 9 files

Confidence score: 5/5

  • Automated review surfaced no issues in the provided summaries.
  • No files require special attention.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant