Skip to content

Add per-action, per-namespace restrictive scopes#2236

Draft
philipfweiss wants to merge 3 commits into
DataJunction:mainfrom
philipfweiss:rbac-per-action-policy
Draft

Add per-action, per-namespace restrictive scopes#2236
philipfweiss wants to merge 3 commits into
DataJunction:mainfrom
philipfweiss:rbac-per-action-policy

Conversation

@philipfweiss

Copy link
Copy Markdown
Contributor

Tracking: #2234 (step 4 of the RBAC enablement sequence).

Stacked on #2233 (step 3) which is stacked on #2232 (step 2). Until those merge, this PR's diff includes their commits; review/merge #2232, then #2233, then this.

This is the mechanism that makes write governance possible with minimal blast radius, and it avoids a global deny footgun.

Adds a RESTRICTIVE_SCOPES setting. Each entry is action:scope_type:scope_value, e.g. write:namespace:finance.*. A request matching any entry is denied unless an explicit grant allows it, regardless of default_access_policy; anything not matched follows the permissive baseline.

This gives per-action and per-namespace enforcement in one mechanism. For example, with restrictive_scopes=["write:namespace:finance.*","delete:namespace:finance.*","manage:namespace:finance.*"] and the default permissive policy:

  • writes/deletes/manage on finance.* require an explicit grant (or ownership),
  • reads on finance.* stay open,
  • every other namespace stays fully permissive.

So you can turn on write governance one namespace at a time instead of flipping the whole deployment to deny.

Implementation:

  • Extracts resource matching (global / same-type / namespace-covers-node) into a shared _resource_in_scope helper, reused by grant checks and restrictive checks.
  • Applies the restrictive check in _make_decision after explicit grants, preserving the collect-then-decide shape from Add configurable default-access role to RBAC #2233.
  • No-op when restrictive_scopes is empty (the default), so nothing changes today.

Made with Cursor

Philip Weiss and others added 3 commits June 5, 2026 16:22
Thread is_admin into AuthContext and short-circuit RBAC authorization for
admins, approving all requests. The bypass is a single explicit check and
is logged for audit, so it is easy to find and to later scope down if
admins should still respect some constraints.

Co-authored-by: Cursor <cursoragent@cursor.com>
Add a DEFAULT_ACCESS_ROLE setting whose scopes are evaluated as a fallback
when no explicit grant matches, so deployments can express graceful
defaults (e.g. read on *) without flipping the whole policy to permissive.

The default role's scopes are pre-loaded into AuthContext and evaluated
together with the principal's own scopes: _make_decision now gathers all
candidate scopes (explicit grants + default role) and resolves them in one
step, then falls back to default_access_policy. Collecting candidates
before deciding (rather than a nested allow-ladder) keeps the door open for
future deny/precedence rules.

Co-authored-by: Cursor <cursoragent@cursor.com>
Add a RESTRICTIVE_SCOPES setting (entries like "write:namespace:finance.*")
so enforcement can be scoped to specific actions and namespaces: a matching
request is denied unless an explicit grant allows it, while everything else
follows the permissive baseline. This enables write governance on one
namespace at a time (writes restrictive there, reads and other namespaces
permissive) without a global deny flip.

Extracts resource matching into a shared helper and applies the restrictive
check in the decision fallback, after explicit grants. No-op when
restrictive_scopes is empty.

Co-authored-by: Cursor <cursoragent@cursor.com>
@netlify

netlify Bot commented Jun 6, 2026

Copy link
Copy Markdown

Deploy Preview for thriving-cassata-78ae72 canceled.

Name Link
🔨 Latest commit d11ea0b
🔍 Latest deploy log https://app.netlify.com/projects/thriving-cassata-78ae72/deploys/6a2365630bab8e00077fbe55

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant