Skip to content
API Now! is currently in closed beta. We are constantly updating these guides as we release updates!

Match Resource Attribute

The Match Resource Attribute (matchResourceAttribute) access rule restricts operations and filters data based on the attributes of the target record itself (such as status == 'published', is_active == true, stock > 0, or category in ['books', 'electronics']).

While Match User Property inspects attributes on the caller (e.g. department or subscription tier), Match Resource Attribute inspects the state of the data record being accessed.


  • Dual-Phase Execution:
    • Collection Queries (list, search) in FETCH Phase: Automatically injects SQL WHERE clauses into the database query, ensuring users only retrieve matching records without performance overhead.
    • Single-Record Detail Actions (read, update, delete) in POST_FETCH Phase: Evaluates the loaded record in memory before returning or mutating it.
  • Fail-Fast Projection Safety: If an API endpoint uses field projections, the engine ensures the filtered attribute is always selected from the database so security checks cannot be bypassed.
PropertySpecification
Rule TypematchResourceAttribute
Identity Constrainingfalse (Must be paired with an identity rule in the same scenario)
Supported StrategiesAll strategies (RBAC, OrganizationRBAC, EnterpriseRBAC)
Allowed Placement LevelsExposed Entity Level (exposure), Action Level (action) (Not allowed at global API Model Level)
Execution PhasesFETCH (list, search), POST_FETCH (read, update, delete, link, unlink)

Must Be Paired with an Identity Rule

Because Match Resource Attribute inspects data attributes rather than user identity, it cannot exist as the only rule in an Access Scenario. Every scenario containing Match Resource Attribute must also include at least one identity-constraining rule (such as Allow Public, Allow Authenticated, Match User Role, or Match Resource Owner).


When configuring Match Resource Attribute, you select the target entity property, a comparison operator, and an expected value:

  • equal (==): Record attribute must match the value (e.g. status equal 'published', is_active equal true).
  • notEqual (!=): Record attribute must not match the value (e.g. status notEqual 'archived').
  • in: Record attribute must be one of the specified list values (e.g. status in ['draft', 'published']).
  • notIn: Record attribute must not be in the specified list (e.g. status notIn ['archived', 'banned']).

3. String Matching (with Automatic Wildcard Escaping)

Section titled “3. String Matching (with Automatic Wildcard Escaping)”
  • startsWith: String begins with prefix (e.g. sku startsWith 'PRO-').
  • endsWith: String ends with suffix (e.g. file_format endsWith '.pdf').
  • contains: String contains substring (e.g. tags contains 'featured').
  • greaterThan (>) & greaterThanOrEqual (>=): Numeric value meets or exceeds threshold (e.g. stock_count > 0, rating >= 4.0).
  • lessThan (<) & lessThanOrEqual (<=): Numeric value is at or below threshold (e.g. price_cents <= 0 for free tier items).

Pattern 1: Public Read of Published Content (Staff Full View)

Section titled “Pattern 1: Public Read of Published Content (Staff Full View)”

Allow public visitors to see only published articles, while editorial staff see drafts and archived items:

Article.list Scenarios:
├── Scenario 1 (Editorial Staff):
│ └── Match User Role: ['editor', 'admin'] <- Staff see all articles (no status filter)
└── Scenario 2 (Public Visitors):
├── Allow Public <- Identity rule (open to public)
└── Match Resource Attribute (status == 'published') <- FETCH injects WHERE status = 'published'

Pattern 2: Ownership + State Gating (Drafts-Only Deletion)

Section titled “Pattern 2: Ownership + State Gating (Drafts-Only Deletion)”

Allow authors to delete their own articles, but only while in draft status. Once published or archived, only an administrator can delete them:

graph TD
    subgraph "Article.delete Endpoint"
        S1["Scenario 1: Match User Role (admin)"] --> Adm["Admins delete any article"]
        S2["Scenario 2: Match Resource Owner + status == 'draft'"] --> Auth["Author deletes own draft"]
        Blocked["Author tries to delete published article"] --> Denied["403 Forbidden"]
    end

Pattern 3: Composite Multi-Attribute Gating (AND Logic)

Section titled “Pattern 3: Composite Multi-Attribute Gating (AND Logic)”

Include multiple attribute rules inside the same scenario to enforce compound conditions:

Product.read Scenario (Public Active & In-Stock):
├── Allow Public
├── Match Resource Attribute: is_active == true
└── Match Resource Attribute: stock_count > 0

Both attribute rules must pass. On list actions, the engine combines them into WHERE is_active = true AND stock_count > 0.


Caller StateResource StateResulting HTTP Status
Anonymous (Public Scenario)Resource matches attribute criteria (e.g. status == 'published')200 OK
Anonymous (Public Scenario)Resource does not match attribute criteria (e.g. status == 'draft')403 Forbidden
Authenticated (Staff Scenario)Resource is in any state (draft/archived)200 OK / 204 No Content
Author (Draft Scenario)Author tries to modify/delete an archived article (status != 'archived' fails)403 Forbidden
Resource Not FoundRecord ID does not exist in the database404 Not Found