Skip to main content

Condition set rule example

Build a complete attribute-based access control (ABAC) policy with the Permit API: one user set, one resource set, and one condition set rule. This page is for developers who have read Create condition sets with the API and want a worked example to adapt.

Every command replaces <YOUR_API_KEY> with your environment API key, and {proj_id} and {env_id} with your project and environment keys or IDs.

Example policy: full-time students rent bicycles after 5 PM

Policy statement

Full-time students of Stanford University, a fictional university in this example, can rent the university's bicycles after 5 PM.

The policy breaks down into three parts:

PartDefinitionKey
User setUsers whose university attribute is Stanford, whose is_full_time attribute is true, and whose current_hour is 17 (5 PM) or laterfull_time_students_after_5
ActionRent a bicyclebicycle:rent
Resource setBicycles whose owner attribute is universityuniversity_bicycles

The time of the request belongs in the user set, not in the resource set: 5 PM is a property of the request, not of a bicycle. Your application reads the clock and sends the hour as the current_hour user attribute in each permit.check() call, the way the time-based role example sends current_time. A resource attribute would hold whatever value was last written to the bicycle, so it could not express "after 5 PM".

Prerequisites

  • An environment API key. See Get your API key.
  • A bicycle resource with a rent action and an owner resource attribute of type string.
  • Three user attributes: university (string), is_full_time (boolean), and current_hour (number). See Define attributes.
  • A user in the environment to run the final check for, for example john@permit.io. See Sync users.
  • A running Edge PDP (policy decision point) and an SDK connected to it, for the final check. See Run the PDP.

1. Create the user set

Create the user set with a POST request to the condition sets endpoint. The allOf operator requires all three conditions: the user studies at Stanford, studies full time, and sends a current_hour of 17 or later with the check. Replace <YOUR_API_KEY> with your environment API key, and {proj_id} and {env_id} with your project and environment keys.

full_time_students_after_5
curl 'https://api.permit.io/v2/schema/{proj_id}/{env_id}/condition_sets' \
-X POST \
-H 'Authorization: Bearer <YOUR_API_KEY>' \
-H 'Content-Type: application/json' \
-d '{
"key": "full_time_students_after_5",
"name": "Full-time Stanford students after 5 PM",
"type": "userset",
"conditions": {
"allOf": [
{"user.university": {"equals": "Stanford"}},
{"user.is_full_time": {"equals": true}},
{"user.current_hour": {"greater-than-equals": 17}}
]
}
}'

The API returns HTTP 200 and the created set: the key, name, type, and conditions you sent, plus the id Permit assigned and the organization_id, project_id, environment_id, created_at, and updated_at fields. An HTTP 422 response means the body has an unknown operator or the wrong shape, and the response names the field that failed.

2. Create the resource set

Create the resource set with a POST request to the same condition sets endpoint, POST /v2/schema/{proj_id}/{env_id}/condition_sets. The resource_id field ties the set to the bicycle resource, and the condition narrows the set to the bicycles the university owns.

university_bicycles
curl 'https://api.permit.io/v2/schema/{proj_id}/{env_id}/condition_sets' \
-X POST \
-H 'Authorization: Bearer <YOUR_API_KEY>' \
-H 'Content-Type: application/json' \
-d '{
"key": "university_bicycles",
"name": "University bicycles",
"type": "resourceset",
"resource_id": "bicycle",
"conditions": {
"allOf": [
{"resource.owner": {"equals": "university"}}
]
}
}'

3. Create the condition set rule

The rule grants bicycle:rent to the user set on the resource set. It references both sets by key, so create the sets first.

bicycle:rent set rule
curl 'https://api.permit.io/v2/facts/{proj_id}/{env_id}/set_rules' \
-X POST \
-H 'Authorization: Bearer <YOUR_API_KEY>' \
-H 'Content-Type: application/json' \
-d '{
"user_set": "full_time_students_after_5",
"permission": "bicycle:rent",
"resource_set": "university_bicycles"
}'

4. Verify the policy

List the rules of the user set:

curl -G 'https://api.permit.io/v2/facts/{proj_id}/{env_id}/set_rules' \
-H 'Authorization: Bearer <YOUR_API_KEY>' \
--data-urlencode 'user_set=full_time_students_after_5'

The response is an array with one rule. Each rule also carries the id, key, organization_id, project_id, environment_id, created_at, and updated_at fields that Permit assigns:

[
{
"user_set": "full_time_students_after_5",
"permission": "bicycle:rent",
"resource_set": "university_bicycles"
}
]

Then run a permission check that passes the attributes the two sets read.

ABAC checks need an Edge PDP

The Cloud PDP does not evaluate ABAC condition sets. A check that depends on a user set or a resource set returns false there, with the cloud_pdp_not_supporting_abac denial code in the decision log. Send the check to an Edge PDP instead. See Cloud PDP capabilities.

Create the SDK client with your environment API key and the address of your Edge PDP:

const { Permit } = require("permitio");

const permit = new Permit({
token: "<YOUR_API_KEY>",
pdp: "http://localhost:7766",
});

Run the check in your Node.js code. The call passes the three user attributes in the user argument and the owner resource attribute in the resource argument:

const permitted = await permit.check(
{
key: "john@permit.io",
attributes: {
university: "Stanford",
is_full_time: true,
current_hour: 18,
},
},
"rent",
{
type: "bicycle",
tenant: "default",
attributes: { owner: "university" },
}
);

permitted is true: the user matches full_time_students_after_5, the bicycle matches university_bicycles, and the rule grants bicycle:rent between them. Change current_hour to 9 and run the same check, and permitted is false, because the user no longer matches the user set. For the same call in other languages, see Check permissions.

Next steps