> For the complete documentation index, see [llms.txt](https://docs.novel.dev/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.novel.dev/novel-server/authorization.md).

# Authorization

Novel uses the CASL library to provide authorization checks for all the routes and actions you need for your SaaS.

{% embed url="<https://casl.js.org/v6/en>" %}

{% hint style="info" %}
**Important**

It is important to remember that authorization is an intentional exercise and not automatic. You need to put these checks in place where they are needed.
{% endhint %}

## Configuration

In `/config/auth.js` there is a roles object that you can modify to add role IDs and permission keys to.

{% code title="config/auth.js" lineNumbers="true" %}

```typescript
/**
 * These are roles within the app that can be assigned to users.
 *
 * They have permissions that can be applied per route. Additional permission checks can be added
 * per transaction via casl/ability.
 *
 * Make sure you update app/(app)/organization/team/members.tsx if you modify this.
 */
roles: {
	superuser: ['all', 'admin'],
	admin: ['read', 'write', 'delete'],
	user: ['read', 'write'],
},
```

{% endcode %}

You can add as many roles you need here, and as many permissions applied to the role here.

These are then auto-loaded during start up time and applied to a global authorizer and a session based authorizer.

{% embed url="<https://docs.novel.dev/guides/knowledge-base/novel-server/configure-roles-and-permissions>" %}

## Permission

The `Permission` object is a class that you can use to organize permissions in your application.

{% code title="feature.ts" lineNumbers="true" %}

```typescript
const permit = new Permission(anyActorWithAnId);

permit.allow('read', Post);
permit.deny('delete', Post);

await permit.persist();

// or fetch a stored permission
const permit = await Permission.fetch(anActorWithAnId);
```

{% endcode %}

### `new Permission(ObjectWithId)`

This creates a new Permission object that can be serialized later on. You can use this to temporarily create permissions in your feature code.

You can persist the permissions to database using `.persist()` below.

### `permit.allow(action: String, subject: String | ObjectWithId)`

This defines what you can use in the Permission object using the CASL Ability `.can` or `.cannot`. The signature for this is the same.

{% embed url="<https://docs.novel.dev/novel-server/routing/request-helpers#await-request.can-action-string-subject-any-fields-string>" %}

### `permit.deny(action: String, subject: String | ObjectWithId)`

This is the opposite of allow you can use in the Permission object using the CASL Ability `.can` or `.cannot`. The signature for this is the same.

{% embed url="<https://docs.novel.dev/novel-server/routing/request-helpers#await-request.cannot-action-string-subject-any-fields-string>" %}

### `permit.build(): Ability`

This is an internal abstraction to CASL's Ability.build function. This makes it so that you can perform CASL functions against the Permission Object

{% code title="feature.ts" lineNumbers="true" %}

```typescript
const permit = new Permission(anyActorWithAnId);

permit.allow('read', Post);
permit.deny('delete', Post);

const permissions = permit.build();

permission.can('read', Post); // returns true
```

{% endcode %}

### `await permit.persist()`

This persists the permissions defined during the lifecycle of the Permission object. It generates a serialized permission records, one row per action/scope into the `access_control` table.

### `await Permission.fetch(actor: String | ObjectWithId)`&#x20;

This is similar to `new Permission(ObjectWithId)`  but for an actor that has been persisted.

{% code title="feature.ts" lineNumbers="true" %}

```typescript
const permissions = await Permission.fetch(anyActorWithAnId);

permission.can('read', Post); // returns true
```

{% endcode %}

## Using with an API

It is important to be familiar with both authorization modes of Novel API. Discussed below:

{% embed url="<https://docs.novel.dev/novel-server/routing#protecting-routes>" %}

Combine the above with the request helpers associated with `permit.allow`and `permit.deny`.

{% embed url="<https://docs.novel.dev/guides/knowledge-base/novel-server/securing-an-endpoint>" %}

## Changelog

* 2024-12-20 - Initial Documentation
