What are Scope Overrides?
Scope overrides let you adjust how roles and permissions resolve at a specific scope without changing the underlying role or permission definitions. You can deactivate a role, deactivate a permission, or grant/revoke a specific role-permission combination at that scope. This is by design a per-scope mechanism: it lets different scopes—especially environments—run their own variant of the same shared roles and permissions. Turn a role or permission off inproduction while it stays on in staging, or grant an extra (optionally conditional) role-permission only in dev—all without forking the definitions. Overrides are not a top-down safety cascade; each scope declares its own variant.
Overrides do not grant memberships. A subject’s role memberships are resolved per the request scope’s
permissionMode (by default, at the exact scope of the request). Overrides only enable, disable, grant, or revoke roles/permissions for subjects whose grants are already being resolved at that scope.Override Types
Bedrock supports three override types, each with its own set of valid states:Only role-permission overrides carry a JSON Logic
condition. Role and permission
overrides are plain state toggles.Role Overrides
Deactivate (or re-activate) an entire role at a scope:inactive at a scope, all grants from that role are dropped while resolving grants at that scope. Role assignments still exist but contribute nothing there. Set state: "active" to re-activate where a role would otherwise be off, or inherit for “no opinion at this scope”.
Permission Overrides
Deactivate a specific permission at a scope:inactive at a scope, no role can grant it while resolving grants at that scope.
Role-Permission Overrides
The most granular override—revoke (or grant) a specific permission for a specific role:
grant adds a (role, permission) grant for a role the subject already holds; revoke drops it; inherit is a no-op.
With Conditions
Role-permission overrides can carry a JSON Logiccondition—typically with grant to add a grant only when the condition passes:
How Overrides Compose Across Scopes
Overrides are applied per scope: an override set at scopeX affects grant resolution at X. There is no blanket “disable here, stays disabled everywhere below” cascade. How a scope’s overrides interact with its ancestors follows that scope’s permissionMode:
override(default) — only the request scope’s own grants and its own overrides apply. An override set on a parent scope does not affect a child evaluated underoverride.inherit/additive— grants are composed up the ancestor chain; each scope’s overrides apply to that scope’s grants as they are composed, and the request scope’s overrides apply to the final composed set.
Override States
inherit (and the absence of any override) means “no opinion at this scope”.
Common Patterns
Production Lockdown
Agent Restrictions
Time-Boxed Elevated Access
Role and permission overrides don’t carry conditions, so time-boxed elevation is expressed as a role-permission override withgrant + a condition:
Querying Overrides
Removing Overrides
Best Practices
Use the most specific override
Use the most specific override
Prefer role-permission overrides over blanket role or permission deactivation.
Set restrictions at every scope they must hold
Set restrictions at every scope they must hold
Overrides are per-scope under the default
override mode—don’t assume a parent override protects children.Prefer conditions over hard revokes
Prefer conditions over hard revokes
Use conditional role-permission overrides for time- or context-based restrictions.
Document your overrides
Document your overrides
Keep track of why overrides exist—they can be hard to debug later.
Related Concepts
Scope Types
How
permissionMode governs cross-scope compositionEvaluation
How overrides affect permission evaluation