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:
| Part | Definition | Key |
|---|---|---|
| User set | Users whose university attribute is Stanford, whose is_full_time attribute is true, and whose current_hour is 17 (5 PM) or later | full_time_students_after_5 |
| Action | Rent a bicycle | bicycle:rent |
| Resource set | Bicycles whose owner attribute is university | university_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
bicycleresource with arentaction and anownerresource attribute of type string. - Three user attributes:
university(string),is_full_time(boolean), andcurrent_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.
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.
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.
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.
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
- Review all comparison operators to write other conditions.
- Build ABAC policies in the Policy Editor to see the same sets and rule in the dashboard.