Policies
A policy is plain data. It is validated, canonicalized, compiled, and frozen by definePolicy().
Resources
Section titled “Resources”Each resource type declares its concrete actions and at most one parent type. Parents form the ancestry that scopes are checked against.
resources: { organization: { actions: ["read"] }, workspace: { parent: "organization", actions: ["read", "update"] }, project: { parent: "workspace", actions: ["read", "update", "delete"] },}Policy names, actions, roles, facts, and fields use a strict safe-name grammar. Resource and subject ids are opaque non-empty strings, so numeric and UUID-style ids work.
Roles and scope
Section titled “Roles and scope”A role declares the scope it lives at and its rules.
roles: { workspace_editor: { scope: "workspace", rules: [ { effect: "allow", permission: "project:read" }, { effect: "allow", permission: "project:update" }, ], },}A role’s rules may target its scoped resource type or that type’s declared descendants. They may not target ancestors or unrelated types. A workspace role can grant project:update; it cannot grant organization:read.
Each rule is an allow or a deny for one permission, with optional condition and field constraints.
{ effect: "deny", permission: "project:delete" }{ effect: "allow", permission: "project:update", where: { ... }, fields: ["title"] }A policy rule may use an action wildcard, project:*. A request never may: every check names one concrete action.
Inheritance
Section titled “Inheritance”Roles may inherit roles at the same scope. They inherit complete rules, including denies.
workspace_admin: { scope: "workspace", inherits: ["workspace_editor"], rules: [{ effect: "allow", permission: "project:delete" }],}No bypass role
Section titled “No bypass role”There is no super admin and no action-level implication. Elevated access is an ordinary scoped assignment with explicit rules. This keeps every grant visible in the policy and every decision explainable.
Versioning
Section titled “Versioning”version is optional and application-controlled. It is echoed on every decision as policyVersion, which lets audit records say which policy produced a result.