Defining permissions
This guide covers the definePermissions function and the Permissions class. You will learn how to:
- Define permissions using the resource/action pattern
- Use prefixes to namespace permissions
- Mark permissions as inactive or create aliases
- Query the permission definitions at runtime
Overview
Permissions are defined as a flat resource/action map. Each resource (like product or billing) contains actions (like create, update, delete). The combination produces permission keys in resource.action format, for example product.create or billing.refund.
You define permissions once in a dedicated file and import the resulting Permissions instance wherever you need it.
Basic definition
Use definePermissions to create a Permissions instance. Each action value controls how the permission is configured:
truegenerates the permission with an auto-generated description.- A
stringuses that string as the description. - An
objectprovides full control over description, inactive state, and aliases.
import { definePermissions } from '@adonisplus/permissions'
export const permissions = definePermissions({
product: {
create: true,
update: 'Update existing products',
delete: {
description: 'Delete products permanently',
},
},
billing: {
refund: 'Issue refunds to customers',
},
})
This produces four permission keys: product.create, product.update, product.delete, and billing.refund. All keys are type-safe. Your editor will autocomplete them wherever a permission key is expected.
Using prefixes
Use the prefix function to namespace a group of permissions. This is useful when different parts of your application have overlapping resource names.
import { definePermissions, prefix } from '@adonisplus/permissions'
export const permissions = definePermissions(
prefix('admin', {
product: { create: true, update: true, delete: true },
}),
{
billing: { refund: 'Issue refunds' },
}
)
The prefixed keys become admin:product.create, admin:product.update, and admin:product.delete. The colon separates the prefix from the resource, and the dot separates the resource from the action.
You can pass multiple definition objects to definePermissions. They are merged together into a single Permissions instance.
Aliases
Aliases let you rename permission keys without breaking existing role assignments. When a user or role has an aliased key stored in the database, the system resolves it to the canonical key automatically.
export const permissions = definePermissions({
product: {
delete: {
description: 'Delete products',
aliases: ['product.remove'],
},
},
})
A role with product.remove in the database will be treated as having product.delete. This works transparently across access checks and Bouncer abilities.
Inactive permissions
Mark a permission as inactive to remove it from runtime checks without deleting it from the definition. Inactive permissions are excluded from access checks, meaning roles that have the key stored in the database will no longer receive it.
export const permissions = definePermissions({
product: {
archive: {
description: 'Archive products',
inactive: true,
},
},
})
This is useful when deprecating a permission. The key remains in .keys() and .all() for reference, but it has no effect on authorization.
Querying permissions
The Permissions instance provides methods to inspect the definition at runtime. These are useful for building admin UIs where you list available permissions for role assignment.
// All permissions with metadata (key, description, inactive, aliases)
permissions.all()
// All permission keys (including inactive)
permissions.keys()
// Only active permission keys
permissions.active()
// Type-safe key validation (throws if unknown)
permissions.getKey('product.create')
// Resolve raw keys: resolves aliases, removes inactive and unknown
permissions.filterKeys(['product.remove', 'product.archive', 'unknown.key'])
// → ['product.delete'] (alias resolved, inactive and unknown removed)
Permissions instance methods
all
Returns all permissions as an array of objects with key, description, inactive, and aliases properties.
permissions.all()
keys
Returns all permission keys as strings, including inactive ones.
permissions.keys()
active
Returns only active permission keys.
permissions.active()
getKey
Returns the key as-is. Exists for compile-time type safety. Throws if the key is not defined.
permissions.getKey('product.create')
filterKeys
Takes raw permission strings (from the database or tokens), resolves aliases, removes inactive and unknown keys. Returns the filtered list of canonical keys.
permissions.filterKeys(rawKeys)
createAccess
Creates a new empty Access instance tied to this permission definition. Call access.use(rawKeys) to populate it.
const access = permissions.createAccess()
createAccessFor
Creates an Access instance pre-populated with the entity's resolved permissions. The entity must implement getPermissions().
const access = await permissions.createAccessFor(user)
abilities
Returns an object of Bouncer abilities, one per active permission key. See the Bouncer integration guide.
const abilities = permissions.abilities()