New Case Study:See how Anthropic automated 95% of dependency reviews with Socket.Learn More
Socket
Sign inDemoInstall
Socket

@strapi/permissions

Package Overview
Dependencies
Maintainers
8
Versions
1458
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@strapi/permissions

Strapi's permission layer.

5.11.0
latest
Source
npm
Version published
Weekly downloads
157K
16.51%
Maintainers
8
Weekly downloads
 
Created
Source

Strapi Permissions

Highly customizable permission engine made for Strapi

Get Started

yarn add @strapi/permissions
const permissions = require('@strapi/permissions');

const engine = permissions.engine.new({ providers });

const ability = await engine.generateAbility([
  { action: 'read' },
  { action: 'delete', subject: 'foo' },
  { action: 'update', subject: 'bar', properties: { fields: ['foobar'] } },
  {
    action: 'create',
    subject: 'foo',
    properties: { fields: ['foobar'] },
    conditions: ['isAuthor'],
  },
]);

ability.can('read'); // true
ability.can('publish'); // false
ability.can('update', 'foo'); // false
ability.can('update', 'bar'); // true
  • You need to give both an action and a condition provider as parameters when instantiating a new permission engine instance. They must be contained in a providers object property.
  • You can also pass an abilityBuilderFactory to customize what kind of ability the generateAbility method will return. By default it'll use a @casl/ability builder.

You can also register to some hooks for each engine instance. See lib/engine/hooks.js -> createEngineHooks for available hooks.

const permissions = require('@strapi/permissions');

const engine = permissions.engine
  .new({ providers })
  .on('before-format::validate.permission', ({ permission }) => {
    if (permission.action === 'read') {
      return false;
    }
  });

const ability = await engine.generateAbility([
  { action: 'read' },
  { action: 'delete', subject: 'foo' },
  { action: 'update', subject: 'bar', properties: { fields: ['foobar'] } },
  {
    action: 'create',
    subject: 'foo',
    properties: { fields: ['foobar'] },
    conditions: ['isAuthor'],
  },
]);

ability.can('read'); // false since the validation hook prevents the engine from registering the permission
ability.can('publish'); // false
ability.can('update', 'foo'); // false
ability.can('update', 'bar'); // true

The format.permission hook can be used to modify the permission.

const permissions = require('@strapi/permissions');

const engine = permissions.engine
  .new({ providers })
  .on('before-format::validate.permission', ({ permission }) => {
    if (permission.action === 'modify') {
      return false;
    }
  })
  .on('after-format::validate.permission', ({ permission }) => {
    if (permission.action === 'update') {
      return false;
    }
  })
  .on('format.permission', ({ permission }) => {
    if (permission.action === 'update') {
      return {
        ...permission,
        action: 'modify',
      };
    }
    if (permission.action === 'delete') {
      return {
        ...permission,
        action: 'remove',
      };
    }
    return permission;
  });

const ability = await engine.generateAbility([{ action: 'update' }, { action: 'delete' }]);

ability.can('update'); // false
ability.can('modify'); // true, because create was changed to 'modify'

ability.can('delete'); // false, doesn't exist because it was changed by format.permission
ability.can('remove'); // true, before-format::validate.permission validates before format.permission changed it

FAQs

Package last updated on 05 Mar 2025

Did you know?

Socket

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Install

Related posts