Skip to main content
Version: 2.0.0

Permit.check()

permit.check() is the main Authorize function to enforce permissions in your application.


The permit.check() function expects the following arguments in its basic form:

  • User - a user ID string or a user object representing the user attempting to perform an action.
  • Action - a string representing the action a user is attempting to perform.
  • Resource - a string or object representing the resource the user is attempting to perform the action on. A resource could point to a resource type or to a specific resource instance.
  • Context (optional) - a context object that can be used to pass additional data to the policy evaluation.

The permit.check() function returns a boolean value, indicating whether the user is permitted to perform the action on the resource.

tip

To maintain the least code changes in your application, you should carefully choose the most granular permit.check() function implementation that fits your use case.

The following examples demonstrate common permit.check() usage with a varied level of granularity:

Basic RBAC Check

The simplest enforcement point you can create using the permit.check() function is a Role-based Access Control (RBAC) policy.

To enforce RBAC, permit.check() requires three parameters to be passed:

  • A unique userId
  • An action this user will attempt to perform
  • The resource for which we want to manage access to.
info

While all examples on this page are written in JavaScript (Node.js SDK), the permit.check() function exists in all Permit SDKs.

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");
}

Tenants

Tenants are silos of resources and users. Tenants can be passed as part of the resource object inside the permit.check() function.

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

Say you have two tenants - Tenant A and Tenant B. The same user can be part of both tenants, with a different role in each one. I.e., The user can be admin in Tenant A and editor in Tenant B.

Attributes

Sometimes, you might require more granular policies than simple RBAC. That's when Attribute Based Access Control (ABAC) comes into play. Specific user or resource attributes might be required to determine the conditions of when your authorization check should pass. Each attribute is compared against a pre-defined value. If all of these comparisons pass, the authorization check will be approved.

Attributes can be declared as part of the user, resource, or tenant.

tip

You can learn more about passing data into Permit here

const permitted = await permit.check(
// the user object
{
// the user key
key: "john@permit.io",
// just-in-time attributes on the user
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 attributes on the resource
attributes: {
hasApproval: "true",
},
// the tenant the resource belong to
tenant: "companyB",
}
);

Just-In-Time (JIT) Attributes

JIT attributes are a way of passing dynamic values to pre-declared attributes as part of the permit.check() function. Passing JIT attributes is useful when an attribute can match more than a single value. There are multiple ways of defining attributes within Permit. You can find a complete guide for them here.

Example

A policy such as:

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

Would be represented using JIT attributes in the following manner:

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

Relationships

In cases where you want to manage access based on the relationships between identities and resources. That's where Relationship Based Access Control (ReBAC) comes in.

The structure of relationships between identities and resources can be defined via the UI or API.

tip

In the code example below, we check if John has the assign permissions on a member group resource (Defined in Permit beforehand).

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

Using the Context Object

If you are using custom policy code and need to pass additional data to the policy evaluation, you can use the context object.

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

Using the API

While the easiest way to call the permit.check() function is to use one of our SDKs, you can also call the Permit PDP directly. The API endpoint for the permit.check() function is /allowed.

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

When calling the permit.check() API, ensure that you are calling either your deployed Permit PDP or the Permit cloud PDP. The api.permit.io is not supported for the permit.check() API.