Skip to content

docs(roles): state the limits of the operations allowlist - #631

Open
dawsontoth wants to merge 3 commits into
mainfrom
docs/operations-allowlist-semantics
Open

dawsontoth wants to merge 3 commits into
mainfrom
docs/operations-allowlist-semantics

Conversation

@dawsontoth

@dawsontoth dawsontoth commented Aug 18, 2026

Copy link
Copy Markdown
Contributor

Documents the limits of a role's permission.operations allowlist on reference/users-and-roles/overview.md, plus the 5.3 release note for the tightening that produced them.

Companion to HarperFast/studio#1628 (merged), which surfaces permission.operations in the Studio roles UI. Building that UI meant establishing the field's real semantics against the Harper source, and several of them contradict a natural reading of this page.

⚠️ Do not merge until Harper 5.3.0 ships

reference/ is the published /reference/v5 site, and this documents behavior that is merged to harper main but present only in v5.3.0-alpha.1. Latest stable is v5.2.13. Held as a draft until 5.3.0 is tagged; the companion-check gate is not the right mechanism here, because the companion PR has already merged and the marker would pass immediately.

Why this was rewritten

The original version of this PR described 5.2.x behavior. Three days after it was opened, harper#2176 moved allowlist gate one ahead of every other privilege check on the role and gave the SQL path its own call into it. That invalidated the two substantive limits the page had claimed:

Original claim (5.2.x) 5.3.0
structure_user bypasses the allowlist for DDL DDL must be listed; structure_user then scopes it to its databases
sql is authorized on its own path and never consults the allowlist sql must be listed for a role to run SQL

The third claim survives unchanged: super_user/cluster_user roles cannot carry an allowlist, because validateNoSUPerms rejects either flag set to true alongside other keys. The page's earlier sentence about what authorization then does with such a role is dropped — it described a state validation will not store, and #2176 inverted it anyway.

What changes

  • reference/users-and-roles/overview.md — the three limits, with <VersionBadge type="changed" version="v5.3.0" /> on the ordering change that produces two of them. Also states that the value must be an array, and points at harper#2194 for the non-array case, where a role carrying one can stop the instance loading its user cache.
  • release-notes/v5-lincoln/5.3.md — a ### Operation Allowlist Enforcement note under ## Security. The tightening revokes access from any role that relied on either bypass, so it owes an upgrade caveat: audit roles combining operations with structure_user, and roles whose list omits sql.

Verification

