Skip to content

Commit

Permalink
Merge pull request #246 from permitio/daniel/permit.check
Browse files Browse the repository at this point in the history
Updated permit.check function page
  • Loading branch information
danielbass37 authored Feb 23, 2024
2 parents 9de0f60 + 57c8058 commit a23aed5
Showing 1 changed file with 88 additions and 54 deletions.
142 changes: 88 additions & 54 deletions docs/how-to/enforce-permissions/check.mdx
Original file line number Diff line number Diff line change
@@ -1,94 +1,128 @@
---
sidebar_position: 1
title: Basic Checks
title: Permit.check()
---

There are many ways to use the `permit.check()` function within permit to enforce permissions. This can depend on the policy
you are checking against and the granularity of the enforcement you need. Below we will talk about the different ways to
compose the `check` function.
## The `permit.check()` Function

## Simple check
`permit.check()` is the main function used by Permit to enforce permissions in your application.
Depending on the complexity of the policy being enforced, `permit.check()` accepts several parameters to return a boolean answer - `Permitted=True` or `Permitted=Flase`.

The most basic enforcement you can create within your app is a simple Role-based Access Control (RBAC) policy.
There are many ways to use the function within Permit to enforce permissions. This can depend on the policy you are checking against, and the required level of granularity.

The function accepts three parameters, a unique `user id`, and `action` and a `resource`.
## 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.

```js
const permitted = await permit.check("[email protected]", "create", "document");

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

## Simple check with tenant definition
## Tenants

Tenants are silos or resources and users. You can pass a tenant as part of the resource object inside the `permit.check()` function.
[Tenants](https://docs.permit.io/overview/glossary#tenant) are silos of resources and users.
Tenants can be passed as part of the `resource` object inside the `permit.check()` function.

```js
const permitted = await permit.check("[email protected]", "create", {
type: "document",
tenant: "companyA",
type: "document",
tenant: "companyA",
});
```

:::note An illustrative use-case
You create two tenats. `Tenant A` and `Tenant B`. You can have the same user `[email protected]` in both tenants, but the user might have
a different role. John may be an `Administrator` in `Tenant A`, but he could be an `Admin` in `Tenant B`.
:::tip 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`.
:::

## Enforce with attributes
## 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.

As your company grows, you permissions will need to get much more granular, and you might have to check for specific attributes
on a user or a resource to determine the conditions for which you will allow an authorization check to pass.
Attributes can be declared as part of the `user`, `resource`, or `tenant`.

:::tip
You can learn more about passing data into Permit [here](https://docs.permit.io/how-to/manage-data/loading-data/)
:::

```js
const permitted = await permit.check(
// the user object
{
// the user key
key: "[email protected]",
// 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",
}
);
```

If you will need to check for conditions as you perform an enforcement, you will be working with the Attribute-based access control
policy. Here, you can define extra attributes as part of the `user id` or `resource` by passing in a whole object.
## Just-In-Time (JIT) Attributes

If you want to learn about the different ways you can load data into Permit, check out the guide **[here](/how-to/manage-data/loading-data)**.
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](https://docs.permit.io/how-to/manage-data/loading-data).

:::tipExample
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:
```js
const permitted = await permit.check(
// the user object
{
// the user key
key: "[email protected]",
// 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",
}
{
key: "[email protected]",
attributes: {
location: location, // With location being a variable extracted from your loggedIn user
},
},
"access",
"document"
);
```
:::

## Enforce based on relationships
## Relationships

As your system complexity increases, you will need to levarage Relationship-Based Access Control (ReBAC) to incorporate
relationship checks into your enforcement. Unlike ABAC, ReBAC evaluates relationships between entities, enhancing the granularity
of access controls.
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.

You can configure all the relationships and their structure by following the **[UI guide](/how-to/build-policies/rebac/building-rebac-policies)**
or via the **[API guide](/api/rebac/rebac-api-calls)**.
The structure of relationships between identities and resources cab be defined via the **[UI](/how-to/build-policies/rebac/building-rebac-policies)** or **[API](/api/rebac/rebac-api-calls)**.

In the code example below, we are checking if `John` has the `assign` permissions on a member group resource (that we defined in
Permit beforehand).
:::tip
In the code example below, we check if `John` has the `assign` permissions on a member group resource (Defined in Permit beforehand).
:::

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

0 comments on commit a23aed5

Please sign in to comment.