ObjectStackObjectStack

Permission

Permission protocol schemas

Entity (Object) Level Permissions Defines CRUD + VAMA (View All / Modify All) + Lifecycle access.

Refined with enterprise data lifecycle controls:

  • Transfer (Ownership change)
  • Restore (Soft delete recovery)
  • Purge (Hard delete / Compliance)

Source: packages/spec/src/security/permission.zod.ts

TypeScript Usage

import { AdminScopeSchema, EffectiveObjectPermissionSchema, FieldPermissionSchema, ObjectAccessScopeSchema, ObjectPermissionSchema, PermissionSetSchema } from '@objectstack/spec/security';
import type { AdminScope, EffectiveObjectPermission, FieldPermission, ObjectAccessScope, ObjectPermission, PermissionSet } from '@objectstack/spec/security';

// Validate data
const result = AdminScopeSchema.parse(data);

AdminScope

Properties

PropertyTypeRequiredDescription
businessUnitstring[ADR-0090 D12] Delegation boundary: sys_business_unit.name of the subtree root
includeSubtreebooleanCover descendant business units too (default true)
manageAssignmentsbooleanManage user↔position assignments within the subtree
manageBindingsbooleanManage position↔permission-set bindings within the subtree
authorEnvironmentSetsbooleanAuthor environment-owned permission sets
assignablePermissionSetsstring[]Allowlist of permission-set names the delegate may hand out

EffectiveObjectPermission

Properties

PropertyTypeRequiredDescription
allowCreatebooleanCreate permission
allowReadbooleanRead permission
allowEditbooleanEdit permission
allowDeletebooleanDelete permission
allowExportbooleanoptional[#3544] User-level export axis over read (opt-in grant). true = export granted (still bounded by read); unset/false = no export. Merged most-permissively like the CRUD bits; NOT implied by viewAllRecords/modifyAllRecords.
allowTransferboolean[RBAC-gated; ENFORCED now via insert/update owner_id guard, #3004] Change record ownership (assign/reassign/disown owner_id)
allowRestoreboolean[RBAC-gated; operation pending M2] Restore from trash (Undelete)
allowPurgeboolean[RBAC-gated; operation pending M2] Permanently delete (Hard Delete/GDPR)
viewAllRecordsbooleanView All Data (Bypass Sharing)
modifyAllRecordsbooleanModify All Data (Bypass Sharing) — bypasses sharing rules and ownership on the objects record sharing enforces on; on an object with NO owner field sharing abstains, so the platform created_by write floor still applies (#6698).
readScopeEnum<'own' | 'own_and_reports' | 'unit' | 'unit_and_below' | 'org'>optional[ADR-0057 D1] Read depth: own|unit|unit_and_below|org
writeScopeEnum<'own' | 'own_and_reports' | 'unit' | 'unit_and_below' | 'org'>optional[ADR-0057 D1] Write depth: own|unit|unit_and_below|org
apiOperationsEnum<'get' | 'list' | 'create' | 'update' | 'delete' | 'upsert' | 'bulk' | 'aggregate' | 'history' | 'search' | 'restore' | 'purge' | 'import' | 'export'>[]optionalServer-resolved effective API operations for this object (#3391). Present only when the object tightens exposure via apiMethods; absent = default-allow. The frontend renders this effective set, never the raw whitelist. Vocabulary is the EFFECTIVE ApiOperation set (six primitives + eight derived verbs, #3543), not the authored six-value ApiMethod enum.

FieldPermission

Properties

PropertyTypeRequiredDescription
readablebooleanField read access
editablebooleanField edit access

ObjectAccessScope

Allowed Values

  • own
  • own_and_reports
  • unit
  • unit_and_below
  • org

ObjectPermission

Properties

PropertyTypeRequiredDescription
allowCreatebooleanCreate permission
allowReadbooleanRead permission
allowEditbooleanEdit permission
allowDeletebooleanDelete permission
allowExportbooleanoptional[#3544] User-level export axis over read (opt-in grant). true = export granted (still bounded by read); unset/false = no export. Merged most-permissively like the CRUD bits; NOT implied by viewAllRecords/modifyAllRecords.
allowTransferboolean[RBAC-gated; ENFORCED now via insert/update owner_id guard, #3004] Change record ownership (assign/reassign/disown owner_id)
allowRestoreboolean[RBAC-gated; operation pending M2] Restore from trash (Undelete)
allowPurgeboolean[RBAC-gated; operation pending M2] Permanently delete (Hard Delete/GDPR)
viewAllRecordsbooleanView All Data (Bypass Sharing)
modifyAllRecordsbooleanModify All Data (Bypass Sharing) — bypasses sharing rules and ownership on the objects record sharing enforces on; on an object with NO owner field sharing abstains, so the platform created_by write floor still applies (#6698).
readScopeEnum<'own' | 'own_and_reports' | 'unit' | 'unit_and_below' | 'org'>optional[ADR-0057 D1] Read depth: own|unit|unit_and_below|org
writeScopeEnum<'own' | 'own_and_reports' | 'unit' | 'unit_and_below' | 'org'>optional[ADR-0057 D1] Write depth: own|unit|unit_and_below|org

PermissionSet

Properties

PropertyTypeRequiredDescription
namestringPermission set unique name (lowercase snake_case)
labelstringoptionalDisplay label
descriptionstringoptionalHuman-readable description shown in Setup (persisted as sys_permission_set.description)
packageIdstringoptional[ADR-0086 D3] Owning package id for a package-shipped set (absent = env-authored)
managedByEnum<'package' | 'platform' | 'user'>optional[ADR-0086 D3] Record provenance: package (upgrade-owned metadata) vs platform/user (env config)
isDefaultboolean[ADR-0090 D5] App baseline for the everyone position: app-level sets are auto-bound at boot (guarded, idempotent); package-level sets become install-time suggestions an admin confirms
objectsRecord<string, { allowCreate: boolean; allowRead: boolean; allowEdit: boolean; allowDelete: boolean; … }>Entity permissions
fieldsRecord<string, { readable: boolean; editable: boolean }>optionalField level security
systemPermissionsstring[]optionalSystem level capabilities
tabPermissionsRecord<string, Enum<'visible' | 'hidden' | 'default_on' | 'default_off'>>optionalApp/tab visibility: visible, hidden, default_on (shown by default), default_off (available but hidden initially)
rowLevelSecurity{ name: string; label?: string; description?: string; object: string; … }[]optionalRow-level security policies (see rls.zod.ts for full spec)
adminScope{ businessUnit: string; includeSubtree: boolean; manageAssignments: boolean; manageBindings: boolean; … }optional[ADR-0090 D12] Scoped delegated-administration grant (BU subtree + assignable-set allowlist)
protection{ lock: Enum<'none' | 'no-overlay' | 'no-delete' | 'full'>; reason: string; docsUrl?: string }optionalPackage author protection block — lock policy for this permission set.
_lockEnum<'none' | 'no-overlay' | 'no-delete' | 'full'>optionalItem-level lock — controls overlay & delete (ADR-0010).
_lockReasonstringoptionalHuman-readable reason shown when a write is refused by _lock.
_lockSourceEnum<'artifact' | 'package' | 'env-forced'>optionalLayer that set _lock (artifact | package | env-forced).
_provenanceEnum<'package' | 'org' | 'env-forced'>optionalOrigin of the item (package | org | env-forced).
_packageIdstringoptionalOwning package machine id.
_packageVersionstringoptionalOwning package version.
_lockDocsUrlstringoptionalOptional documentation link surfaced next to _lockReason.

On this page