You're Invited:Meet the Socket Team at RSAC and BSidesSF 2026, March 23–26.RSVP
Socket
Book a DemoSign in
Socket

@casl/ability

Package Overview
Dependencies
Maintainers
1
Versions
88
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@casl/ability

CASL is an isomorphic authorization JavaScript library which restricts what resources a given user is allowed to access

Source
npmnpm
Version
2.0.3
Version published
Weekly downloads
896K
-14.94%
Maintainers
1
Weekly downloads
 
Created
Source

CASL Ability

@casl/ability NPM version CASL Documentation CASL Join the chat at https://gitter.im/stalniy-casl/casl

This package is the core of CASL. It includes logic responsible for checking and defining permissions.

Installation

npm install @casl/ability

Getting Started

CASL concentrates all attention at what a user can actually do and allows to create abilities in DSL style. Lets see how

1. Defining Abilities

AbilityBuilder allows to define abilities using DSL:

import { AbilityBuidler } from '@casl/abiltiy'

const ability = AbilityBuilder.define((can, cannot) => {
  can('protect', 'Website')
  cannot('delete', 'Website')
})

class Website {}

console.log(ability.can('delete', new Website())) // false

If you would like to define abilities in own function, it'd better to use its extract method:

import { AbilityBuidler, Ability } from '@casl/abiltiy'

function defineAbilityFor(user) {
  const { rules, can, cannot } = AbilityBuilder.extract()

  if (user.isAdmin) {
    can('manage', 'all')
  } else {
    can('read', 'all')
    can('manage', 'Post', { author: 'me' })
    cannot('delete', 'Post')
  }

  return new Ability(rules)
}

Also you can combine similar rules together:

const { can, rules } = AbilityBuilder.extract()

can(['read', 'update'], 'User', { id: 'me' })
can(['read', 'update'], ['Post', 'Comment'], { authorId: 'me' })

console.log(rules)

Sometimes you may need to define permissions per field. For example, you can let moderator update only post status field

const { can, rules } = AbilityBuilder.extract()

can('read', 'all')

if (user.is('moderator')) {
  can('update', 'Post', 'status')
} else if (user.is('editor')) {
  can('update', 'Post', ['title', 'description'], { authorId: user.id })
}

const ability = new Ability(rules)

See Defining Abilities for details.

2. Checking rules

Later on you can check abilities by using can and cannot.

// true if user can read at least one Post
ability.can('read', 'Post')

// true if user cannot update a post
const post = new Post({ title: 'What is CASL?', authorId: 'not_me' })
ability.cannot('update', post)

See Check Abilities for details.

3. Serializing rules

As rules are plain objects, they can be easily serialized and cached in session or JWT token or even saved to any database and added dynamically later in admin panel.

const jwt = require('jsonwebtoken')
const payload = {
  rules: ability.rules
}

jwt.sign(payload, secret, (error, token) => {
  if (error) {
    return next(error)
  }

  // later you can send this token to client
  // and restore Ability on the client using `jwt.verify`
  console.log(token)
})

See Caching Abilities for details.

4. Extra

This package also provides @casl/ability/extra submodule which contains helper functions that can construct a database query based on permissions or extract some information from them.

import { rulesToQuery } from '@casl/ability/extra'

function ruleToMongoQuery(rule) {
  return rule.inverted ? { $nor: [rule.conditions] } : rule.conditions
}

function toMongoQuery(ability, subject, action = 'read') {
  return rulesToQuery(ability, action, subject, ruleToMongoQuery)
}

// now you can construct query based on Ability
const query = toMongoQuery(ability, 'Post')

@casl/mongoose uses rulesToQuery function to construct queries to MongoDB database.

See Storing Abilities for details.

Another useful method is permittedFieldsOf which allows to find all permitted fields for specific subject and action. You can use this method together with lodash.pick to extract only allowed fields from request body

import { permittedFieldsOf } from '@casl/ability/extra'

const { can, rules } = AbilityBuilder.extract()

can('update', 'Post', ['title', 'description'])

const ability = new Ability(rules)

// later in request middleware
const fields = permittedFieldsOf(ability, 'update', 'Post')
const attributesToUpdate = _.pick(req.body, fields)

See Extracting Permitted Attributes for details.

Want to help?

Want to file a bug, contribute some code, or improve documentation? Excellent! Read up on guidelines for contributing

License

MIT License

Keywords

access control

FAQs

Package last updated on 16 Apr 2018

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