Skip to content

Commit 191fbd2

Browse files
committed
docs(permissions): add allowExport to the bit matrix and carve the super-user exception
The permissions matrix is the canonical hand-written table of object permission bits, and it had no `allowExport` row. Worse, its super-user bypass callout is exactly the sentence this axis carves an exception into: neither VAMA bit confers export, so an admin can read every record and still be refused a bulk copy. Left as-is it would read as "admins automatically have export", which is now false. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01PDbwCy9Jrc1chhR2vnAUos
1 parent b96345e commit 191fbd2

1 file changed

Lines changed: 9 additions & 0 deletions

File tree

content/docs/permissions/permissions-matrix.mdx

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ ObjectStack's `ObjectPermission` schema defines these boolean flags for object a
2323
| **Create** | `allowCreate` | Create new records | Insert records |
2424
| **Edit** | `allowEdit` | Modify records owned by the user or shared with them | Edit own records |
2525
| **Delete** | `allowDelete` | Remove records owned by the user or shared with them | Delete own records |
26+
| **Export** | `allowExport` | Take a bulk machine-readable copy of the records the user can read | Export / bulk egress ([details](/docs/permissions/permission-sets#allowexport--the-export-axis)) |
2627
| **Transfer** | `allowTransfer` | Change record ownership | Reassign owner |
2728
| **Restore** | `allowRestore` | Undelete from trash | Recover soft-deleted records |
2829
| **Purge** | `allowPurge` | Permanently (hard) delete | GDPR / compliance erase |
@@ -32,6 +33,14 @@ ObjectStack's `ObjectPermission` schema defines these boolean flags for object a
3233
<Callout type="tip">
3334
**Super-user bypass:** When `modifyAllRecords` is set it satisfies write checks (`allowEdit`/`allowDelete`, and the lifecycle class `allowTransfer`/`allowRestore`/`allowPurge`) on any record; `viewAllRecords` (or `modifyAllRecords`) satisfies `allowRead` on any record — both bypass ownership and sharing. See `packages/plugins/plugin-security/src/permission-evaluator.ts`.
3435

36+
**The one exception is `allowExport`.** Neither super-user bit confers it: a
37+
principal with View/Modify All Data may read every record and still be refused a
38+
bulk copy of them. Export is an opt-in grant that must be stated explicitly —
39+
separating "may see all data" from "may take a bulk copy of it" is the
40+
segregation-of-duties case the axis exists for. The built-in
41+
`admin_full_access` / `organization_admin` sets therefore carry
42+
`allowExport: true` alongside their super-user bits.
43+
3544
The bypass is **posture-gated for row-level security** (ADR-0066 D2 ①): RLS
3645
policies are short-circuited only on objects whose posture permits it —
3746
`access: { default: 'private' }`, `tenancy.enabled: false`

0 commit comments

Comments
 (0)