Feat permissions audit - #2208
Draft
papistacoding wants to merge 4 commits into
Draft
Conversation
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
Audit of every <Button>/<button> in the console against the org-level relations in core's fga/model/generated/crud.fga. Of 265 files invoking mutations, these trigger surfaces reached the backend with no permission check at all: - trust center NDA approve/deny and Approve All, which only ever gated the revoke path - subscriber bulk upload and row delete - campaign launch, cancel, delete, reminders, recipients and the draft setup view - the workflow wizard, both at its own route and where it renders embedded on an empty workflows list - creating a questionnaire from a template, which was also gated on CanCreateTemplate rather than CanCreateAssessment - inline owner/delegate/approver/stakeholder/assignee cells in the controls, policies, procedures, risks and tasks tables The generic table toolbar fell back to org can_edit whenever a page did not pass createPermission, which hid the create button from anyone holding only a <entity>_creator grant. Nine table pages now pass their own relation; every can_create_* includes can_edit, so nobody who could already create loses the button. Campaigns keeps its list readable: a route-level gate on CanCreateCampaign would lock viewers out of the whole section even though can_view_campaign is a distinct relation and the nav shows the entry to every role. The gate sits on the create button and the detail actions instead. Two scope bugs found while wiring this up: - PermissionGate keyed its denial on isSuccess, so a permission-service failure left it neither loading nor successful and rendered the protected children anyway. It now falls back to hasPermission, which fails closed and keeps the impersonation exception. - can_edit_trust_center_nda_request is declared on the organization type, but the NDA page looked for it in a trust-center object-roles response, where it can never appear. Request management now ORs the org-scoped capability with generic trust-center edit. Invite resend is separated from invite deletion: a MEMBER holds can_invite_members and may reissue a member invite, but not manage existing ones, and previously got an empty actions column. Inline cells read their own permission via useCanEditRows rather than threading a flag through the column factories, matching how the rest of the app resolves org roles at the point of use. Signed-off-by: papistacoding <bruno.papista@gmail.com>
papistacoding
force-pushed
the
feat-permissions-audit
branch
from
August 27, 2026 15:15
d3264a7 to
e61f8dc
Compare
Cross-checked every gate against core: internal/ent/schema/*.go for the per-entity policy, iam@v0.31.1/entfga/checks.go for what each check does, and fga/model for the relations themselves. entfga.CheckEditAccess runs CheckAccessForEdit for delete operations too, so of the 50 schemas only trustcenterndarequest and workflowobjectref distinguish deletion at all. Four gates were derived from the existence of a can_delete_* relation rather than from the check core invokes, and hid the action from users the backend would allow: - campaign delete now needs object can_edit (CheckEditAccess) - subscriber delete now needs org can_edit (CheckOrgWriteAccess) — can_delete_subscriber resolves only through full_access, so gating on it locked out every admin - trust center document delete now needs object can_edit - trust center subprocessor delete now needs org can_edit Organization delete keeps can_delete: HasOrgMutationAccess is one of the two places that really does require it. CanDeleteSubscriber and CanDeleteTrustCenterSubprocessor lose their last consumers and go with them. Creates were checked the same way and need no change: CheckCreateAccess resolves to can_create_<entity>, which is what the createPermission entries already pass. Signed-off-by: papistacoding <bruno.papista@gmail.com>
Three of the route layouts gated on a relation core never consults for the mutations behind them. Branding and customer logos required org can_edit. Core admits any trust-center editor: rule.AllowIfTrustCenterEditor checks can_edit on the trust center object and short-circuits to privacy.Allow, and the FGA model reaches editor either from the org through parent_editor or from a direct tuple on the trust center. The org-only gate therefore turned away legitimate editors before the page could run the useAccountRoles check it already has. Both now use TrustCenterEditorGate, which reads the object's roles. The custom domain route required can_create_custom_domain, which is `can_edit or can_edit_custom_domain`, while core guards CustomDomain with CheckOrgWriteAccess — plain org can_edit. A can_edit_custom_domain holder passed the route and then failed every mutation on it. CanCreateCustomDomain loses its last consumer and goes with it. Signed-off-by: papistacoding <bruno.papista@gmail.com>
Workflows and task creation are no longer gated, route-level gates are replaced by per-affordance checks, and every trust-center surface resolves one edit rule instead of eight. Org deletion returns to the owner check and the email-template editor stops checking a create relation on update. Close the gaps the route gates were hiding: SSO actions, domain verification, FAQ reordering, subprocessor mode switching and trust-center document management. Create gates run through hasPermission so impersonation keeps working, and no longer stop at the button. domain-list-editor is carried here too: the SSO and allowed-domain gates need its prop shape, so the branch would not build without it. Signed-off-by: papistacoding <bruno.papista@gmail.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
No description provided.