Skip to main content
Attribute-Based Access Control (ABAC) is the right choice when access decisions depend on properties of the user, resource, or environment rather than on static roles or entity relationships alone. Where RBAC asks “what role does this user have?” and ReBAC asks “how is this user related to this resource?”, ABAC asks “do the attributes of this request satisfy these conditions?” In Permify, ABAC is implemented with two schema constructs: attributes (typed properties attached to entities) and rules (boolean functions that evaluate those attributes, optionally against request context).

When to use ABAC

  • Access depends on a property of a resource (e.g., is_public, min_age, region).
  • Access depends on runtime context supplied in the request (e.g., current IP address, day of the week).
  • You need to express numerical ranges or set membership (e.g., balance limits, allowed locations).
  • Compliance rules require evaluating a combination of user, resource, and environmental attributes.
ABAC composes with RBAC and ReBAC in a single Permify schema. You can, for example, require both a valid IP range (ABAC) and organization membership (ReBAC) in the same action.

Core constructs

Attributes

Attributes define typed properties on an entity. Permify supports the following attribute types:
Declare an attribute inside an entity block:

Rules

Rules are named boolean functions written in Common Expression Language (CEL). They accept the entity attribute (and optionally context.data fields from the request) and return true or false.
A rule is referenced inside an action (or permission) expression:
Boolean attributes are the one exception: they can be used directly in a permission expression without a wrapping rule, because their value is the condition. All other attribute types require a rule.

Example: public/private content

A boolean attribute can gate access with no rule required.
If post:1$is_public|boolean:true, any user can view it. If false, only the owner can.

Example: age-restricted content

An integer attribute combined with a rule enforces a minimum age requirement supplied in the request context.
The caller passes the user’s age in the context.data field of the check request. The rule evaluates context.data.age >= min_age at query time.

Example: IP range restriction

This example combines a ReBAC rule (admin role) with an ABAC rule (IP allow-list) using or.

Write the attribute

cURL

Check with context

Pass the user’s current IP address in context.data:
cURL
Response
If the IP were not in the ip_range attribute, and user:2 is not an admin, the response would be RESULT_DENIED.

Example: weekday-based access

A string[] attribute holds an allow-list of valid days; the rule checks the request context.
To view a repository, the current day must be in valid_weekdays and the user must be a member of the owning organization. Both conditions are required.

Example: banking withdrawal limit

A double attribute stores the account balance; the rule enforces both a balance check and a per-transaction cap.
A withdrawal is allowed only if the user owns the account and the requested amount does not exceed both the current balance and the 5,000 per-transaction cap.

Hierarchical ABAC

Attribute rules can depend on permissions from parent entities. This lets you express conditions like “a department is viewable only if its budget exceeds 10,000 and its parent organization was founded after 2000”.
department.view requires check_budget to pass and the parent organization.view permission to be allowed. Permify evaluates the full chain.
You can reference a parent entity’s permission (e.g., organization.view) from a child entity’s action. You cannot directly reference the parent entity’s attribute (e.g., organization.founding_year) — only permissions traverse entity boundaries.

Building RBAC Systems

Start with static roles before adding attribute-based conditions.

Building ReBAC Systems

Combine relationship traversal with attribute checks for fine-grained rules.

Modeling guide

Full reference for attributes, rules, and all schema DSL constructs.

Testing

Write validation files that assert permission outcomes including context data.