Match Lifecycle Status
The Match Lifecycle Status (lifecycleStatus) access rule is a semantic-aware attribute rule designed for entities with a lifecycle state machine. It restricts access to resources based on whether their status is permitted by an allowlist (allowedStatuses) or blocked by a denylist (deniedStatuses).
Unlike generic attribute matching, Match Lifecycle Status automatically detects the property tagged with the Status semantic module on the target entity.
1. How It Works
Section titled “1. How It Works”- Semantic Status Binding: Automatically binds to the entity property annotated with the
Statussemantic module without needing manual column selection. - Dual-Phase Execution:
- Collection Actions (
list,search) inFETCHPhase: Automatically injects SQLWHERE status IN (...)orWHERE status NOT IN (...)clauses into the query. - Single-Record Actions (
read,update,delete) inPOST_FETCHPhase: Inspects the hydrated record’s status in memory before executing the mutation or returning data.
- Collection Actions (
- Deny-First Evaluation: If both
deniedStatusesandallowedStatusesare specified, the denylist is evaluated first for maximum security.
| Property | Specification |
|---|---|
| Rule Type | lifecycleStatus |
| Identity Constraining | false (Must be paired with an identity rule in the same scenario) |
| Supported Strategies | All strategies (RBAC, OrganizationRBAC, EnterpriseRBAC) |
| Allowed Placement Levels | Exposed Entity Level (exposure), Action Level (action) (Not allowed at global API Model Level) |
| Execution Phases | FETCH (list, search), POST_FETCH (read, update, delete, link, unlink) |
Must Be Paired with an Identity Rule
Because Match Lifecycle Status filters data based on resource state rather than caller identity, it cannot exist as the only rule in an Access Scenario. It must be paired with an identity rule (such as Allow Public, Allow Authenticated, Match User Role, or Match Resource Owner).
2. Configuration Options
Section titled “2. Configuration Options”When configuring Match Lifecycle Status, you can specify allowlists, denylists, or both:
1. Allowed Statuses (allowedStatuses)
Section titled “1. Allowed Statuses (allowedStatuses)”An array of status values permitted for this action.
- Example:
allowedStatuses: ['published'] - Behavior:
list/search: InjectsWHERE status IN ('published').read/update: Denies (403 Forbidden) if the record status is not'published'.
2. Denied Statuses (deniedStatuses)
Section titled “2. Denied Statuses (deniedStatuses)”An array of status values explicitly forbidden for this action.
- Example:
deniedStatuses: ['archived', 'banned'] - Behavior:
list/search: InjectsWHERE status NOT IN ('archived', 'banned').read/update: Denies (403 Forbidden) if the record status matches any denied value.
3. How List Queries and Filters Interact
Section titled “3. How List Queries and Filters Interact”On collection endpoints (list and search), Match Lifecycle Status injects SQL whereIn / whereNotIn clauses during the FETCH phase.
When API clients provide query parameter filters (such as GET /articles?status=draft), the database engine combines the client filter with the authorization rule using AND logic:
SELECT * FROM articlesWHERE (status = 'draft') AND (status IN ('in_review', 'published'))- Querying Permitted Statuses: If a client requests
GET /articles?status=published, matching published records are returned normally (200 OK). - Querying Forbidden Statuses: If a client requests
GET /articles?status=draftwhen only['in_review', 'published']are allowed, the query returns an empty list[](200 OK) because no records satisfy both constraints. The engine does not throw a 403 error on list filters, preventing data enumeration. - Direct Record Access by ID: In contrast, if a client attempts to fetch a single forbidden record directly (
GET /articles/:id), the single-record check inPOST_FETCHrejects the request with403 Forbidden.
4. Prerequisites in the Data Domain
Section titled “4. Prerequisites in the Data Domain”StatusSemantic Module: Exactly one property on the target entity must be tagged with theStatussemantic module in your Data Domain (e.g.Article.statuswith valuesdraft,in_review,published,archived).
5. Recommended Modeling Patterns
Section titled “5. Recommended Modeling Patterns”Pattern 1: Multi-Tier Content Visibility (Public vs. Reviewers vs. Admins)
Section titled “Pattern 1: Multi-Tier Content Visibility (Public vs. Reviewers vs. Admins)”Expose public content while allowing editorial staff to view review pipelines on the exact same GET /articles endpoint:
Article.list Scenarios:├── Scenario 1 (Admin Full View):│ └── Match User Role: ['admin'] <- Admins see all records├── Scenario 2 (Editorial Reviewers):│ ├── Match User Role: ['editor', 'reviewer']│ └── Match Lifecycle Status: allowedStatuses: ['in_review', 'published']└── Scenario 3 (Public Readers): ├── Allow Public └── Match Lifecycle Status: allowedStatuses: ['published'] <- Public sees published onlyPattern 2: Write-Locking Finalized Records (deniedStatuses)
Section titled “Pattern 2: Write-Locking Finalized Records (deniedStatuses)”Prevent authors from modifying invoices or documents once they reach a finalized or immutable state (e.g. paid, archived, settled):
graph TD
subgraph "Invoice.update Endpoint"
S1["Scenario 1: Match User Role (finance_admin)"] --> Adm["Admins can edit any invoice"]
S2["Scenario 2: Match Resource Owner + denied: [paid, void]"] --> Owner["Author can edit unpaid invoices"]
Blocked["Author tries to edit paid invoice"] --> Denied["403 Forbidden"]
end
Pattern 3: Drafts-Only Creator Deletion
Section titled “Pattern 3: Drafts-Only Creator Deletion”Allow authors to delete their own articles only while in draft state. Once submitted or published, deletion requires an administrator:
Article.delete Scenarios:├── Scenario 1 (Admin Override):│ └── Match User Role: ['admin'] <- Admins delete any article└── Scenario 2 (Author Drafts Only): ├── Allow Authenticated ├── Match Resource Owner (author) └── Match Lifecycle Status: allowedStatuses: ['draft'] <- Authors delete drafts only6. HTTP Status Codes Summary
Section titled “6. HTTP Status Codes Summary”| Caller State | Resource Lifecycle Status | Resulting HTTP Status |
|---|---|---|
| Anonymous (Public Scenario) | Status is in allowedStatuses (e.g. published) | 200 OK |
| Anonymous (Public Scenario) | Status is NOT in allowedStatuses (e.g. draft) | 403 Forbidden |
| Author (Draft Scenario) | Author tries to edit a record with status in deniedStatuses (e.g. archived) | 403 Forbidden |
| Admin (Admin Scenario) | Record is in any status | 200 OK / 204 No Content |
| Resource Not Found | Record ID does not exist | 404 Not Found |
Next Steps
Section titled “Next Steps”- Status Semantic Module: Data modeling reference for configuring status state machines and default states.
- Match Resource Attribute: General property matching for non-status fields.
- Match Resource Owner: Direct ownership checks for creator-owned records.
- Getting Started with Authorization: Core concepts of access scenarios and evaluation phases.