docs: custom roles REST API reference (CUB-4361) - #11894
paveltiunov wants to merge 63 commits into
Conversation
|
Preview deployment for your docs. Learn more about Mintlify Previews.
💡 Tip: Enable Automations to automatically generate PRs for you. |
|
Claude finished @paveltiunov's task in 3m 1s —— View job Review complete — 3 findings (1 medium, 2 low), no blockers in the generated spec or navDetails
Findings
Checks that passed
Note, not a findingThe regeneration also sweeps in unrelated upstream spec drift not mentioned in the PR description: I could not run |
|
Claude finished @paveltiunov's task in 2m 29s —— View job Review complete — 2 medium, 2 low, no blockersDetails (4 inline comments, verification notes, checklist)Findings
What checks out
Not verified
No prior review threads existed on this PR, so there was nothing to resolve or dedupe against. Checklist
|
|
Claude finished @paveltiunov's task in 3m 9s —— View job Review complete — 2 medium, 1 low posted inline; 1 prior thread re-affirmedDetails
Findings
Re-affirmed 1 prior thread still applies: the Checked and clean
Security / performance / testsDocs-only; no runtime surface. One note worth keeping in view: every new operation's description opens with 🔒 Admin only, and the endpoints are admin-gated server-side, so the reference doesn't leak a callable surface to non-admins. |
Reviewing PR #11894
|
|
Claude finished @paveltiunov's task in 4m 4s —— View job Review — 1 high, 2 medium. All three are on
|
| Sev | Where | What |
|---|---|---|
| High | custom-roles.mdx:264 |
"built-in roles are not listed, editable or assignable" is false on the third term. Your own reply on efe7fbd established that assignRole branches on the negative id and always has; api.yaml restricts only DELETE and PUT /roles/{roleId}, and says nothing of the kind on the assign endpoint. PUT /api/v1/roles/-7/users/{id} grants Admin and returns 200. Leaving it unadvertised was defensible — asserting the opposite points a privilege-escalation audit the wrong way. |
| Medium | custom-roles.mdx:251 |
Says the auto-bump "applies to your payload too"; the <Warning> at :260 says it is builder-only and "not one the server applies to what you send". ff91d58 narrowed :260 and left :251 asserting the broad version first. |
| Medium | custom-roles.mdx:213–217 |
The new intro promises to flag where the API validates differently but names only the action-less policy. The reserved-name bullet gets no qualifier, so "name": "AIBIViewer" 400s from a name the page implies is free, and "name": "All" succeeds from one it says is rejected. |
Checked and clean
- Nav ordering.
RolesafterUsers Adminindocs.json:982matchesTAG_ORDER—GroupsandUser Groupshave no tags in this spec, soRoleslands where the generator would put it.introduction.mdx:93is in the same position. - Link targets.
#auto-bump-to-developerresolves to:69(I initially read this as a dead anchor — it isn't; only the sentence around it is wrong).ref-api-roles→List custom roles,ref-api-create-deployment→api.yaml:5221. Both slugs match theirsummary. - Schema refs.
Role,RoleCreateBody,RoleUpdateBody,RolesListResponseresolvePolicy(api.yaml:11026) andPageInfo(:10847), both pre-existing. Seven paths in the spec, seven in the nav group. restrictDataDownload/showRowTotals. Your earlier thread reads correctly — pre-existing drift between this repo's committed reference and the enterprise spec on master, not fields riding in on the branch.- Page-vs-reference consistency on the rest of the API section: the
400conditions, thePUT-replaces-not-merges note, the id-shape-not-existence note and the admin-only requirement all match thex-mintdescriptions.
Not run
node scripts/extract-api.mjs --check <spec> — the spec lives in the private cubedevinc/cubejs-enterprise repo, so I can't reproduce the up-to-date claim from here. Worth noting the gap you identified stands: nothing in CI catches this reference drifting from the enterprise spec, which is why a regen on an unrelated PR keeps surfacing unrelated fields.
No prior review threads were open — the thread list paged out empty, so nothing to resolve or dedupe against.
Reviewing PR #11894
|
|
Claude finished @paveltiunov's task in 5m 23s —— View job Approve with nits — 0 high, 2 medium, 2 low. Generated reference, nav and links all check out.Full review
Findings
Findings 1–3 are upstream ( Verified clean
Notes, no action askedThe No prior unresolved review threads — the eight rounds above are all resolved, so none of these four findings duplicates one. |
The page made the same point — a custom role's Base Role confers the tier and no deployment access — in six places, most of them added by this PR. docs-mintlify/CLAUDE.md says to say it once. The Base Role section keeps the statement and the built-in comparison, now one paragraph instead of two; the concept list stops at the tier, the Base Role actions section links back instead of restating, and the two action rows say what the permission grants without re-litigating where the built-in roles get it from. Walkthrough 1 built an Org Viewer that could not export, weaker than the built-in Viewer it is named after, with nothing at the point of decision saying so. Offer Download data the way walkthrough 2 does — conditionally, and free, since it does not trigger the auto-bump. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_014vmXD5G9wKFi5cV6Vn6xkg
"Sit at every tier" reads as the tier granting them, which is the misreading the rest of the page exists to prevent — :48 and the Org Viewer walkthrough both say the Base Role carries no deployment-scoped access. The property is exemption from the auto-bump, so say that, and say the policy still has to grant them. Chat history's exemption and its caution were stated three times; the anchor and the catalog row now carry one fact each — what the permission shows, and where the auto-bump rule lives — and walkthrough 2 keeps the practical note. Download data exports query results as CSV; exporting a dashboard as PNG or PDF is the separate Dashboard Exports API, so walkthrough 1 no longer offers it as "dashboards and results". Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_014vmXD5G9wKFi5cV6Vn6xkg
Giving walkthrough 1 its chat and its export made the finished role identical to the built-in Viewer — same tier, same scope, same three actions — on a page that opens by framing custom roles as what you reach for when you need finer control. Narrowing the step again would cost the role its chat, which is the defect db7cb29 fixed, so name the outcome instead: it reproduces the built-in Viewer, and the reason to write it as a custom role is what you change next. The auto-bump lead-in also gave as its reason a restatement of its own claim, and repeated the policy rule that the Base Role bullet already owns. The list is the section's content; it needs neither. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_014vmXD5G9wKFi5cV6Vn6xkg
The step offers Download data conditionally, so "as written" had two referents and the claim was false on the branch where a reader leaves it off. Say which branch it describes — and since that branch is the page's own first example of narrowing, make it the first way out rather than the abstract "drop an action the built-in grants". Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_014vmXD5G9wKFi5cV6Vn6xkg
7fb0133 to
81332dc
Compare
|
Claude finished @paveltiunov's task in 3m 26s —— View job 1 low —
|
The built-in Developer's deployment policy is every deployment action except Access chat history (`default-roles.ts` filters it out of `actionsByResourceType[Deployment]`), while Full access (`All`) expands to that list unfiltered. Offering Full access as the way to build "a Developer-equivalent" therefore over-granted, silently. Name the exclusion where the built-in is described and let the contrast fall out of it. Also drops the Base Role bullet's trailing clause: the paragraph eight lines below already says a custom role starts with no deployment access, and says it with the supporting detail. "Grants no deployment-scoped access" is also not something the Base Role determines, which is what the list it sits in is enumerating. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_014vmXD5G9wKFi5cV6Vn6xkg
|
Claude finished @paveltiunov's task in 4m 45s —— View job Docs-only change, 3 low-severity findings — 1 claim to verify, 2 wording defects introduced this roundReview details
Findings (all inline)
Checked and clean
Review threadsListing returned 0 of my own threads (single page, Not reviewed: the two pre-existing Databricks Metric View |
`viewerRole` carries three policies, not two: Global `AIBIView`, the three deployment actions over every deployment, and an Agent policy with `AgentRead`. The console's role builder writes only Global and deployment policies (`policyAdapter.ts` drops every other resource type), so a custom role cannot reproduce that third one and "assigning that role does the same thing" was false. The claim now covers what was actually checked — the same tier and the same deployment access — and the agent policy stays unmentioned for the same reason `WorkbookManage` does: it is not something the builder can express. Also rewrites the built-ins paragraph so each role gets its own clause. In one chain, "including the data-model ones" attached to Access chat history rather than to "every deployment action" three commas earlier, and "it takes chat history too" read as agreeing with the built-in Developer when the point was the contrast. And renames the first walkthrough's heading: it stopped being "read access" when the step gained Access AI agents and Download data. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_014vmXD5G9wKFi5cV6Vn6xkg
|
Claude finished @paveltiunov's task in 4m 26s —— View job Review complete — 3 findings (1 medium, 2 low). No blockers.Full review
Findings
Checked and clean
Review threadsThe listing returned 0 threads — no prior |
"Every custom role has exactly one Base Role" is a claim about roles, and
the Warning further down says the opposite for a role created over the API —
one sent without a `Global` tier policy is accepted and has none. The two
neighbouring statements were already scoped to the builder; this one is now
too.
The action catalog's caveat covered one of the two dimensions the builder
narrows. `PolicyResourceType` has ten values and `policyAdapter.ts` writes
two of them, so a Report, Workbook, Agent or Folder policy is grantable over
the API with nothing on the page hinting it exists — and the wire-format
sentence above ("the Base Role is a Global policy… each deployment policy
card is one Deployment policy") reads as the whole format because it is the
only description of it the page gives.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_014vmXD5G9wKFi5cV6Vn6xkg
|
Claude finished @paveltiunov's task in 3m 57s —— View job Review complete — no blocking issues; 3 low (editorial) findings posted inlineDetails
Scope of this roundThe five newest commits ( Findings
Checks that came back clean
Review threads
|
- The Base Role's second bullet had nothing left after a49995e took its substantive half: its subject repeated the table header two lines below and its gloss repeated the concept list at the top of the page. With one bullet remaining, the list became a sentence. - "Wider in both directions" says one of them narrows; neither does. And "agents" collided with the **Access AI agents** deployment action the builder does render — what has no card is the `Agent` resourceType, so the list now names the enum values. - "Leave Download data off" was offered as a departure from what the walkthrough produces, but the step already presents that action as conditional, so it is one of the walkthrough's own paths. Dropped; the two genuine departures stay. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_014vmXD5G9wKFi5cV6Vn6xkg
|
Claude finished @paveltiunov's task in 3m 52s —— View job Approve — no blocking findings (0 high, 0 medium, 2 non-blocking notes)Review detail
What I checkedDocs-only change. I verified the page against the generated reference rather than reading the two independently:
Also consistent: the four exempt actions at The Two non-blocking notes, neither newBoth were raised and deliberately deferred earlier in the thread, and neither is tracked by an open thread now. Recording them so they don't evaporate:
Review threads
|

Check List
scripts/extract-api.mjs --checkis the gate and passesIssue Reference this PR resolves
CUB-4361. Docs half of cubedevinc/cubejs-enterprise#15056, which adds the
/api/v1/rolesendpoints to the console-server public API.Description of Changes Made
api-reference/api.yaml,docs.jsonandapi-reference/introduction.mdxfrom the console-server public spec, which now carries/api/v1/roles(list, create, get, update, delete, plus assign/unassign a role for a user).RolestoTAG_ORDERinscripts/extract-api.mjsso the group sits with the other access-control groups (Users, Users Admin, Groups, User Groups) instead of being appended A–Z at the end of the Platform Endpoints nav, which is where an unlisted tag lands.admin/users-and-permissions/custom-roles.mdx. That page is written entirely around the console, which was accurate until now; the section walks the flow the endpoints were added for — create a deployment, scope a role to its numeric id, assign it — and notes the two things that aren't obvious from the schema:"actions": ["All"]is the Full access shortcut, and deployment ids are checked for shape rather than existence.On
extract-api.mjs --checkafter the rebase onto masternode scripts/extract-api.mjs --check <spec>, against the spec on the linked PR's branch, reports every roles path and schema up to date. It does report the reference out of date overall, on two paths this PR did not touch — the Databricks Metric Viewsyncsendpoints, which landed oncubejs-enterprisemaster after this branch's regeneration. That drift is already oncubemaster (the reference was not regenerated when those endpoints shipped) and is not this PR's to carry: regenerating here would fold 419 unrelated reference lines into a docs change that is already reviewed, so this PR leaves them to the change that adds them.🤖 Generated with Claude Code
https://claude.ai/code/session_014vmXD5G9wKFi5cV6Vn6xkg
Generated by Claude Code