What is Attribute Based Access Control (ABAC)?
Attribute-Based Access Control (ABAC) is like a security guard that decides who gets to access what based on specific characteristics or “attributes”. These attributes can be associated with users, resources, or the environment, and their values can influence the outcome of an access request. Let’s make an analogy, it’s the best way to understand complex ideas. Think about an amusement park, and there are 3 different rides. In order to access each ride, you need to have different qualities. For example:- ride one you need to be over 6ft tall.
- ride two you need to be under 200lbs.
- ride three you need to be between 12 - 18 years old.
Why Would Need ABAC?
It’s obvious but the simple answer is “use cases”… Sometimes, using ReBAC and RBAC isn’t the best fit for the job. It’s like using winter tires on a hot desert road, or summer tires in a snowstorm - they’re just not the right tools for the conditions.- Geographically Restricted: Think of ABAC like a bouncer at a club who only lets in people from certain towns. For example, a movie streaming service might only show certain movies in certain countries because of rules about who can watch what and where.
- Time-Based: ABAC can also act like a parent setting rules about when you can use the computer. For example, a system might only let you do certain things during office hours.
- Compliance with Privacy Regulations: ABAC can help follow rules about privacy. For example, a hospital system might need to limit who can see a patient’s data based on the patient’s permission, why they want to see it, and who the person is.
- Limit Range: ABAC can help you create a rules defining a number limit or range. For instance, a banking system might have limits for wiring or withdrawing money.
- Device Information: ABAC can control access based on attributes of the device, such as the device type, operating system version, or whether the device has the latest security patches.
Modeling ABAC
To support ABAC in Permify, we’ve added two main components into our DSL: attributes and rules.Defining Attributes
Attributes are used to define properties for entities in specific data types. For instance, an attribute could be an IP range associated with an organization, defined as a string array:attribute
.
Defining Rules
Rules are structures that allow you to write specific conditions for the model. You can think rules as simple functions of every software language have. They accept parameters and are based on condition to return a true/false result. In the following example schema, a rule could be used to check if a given IP address falls within a specified IP range:We design our schema language based on Common Expression Language (CEL). So the syntax looks nearly identical to equivalent expressions in C++, Go, Java, and TypeScript.Please let us know via our Discord channel if you have questions regarding syntax, definitions or any operator you identify not working as expected.
Boolean - True/False Conditions
For attributes that represent a binary choice or state, such as a yes/no question, theBoolean
data type is an excellent choice.
Text & Object Based Conditions
String can be used as attribute data type in a variety of scenarios where text-based information is needed to make access control decisions. Here are a few examples:- Location: If you need to control access based on geographical location, you might have a location attribute (e.g., “USA”, “EU”, “Asia”) stored as a string.
- Device Type: If access control decisions need to consider the type of device being used, a device type attribute (e.g., “mobile”, “desktop”, “tablet”) could be stored as a string.
- Time Zone: If access needs to be controlled based on time zones, a time zone attribute (e.g., “EST”, “PST”, “GMT”) could be stored as a string.
- Day of the Week: In a scenario where access to certain resources is determined by the day of the week, the string data type can be used to represent these days (e.g., “Monday”, “Tuesday”, etc.) as attributes!
This schema works correctly in versions above v1.1. If you are using an earlier version, please refer to the version differences here.
Numerical Conditions
Integers
Integer can be used as attribute data type in several scenarios where numerical information is needed to make access control decisions. Here are a few examples:- Age: If access to certain resources is age-restricted, an age attribute stored as an integer can be used to control access.
- Security Clearance Level: In a system where users have different security clearance levels, these levels can be stored as integer attributes (e.g., 1, 2, 3 with 3 being the highest clearance).
- Resource Size or Length: If access to resources is controlled based on their size or length (like a document’s length or a file’s size), these can be stored as integer attributes.
- Version Number: If access control decisions need to consider the version number of a resource (like a software version or a document revision), these can be stored as integer attributes.
This schema works correctly in versions above v1.1. If you are using an earlier version, please refer to the version differences here.
Double - Precise numerical information
Double can be used as attribute data type in several scenarios where precise numerical information is needed to make access control decisions. Here are a few examples:- Usage Limit: If a user has a usage limit (like the amount of storage they can use or the amount of data they can download), and this limit needs to be represented with decimal precision, it can be stored as a double attribute.
- Transaction Amount: In a financial system, if access control decisions need to consider the amount of a transaction, and this amount needs to be represented with decimal precision (like $100.50), these amounts can be stored as double attributes.
- User Rating: If access control decisions need to consider a user’s rating (like a rating out of 5 with decimal points, such as 4.7), these ratings can be stored as double attributes.
- Geolocation: If access control decisions need to consider precise geographical coordinates (like latitude and longitude, which are often represented with decimal points), these coordinates can be stored as double attributes.
This schema works correctly in versions above v1.1. If you are using an earlier version, please refer to the version differences here.
Example Use Cases
Example of Public/Private Repository
In this example,is_public
is defined as a boolean attribute. If an attribute is a boolean, it can be directly used without the need for a rule. This is only applicable for boolean types.
is_public
attribute of the repository is set to true, everyone can view it. If it’s not public (i.e., is_public
is false), only the owner, in this case user:1
, can view it.
The permissions in this model are defined as such:
permission view = is_public or owner
This means that the ‘view’ permission is granted if either the repository is public (is_public
is true) or if the current user is the owner of the repository.
relationships:
- post:1#owner@user:1
- post:1$is_public|boolean:true
check*{snapshot}*{schema*version}*{context}\_post:1$is_public
→ truecheck*{snapshot}*{schema*version}*{context}\_post:1#admin@user:1
→ true
Example of Weekday
In this example, to be able to view the repository it must not be a weekend, and the user must be a member of the organization.This schema works correctly in versions above v1.1. If you are using an earlier version, please refer to the version differences here.
day_of_week
) must not be a weekend (determined by the is_weekday
rule), and the user must be a member of the organization that owns the repository.
Relationships:
- organization:1#member@user:1
check*{snapshot}*{schema*version}*{context}\_organization:1$is_weekday(valid_weekdays)
→ truecheck*{snapshot}*{schema*version}*{context}\_post:1#member@user:1
→ true
Example of Banking System
This model represents a banking system with two entities:user
and account
.
user
: Represents a customer of the bank.account
: Represents a bank account that has anowner
(which is auser
), and abalance
(amount of money in the account).
This schema works correctly in versions above v1.1. If you are using an earlier version, please refer to the version differences here.
withdraw
permission to be granted. In other words, a user can withdraw money from an account only if they are the owner of that account, and the amount they want to withdraw is within the account balance and doesn’t exceed 5000.
Relationships
- account:1#owner@user:1
- account:1$balance|double:4000
check*{snapshot}*{schema*version}*{context}\_account:1$check_balance(balance)
→ truecheck*{snapshot}*{schema*version}*{context}\_account:1#owner@user:1
→ true
Hierarchical Usage
In this model:employee
: Represents an individual worker. It has no specific attributes or relations in this case.organization
: Represents an entire organization, which has afounding_year
attribute. Theview
permission is granted if thecheck_founding_year
rule (which checks if the organization was founded after 2000) returns true.department
: Represents a department within the organization. It has abudget
attribute and a relation to its parentorganization
. Theview
permission is granted if the department’s budget is more than 10,000 (checked by thecheck_budget
rule) and if theorganization.view
permission is true.
organization.view
). However, you cannot use the attribute of a relation in this way. For example, you cannot directly reference organization.founding_year
in a permission expression. Permissions can depend on permissions in a related entity, but not directly on the related entity’s attributes.
- department:1#organization@organization:1
- department:1#organization@organization:2
- department:1$budget|double:20000
- organization:1$organization|integer:2021
check*{snapshot}*{schema*version}*{context}\_department:1$check_budget(budget)
→ truecheck*{snapshot}*{schema*version}*{context}\_organization:2$check_founding_year(founding_year)
→ falsecheck*{snapshot}*{schema*version}*{context}\_organization:1$check_founding_year(founding_year)
→ true
Evaluation of ABAC Access Checks
ModelThis schema works correctly in versions above v1.1. If you are using an earlier version, please refer to the version differences here.
- organization:1#admin@user:1
- organization:1$ip_range|string[]:[‘187.182.51.206’, ‘250.89.38.115’]
check*{snapshot}*{schema*version}*{context}\_organization:1#admin@user:1
→ truecheck*{snapshot}*{schema*version}*{context}\_organization:1$check_ip_range(ip_range)
→ true
How To Use ABAC
Install Permifydelete
permission rule is set. It calls the function is_weekday
with the value of valid_weekdays
from the related entity. If is_weekday(["monday", "tuesday", "wednesday", "thursday", "friday"])
is true, the delete permission is granted.
Create Validation File
This schema works correctly in versions above v1.1. If you are using an earlier version, please refer to the version differences here.