Constructive Access Control
The access control model — how users get capabilities, how roles and profiles organize them, and how access composes across scopes. This skill covers the semantic layer: what access means in a Constructive app, how to configure it via blueprints and the ORM, and how the different layers (roles, profiles, grants, defaults) compose into effective access.
Naming: a capability is the named unit of access — every table, column, ORM model, blueprint argument, and module name uses that spelling (appCapability, capabilities_module, capabilities: […]). Permission appears only as a value of a capability's kind column, distinguishing a granted access right from an earned trust level.
For application UI, the App access and Organizations feature packs expose the corresponding membership, invitation, profile, capability, and default-management surfaces. Use constructive-blocks for installation, standalone host contracts, and Console module discovery and adapters; this skill remains the authority for access semantics.
When to Apply
Use this skill when:
- Defining what capabilities users should have in an app
- Creating custom roles via profiles (Editor, Viewer, Manager, etc.)
- Configuring which capabilities new members receive automatically
- Understanding how admin/owner/member roles differ, and why they hold every capability
- Granting or revoking capabilities for individual members
- Setting up entity-scoped access (app vs org vs custom entity)
- Assigning profiles to memberships via invites or direct assignment
- Understanding effective capability resolution (grants + profiles)
- Deciding where to gate something an org owner must not bypass
Relationship to Other Skills
| Skill |
Focus |
This skill covers |
constructive-security |
Enforcement — Authz* policies, RLS, how access is enforced at the database level |
Model — what access exists, who gets it, how it composes |
constructive-entities |
Structure — entity types, multi-tenancy, provisioning |
Access within structure — how capabilities scope to entities |
constructive-events |
Earning — events, achievements, trust ladders that produce kind = 'level' capabilities |
Holding — what a level means once held |
constructive-auth |
Identity — login, sessions, MFA, devices |
Authorization — what authenticated users can do |
Access Control Layers
A Constructive app has four composable access layers:
┌─────────────────────────────────────────────┐
│ 1. Role (admin / owner / member) │ ← built-in, highest precedence
├─────────────────────────────────────────────┤
│ 2. Profile (named capability bundle) │ ← reusable role definitions
├─────────────────────────────────────────────┤
│ 3. Direct Grants (per-member overrides) │ ← individual adjustments
├─────────────────────────────────────────────┤
│ 4. Capability Defaults (module-level base) │ ← automatic on join
└─────────────────────────────────────────────┘
Effective capabilities = Role bypass OR (Profile capabilities ∪ Direct grants ∪ Defaults ∪ Earned levels)
Layer 1 is not a tiebreaker but a replacement: an admin or owner holds every capability in the scope, earned trust levels included. See admin-owner-member.md before designing anything that must constrain an owner.
Quick Reference
Enabling Access Control in Blueprints
{
"entity_types": [
{
"name": "Organization",
"prefix": "org",
"hasProfiles": true
}
]
}
Every entity type automatically gets a capabilities_module and memberships_module. Setting hasProfiles: true additionally provisions the profiles system for that scope.
ORM Tables by Scope
| Scope |
Capabilities |
Grants |
Profiles |
Memberships |
Defaults |
| App |
appCapability |
appGrant |
appProfile |
appMembership |
appCapabilityDefault |
| Org |
orgCapability |
orgGrant |
orgProfile |
orgMembership |
orgCapabilityDefault |
| Custom |
{prefix}Capability |
{prefix}Grant |
{prefix}Profile |
{prefix}Membership |
{prefix}CapabilityDefault |
Membership Fields
| Field |
Meaning |
granted |
What the member was given — defaults ∪ profile ∪ direct grants |
capabilities |
What the member effectively holds — equals granted, except for admins and owners, who hold everything |
References
| File |
Content |
| admin-owner-member.md |
Admin, owner, and member role semantics — owners/admins hold every capability including trust levels, grant tables, promotion/demotion, audit trail |
| roles-hierarchy.md |
Org hierarchy — chart edges, closure table traversal, AuthzOrgHierarchy policy, direction/depth |
| named-capabilities.md |
Named capability slots, the capability/level kinds, module registration, discovery |
| profiles.md |
Profile definitions, capability bundles, default profiles, system profiles |
| capability-defaults.md |
Automatic capabilities for new members, module defaults, overriding |
| entity-scoped-access.md |
App vs org vs custom entity scope, capability isolation, cross-scope patterns |
| grants-lifecycle.md |
Granting/revoking capabilities, effective capability computation, audit trail |
| membership-access.md |
Membership creation, invite-time assignment, state transitions, approval |
Cross-References
1---2name: constructive-access-control3description: Access control — roles, capabilities, profiles, grants, membership access, and entity-scoped authorization. Use when asked to 'assign capabilities', 'create roles', 'set up profiles', 'grant access', 'capability defaults', 'admin vs owner', 'membership capabilities', 'effective capabilities', 'revoke access', 'role hierarchy', 'custom roles', 'profile bundles', 'default profile', 'entity-scoped capabilities', 'org capabilities', 'app capabilities', 'capability resolution', 'trust levels', 'do owners get everything', or when working with the access control model in blueprints or the ORM.4---56# Constructive Access Control78The access control model — how users get capabilities, how roles and profiles organize them, and how access composes across scopes. This skill covers the semantic layer: what access means in a Constructive app, how to configure it via blueprints and the ORM, and how the different layers (roles, profiles, grants, defaults) compose into effective access.910> **Naming:** a **capability** is the named unit of access — every table, column, ORM model, blueprint argument, and module name uses that spelling (`appCapability`, `capabilities_module`, `capabilities: […]`). *Permission* appears only as a value of a capability's `kind` column, distinguishing a granted access right from an earned trust `level`.1112For application UI, the App access and Organizations feature packs expose the corresponding membership, invitation, profile, capability, and default-management surfaces. Use [`constructive-blocks`](../constructive-blocks/SKILL.md) for installation, standalone host contracts, and Console module discovery and adapters; this skill remains the authority for access semantics.1314## When to Apply1516Use this skill when:17- Defining what capabilities users should have in an app18- Creating custom roles via profiles (Editor, Viewer, Manager, etc.)19- Configuring which capabilities new members receive automatically20- Understanding how admin/owner/member roles differ, and why they hold every capability21- Granting or revoking capabilities for individual members22- Setting up entity-scoped access (app vs org vs custom entity)23- Assigning profiles to memberships via invites or direct assignment24- Understanding effective capability resolution (grants + profiles)25- Deciding where to gate something an org owner must not bypass2627## Relationship to Other Skills2829| Skill | Focus | This skill covers |30|-------|-------|-------------------|31| [`constructive-security`](../constructive-security/SKILL.md) | **Enforcement** — Authz* policies, RLS, how access is enforced at the database level | **Model** — what access exists, who gets it, how it composes |32| [`constructive-entities`](../constructive-entities/SKILL.md) | **Structure** — entity types, multi-tenancy, provisioning | **Access within structure** — how capabilities scope to entities |33| [`constructive-events`](../constructive-events/SKILL.md) | **Earning** — events, achievements, trust ladders that produce `kind = 'level'` capabilities | **Holding** — what a level means once held |34| [`constructive-auth`](../constructive-auth/SKILL.md) | **Identity** — login, sessions, MFA, devices | **Authorization** — what authenticated users can do |3536## Access Control Layers3738A Constructive app has four composable access layers:3940```41┌─────────────────────────────────────────────┐42│ 1. Role (admin / owner / member) │ ← built-in, highest precedence43├─────────────────────────────────────────────┤44│ 2. Profile (named capability bundle) │ ← reusable role definitions45├─────────────────────────────────────────────┤46│ 3. Direct Grants (per-member overrides) │ ← individual adjustments47├─────────────────────────────────────────────┤48│ 4. Capability Defaults (module-level base) │ ← automatic on join49└─────────────────────────────────────────────┘50```5152**Effective capabilities** = Role bypass OR (Profile capabilities ∪ Direct grants ∪ Defaults ∪ Earned levels)5354Layer 1 is not a tiebreaker but a replacement: an admin or owner holds **every** capability in the scope, earned trust levels included. See [admin-owner-member.md](./references/admin-owner-member.md#owner-and-admin-hold-every-capability) before designing anything that must constrain an owner.5556## Quick Reference5758### Enabling Access Control in Blueprints5960```json61{62 "entity_types": [63 {64 "name": "Organization",65 "prefix": "org",66 "hasProfiles": true67 }68 ]69}70```7172Every entity type automatically gets a `capabilities_module` and `memberships_module`. Setting `hasProfiles: true` additionally provisions the profiles system for that scope.7374### ORM Tables by Scope7576| Scope | Capabilities | Grants | Profiles | Memberships | Defaults |77|-------|--------------|--------|----------|-------------|----------|78| App | `appCapability` | `appGrant` | `appProfile` | `appMembership` | `appCapabilityDefault` |79| Org | `orgCapability` | `orgGrant` | `orgProfile` | `orgMembership` | `orgCapabilityDefault` |80| Custom | `{prefix}Capability` | `{prefix}Grant` | `{prefix}Profile` | `{prefix}Membership` | `{prefix}CapabilityDefault` |8182### Membership Fields8384| Field | Meaning |85|-------|---------|86| `granted` | What the member was given — defaults ∪ profile ∪ direct grants |87| `capabilities` | What the member effectively holds — equals `granted`, except for admins and owners, who hold everything |8889## References9091| File | Content |92|------|---------|93| [admin-owner-member.md](./references/admin-owner-member.md) | Admin, owner, and member role semantics — **owners/admins hold every capability including trust levels**, grant tables, promotion/demotion, audit trail |94| [roles-hierarchy.md](./references/roles-hierarchy.md) | Org hierarchy — chart edges, closure table traversal, AuthzOrgHierarchy policy, direction/depth |95| [named-capabilities.md](./references/named-capabilities.md) | Named capability slots, the `capability`/`level` kinds, module registration, discovery |96| [profiles.md](./references/profiles.md) | Profile definitions, capability bundles, default profiles, system profiles |97| [capability-defaults.md](./references/capability-defaults.md) | Automatic capabilities for new members, module defaults, overriding |98| [entity-scoped-access.md](./references/entity-scoped-access.md) | App vs org vs custom entity scope, capability isolation, cross-scope patterns |99| [grants-lifecycle.md](./references/grants-lifecycle.md) | Granting/revoking capabilities, effective capability computation, audit trail |100| [membership-access.md](./references/membership-access.md) | Membership creation, invite-time assignment, state transitions, approval |101102## Cross-References103104- **Enforcement details:** [`constructive-security`](../constructive-security/SKILL.md) — how capabilities translate into RLS policies105- **Entity provisioning:** [`constructive-entities`](../constructive-entities/SKILL.md) — creating entity types that carry capabilities106- **Earning levels:** [`constructive-events`](../constructive-events/SKILL.md) — trust ladders that produce `kind = 'level'` capabilities107- **Invite system:** [`constructive-entities` → invites.md](../constructive-entities/references/invites.md) — profile assignment on invite108- **Read-only access:** [`constructive-security` → read-only-access.md](../constructive-security/references/read-only-access.md) — `isReadOnly` membership field and read-only API keys109- **Billing/limits:** [`constructive-billing`](../constructive-billing/SKILL.md) — quota enforcement (separate from capability enforcement, and the right place for a limit an owner must not bypass)110- **App access and Organizations UI:** [`constructive-blocks`](../constructive-blocks/SKILL.md) — standalone host contracts plus Console module discovery and adapters