Access control

This guide covers the Access class for checking permissions at runtime. You will learn how to:

  • Create an Access instance from a user or raw permission keys
  • Check whether a permission is allowed or denied
  • Scope permissions for API tokens

Overview

The Access class represents the resolved set of permissions for a specific user in a specific context. It takes raw permission strings (from the database), resolves aliases, removes inactive and unknown keys, and provides allows and denies methods for checking access.

You do not create Access instances directly. Instead, use the createAccess or createAccessFor methods on your Permissions instance.

Creating an Access instance

From a user

The most common approach is createAccessFor, which loads the user's permissions (from roles and direct assignments) and resolves them in one step.

import { permissions } from '#start/permissions'

const access = await permissions.createAccessFor(user)
access.allows('product.create') // true or false

The user must implement a getPermissions() method that returns a Promise<string[]>. Both the withRoles and withPermissions mixins provide this method.

From raw keys

For lower-level control, create an empty Access instance and populate it manually.

const access = permissions.createAccess()
access.use(['product.create', 'product.update', 'product.remove'])

The use method resolves aliases and filters out inactive and unknown keys before adding them to the resolved set.

Checking permissions

access.allows('product.create') // true
access.denies('billing.refund') // true

Both methods accept a permission key and return a boolean. Keys are type-safe and will be autocompleted by your editor.

Listing permissions

Use the permissions method to get all resolved permission keys.

access.permissions()
// ['product.create', 'product.update', 'product.delete']

Token scoping

When issuing API tokens, you may want to limit the token's capabilities to a subset of the user's permissions. The scopeTo method intersects the resolved permissions with the provided abilities, keeping only permissions present in both.

const access = await permissions.createAccessFor(user)

// User has: product.create, product.update, product.delete, billing.refund
// Token allows: product.create, product.update

access.scopeTo(['product.create', 'product.update'])

access.allows('product.create') // true
access.allows('product.delete') // false (not in token scope)
access.allows('billing.refund') // false (not in token scope)

The abilities passed to scopeTo are also resolved through the permission definition, so aliases and inactive keys are handled automatically.

Access instance methods

use
method

Loads raw permission strings, resolves aliases, filters out inactive and unknown keys, and adds the result to the resolved set.

access.use(['product.create', 'billing.refund'])
allows
method

Returns true if the permission key is in the resolved set.

access.allows('product.create')
denies
method

Returns true if the permission key is not in the resolved set.

access.denies('billing.refund')
scopeTo
method

Intersects the resolved set with the provided abilities. Only permissions present in both survive. Used for API token scoping.

access.scopeTo(['product.create', 'product.update'])
permissions
method

Returns all resolved active permission keys as an array.

access.permissions()
Terms & License Agreement