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 allow list (allowedStatuses) or blocked by a deny list (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 deny list is evaluated first for maximum security. - Separation from Creation Gating: This access rule evaluates existing records (
FETCHandPOST_FETCH). Constraining which states are allowed when creating new records is handled at the data layer by theStatussemantic module (initialStatusesand default values).
| 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, restore), POST_FETCH (read, update, delete, link, unlink) |
2. Configuration Options
Section titled “2. Configuration Options”When configuring Match Lifecycle Status, you can specify allow lists, deny lists, 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”When a team member browses or filters a collection of records (such as an editorial dashboard or support queue), two filters work together at the same time:
- The Security Rule (Access Rule): The permission boundary configured in API Now for their role. For example, an Editorial Reviewer might be permitted to see records in two active states:
in_reviewandpublished(allowedStatuses: ['in_review', 'published']). - The User’s Search Filter (URL Query Parameter): What the reviewer specifically asks to see in their dashboard right now (for example:
GET /articles?status=in_review).
The database combines both rules using AND logic: records are only returned if they match what the reviewer asked for AND what their security role permits.
Scenario A: Filtering for One of Their Permitted Statuses
Section titled “Scenario A: Filtering for One of Their Permitted Statuses”The reviewer wants to focus only on articles waiting for review and filters their dashboard with GET /articles?status=in_review:
- What the reviewer requested:
status = 'in_review' - What their role permits:
status IN ('in_review', 'published') - What the database looks for:
SELECT * FROM articlesWHERE (status = 'in_review')AND (status IN ('in_review', 'published'))
- Result: Success (
200 OK). The query narrows down the list and returns only the articles currently in review. The reviewer sees exactly what they asked for.
Scenario B: Filtering for a Status Outside Their Permissions
Section titled “Scenario B: Filtering for a Status Outside Their Permissions”The reviewer tries to filter for writers’ early personal drafts by requesting GET /articles?status=draft:
- What the reviewer requested:
status = 'draft' - What their role permits:
status IN ('in_review', 'published') - What the database looks for:
SELECT * FROM articlesWHERE (status = 'draft')AND (status IN ('in_review', 'published'))
- Result: Empty list
[](200 OK). Because no article can simultaneously be adraftand also bein_revieworpublished, the query simply finds zero matching items.
What Happens When Opening a Specific Record Directly?
Section titled “What Happens When Opening a Specific Record Directly?”Unlike search lists, if the reviewer tries to open a specific private record directly by its unique link or ID (such as GET /articles/art_10293 when that article is in draft):
- The system loads that specific record.
- It checks whether the reviewer’s role is allowed to view records in
draftstatus. - Because reviewers cannot view drafts, the request is immediately blocked with
403 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.