Skip to main content

Check permissions with permit.check()

Call permit.check() from your backend to decide whether a user can perform an action on a resource. This page is for developers adding enforcement to an application. It covers the arguments, then shows checks for role-based access control (RBAC), tenants, attribute-based access control (ABAC), relationship-based access control (ReBAC), custom policy context, and the policy decision point (PDP) HTTP API.

Prerequisites

The examples on this page use the Node.js SDK. The other Permit SDKs take the same arguments: permit.check() in Python and Java, and permit.Check() in Go.

permit.check() arguments and result

ArgumentTypeRequiredDescription
userstring or objectYesThe user key (for example, the sub claim of the user's JWT), or an object with key and optional attributes.
actionstringYesThe action the user attempts, for example create.
resourcestring or objectYesA resource type (document), a resource instance (document:123), or an object with type, optional key, optional tenant, and optional attributes.
contextobjectNoExtra data for the policy evaluation, used by custom policy code.

permit.check() returns a boolean: true when the policy allows the action, false when it doesn't.

Pick the narrowest check that fits

Pass only the data your policy needs. A check on a resource type is enough for RBAC. Add a tenant, attributes, or an instance key only when the policy depends on them.

Check an RBAC permission

An RBAC check needs three arguments: the user key, the action, and the resource type. The PDP returns true when one of the user's roles grants the action on the resource type.

const permitted = await permit.check("john@permit.io", "create", "document");

if (permitted) {
console.log("John is PERMITTED to create a document");
} else {
console.log("John is NOT PERMITTED to create a document");
}

When John has a role that grants create on document, the example prints John is PERMITTED to create a document.

Check a permission in a tenant

A tenant is an isolated group of users and resources. The same user can hold a different role in each tenant, for example admin in companyA and editor in companyB.

To check a permission in one tenant, pass the tenant key in the resource object:

const permitted = await permit.check("john@permit.io", "create", {
type: "document",
tenant: "companyA",
});

The PDP evaluates only John's role assignments in companyA.

Check an ABAC permission with attributes

ABAC policies decide access by comparing user, resource, or tenant attributes to the conditions in your user sets and resource sets. The check passes when the attributes meet the conditions of a rule that grants the action.

Pass attributes in the user object and the resource object:

const permitted = await permit.check(
// the user object
{
// the user key
key: "john@permit.io",
// just-in-time user attributes
attributes: {
location: "England",
department: "Engineering",
},
},
// the action the user is trying to do
"create",
// Resource
{
// the type of the resource (the resource key)
type: "document",
// just-in-time resource attributes
attributes: {
hasApproval: "true",
},
// the tenant the resource belongs to
tenant: "companyB",
}
);
ABAC needs a container PDP

The Cloud PDP doesn't evaluate ABAC policies. Run a container PDP for attribute-based checks. See Cloud PDP capabilities.

To store attributes in Permit instead of passing them on every check, see Load custom data.

Pass just-in-time (JIT) attributes

Just-in-time (JIT) attributes are attribute values you pass in permit.check() at request time. Use JIT attributes when a value changes per request, such as the location the user signs in from. The attribute must already be defined in your policy.

For a policy such as the following:

A document can only be accessed by users from EU and UK

Pass the user's current location as a JIT attribute:

const permitted = await permit.check(
{
key: "john@smith.com",
attributes: {
location: location, // With location being a variable extracted from your logged user
},
},
"access",
"document"
);

For other ways to load attributes, see Load custom data.

Check a ReBAC permission on a resource instance

ReBAC policies grant access through relationships between users and resource instances, such as a user's role on a specific group or folder. Define the resource roles and relations in the ReBAC policy editor or through the ReBAC API.

To check a ReBAC permission, pass a resource instance in the type:key format. This check asks whether the user can perform assign on one member_group instance:

await permit.check(userId, "assign", `member_group:${group}`);

This check asks whether the user can perform assign on the document instance doc1.txt:

await permit.check(userId, "assign", `document:doc1.txt`);

The PDP returns true when the user has a role on the instance, or a role derived through a relation, that grants the action.

Pass a context object

The context argument passes extra data to custom policy code. The PDP includes the context in the policy input, so your Rego rules can read the values.

await permit.check(user, "create", "document", {
// additional data to be passed to the policy evaluation
totalDocuments: 100,
});

In the Node.js SDK, the fourth argument of permit.check() is the context object itself.

Call the PDP API directly

Without an SDK, send the check to the PDP's POST /allowed endpoint. Pass your environment API key in the Authorization: Bearer header and the check in the JSON body.

curl -X POST https://<your-permit-pdp-url>/allowed \
-H "Content-Type: application/json" \
-H "Authorization: Bearer <your-permit-api-key>" \
-d '{
"user": "john@doe.me",
"action": "create",
"resource": {
"type": "document",
"tenant": "companyA"
},
"context": {}
}'

Replace <your-permit-pdp-url> with the address of your container PDP (for example, http://localhost:7766) or the Cloud PDP (https://cloudpdp.api.permit.io).

The response body contains an allow field. "allow": true means the user is permitted.

Send checks to a PDP, not to api.permit.io

The /allowed endpoint exists only on a PDP. A request to https://api.permit.io/allowed doesn't return a decision.

Next steps