Re-derived from the source at v5.2.13 and origin/main (5.3.0-alpha.1), not from PR descriptions:

  • utility/operation_authorization.tsverifyOperationsAllowlist (new in #2176) runs after the empty-role check and before every privilege early-return; its own comment names the ordering requirement. Gate 2 (the SU-only-op grant) stays below the ambient privilege checks.
  • server/serverHelpers/serverUtilities.ts:362 — the SQL path calls verifyOperationsAllowlist(json, json.operation) directly, ahead of checkASTPermissions.
  • validation/role_validation.tsvalidateNoSUPerms gates on super_user === true / cluster_user === true with more than one permission key (hence "set to true" in the text; super_user: false alongside an allowlist is fine). OPERATIONS_MUST_BE_ARRAY rejects a non-array. Unchanged between v5.2.13 and main.
  • DDL api_name mappings (CREATE_TABLE, DROP_DATABASE, …) are registered, so gate one resolves the camelCase handler names to the snake_case names an allowlist is written in.
  • Badge version derived from tags, not a branch package.json: #2176 is merged, git tag --contains returns only v5.3.0-alpha.1, and role_validation.ts/operationPermissions.ts confirm the shipped v5.2.13 behavior differs. Ships in v5.3.0.

npm run format:check clean; npm run build succeeds (407 documents), which also validates the new cross-link and the badge.

Review coverage

Written by an LLM (originally Claude Fable 5; re-verified and rewritten by Claude Opus 5). Prose-only, two files. The underlying 5.2.x findings were reviewed by @cb1kenobi and @kriszyp on studio#1628; the 5.3.0 semantics here are newly derived and have not been reviewed by a human.

Both Gemini review comments are addressed — see the replies inline.

🤖 Generated with Claude Code

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Code Review

This pull request updates the documentation in reference/users-and-roles/overview.md to clarify the scoping behavior and limitations of the operations field in permission objects. The review feedback suggests clarifying the explanation of how super_user roles interact with the allowlist to avoid misleading phrasing, and recommends using a VersionBadge component to properly document the behavior change introduced in version 5.0.0.

Comment thread reference/users-and-roles/overview.md Outdated
Comment thread reference/users-and-roles/overview.md Outdated
@github-actions
github-actions Bot temporarily deployed to pr-631 August 18, 2026 16:10 Inactive
@github-actions

Copy link
Copy Markdown

🚀 Preview Deployment

Your preview deployment is ready!

🔗 Preview URL: https://preview.harper-documentation.harperfabric.com/pr-631

This preview will update automatically when you push new commits.

harper#2176 moved gate one ahead of every other privilege check on the role,
so the two limits this page originally described no longer hold: the
structure_user carve-out and the SQL path both consulted the allowlist as of
that change. Documents the 5.3.0 semantics instead — structure_user narrows
which databases listed DDL reaches rather than widening which operations are
reachable, and sql must be listed for a role to run SQL at all.

The one limit that survives is that super_user/cluster_user roles cannot carry
an allowlist: add_role and alter_role reject either flag set to true alongside
other keys, so a 'restricted super user' is a validation error rather than a
narrowed administrator. Drops the earlier claim about what authorization does
with such a role, which described a state validation will not store and which
#2176 inverted.

Also notes that a non-array value can wedge the user-cache load (harper#2194),
and adds the 5.3 release note, since the tightening revokes access from roles
that relied on either bypass.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@dawsontoth
dawsontoth force-pushed the docs/operations-allowlist-semantics branch from 64c8bcb to c4c697f Compare September 17, 2026 15:17
@github-actions

Copy link
Copy Markdown

🚀 Preview Deployment

Your preview deployment is ready!

🔗 Preview URL: https://preview.harper-documentation.harperfabric.com/pr-631

This preview will update automatically when you push new commits.

@github-actions
github-actions Bot temporarily deployed to pr-631 September 17, 2026 15:20 Inactive
Matches the shape reference/database/compaction.md uses for the same kind of
note: the badge on its own line, then a sentence naming what changed and an
"earlier v5 releases" clause for the prior behavior. The badge was sitting
mid-sentence immediately before a literal "Before v5.3.0", which rendered as
"Changed in: v5.3.0 Before v5.3.0 ...".

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@github-actions
github-actions Bot temporarily deployed to pr-631 September 17, 2026 15:26 Inactive
@github-actions

Copy link
Copy Markdown

🚀 Preview Deployment

Your preview deployment is ready!

🔗 Preview URL: https://preview.harper-documentation.harperfabric.com/pr-631

This preview will update automatically when you push new commits.

The three bullets explained gate ordering and which path bypassed what — the
mechanism, not the task. A developer arriving here is writing a role and wants
to know what to put in the list.

Replaces them with one role that exercises all three limits (sql listed, DDL
listed, structure_user scoping the DDL to one database) and two sentences of
annotation. The super_user limit becomes the reason to build a role up rather
than a bullet about validation. Same for the release note: what broke and the
two cases to audit, rather than a narrative of the ordering change.

Verified while rewriting that listing `sql` alone admits any statement variant
on a direct SQL call — the allowlist checks `sql`, and the statement is then
authorized against table permissions (harper DESIGN.md:2536), so the example
can show SELECT/INSERT reaching only what the table grants.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@github-actions

Copy link
Copy Markdown

🚀 Preview Deployment

Your preview deployment is ready!

🔗 Preview URL: https://preview.harper-documentation.harperfabric.com/pr-631

This preview will update automatically when you push new commits.

@dawsontoth
dawsontoth marked this pull request as ready for review September 17, 2026 15:33
@dawsontoth
dawsontoth requested a review from a team as a code owner September 17, 2026 15:33
@dawsontoth dawsontoth added waiting-for-companion PR is generally ready to go as soon as companion (usually implementation) PR merges. content 📝 Content specific issues and requests - text, examples, missing info, or clarity labels Sep 17, 2026
@dawsontoth

Copy link
Copy Markdown
Contributor Author

Ready for review — but please do not merge this yet, even with an approval.

reference/ is the published /reference/v5 site, and this documents the allowlist ordering from harper#2176, which is merged to harper main but tagged only in v5.3.0-alpha.1. Latest stable is v5.2.13, so merging now would publish behavior no released Harper has. Labelled waiting-for-companion for that, though the literal wait here is on the 5.3.0 release rather than on a companion PR merging — the companion-check gate would pass immediately, since #2176 has already merged.

Please also do not arm auto-merge. Happy to flip it back to draft if that is a safer place to park it while it waits.

Worth a careful look at two things:

  1. The v5.3.0 badge version. Derived from tags per the repo guideline: #2176 is merged, git tag --contains returns only v5.3.0-alpha.1, and v5.2.13 still has the old ordering. If 5.3.0 slips such that this lands in a later minor, the badge and the release-note file both need moving.
  2. The claim that listing sql admits any statement variant, with table permissions deciding what it may touch. That is from DESIGN.md — "a direct sql call has no outer job op, so there the operations allowlist alone is the operation-invocation check" — plus serverUtilities.ts:362 passing json.operation. It is the load-bearing claim in the example, and the previous version of this PR had it backwards, so it is the one I would most like a second pair of eyes on.

🤖 Generated with Claude Code

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

Labels

content 📝 Content specific issues and requests - text, examples, missing info, or clarity waiting-for-companion PR is generally ready to go as soon as companion (usually implementation) PR merges.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant