Skip to content
CASL is an isomorphic authorization JavaScript library which restricts what resources a given user is allowed to access
JavaScript TypeScript
Branch: master
Clone or download


Type Name Latest commit message Commit time
Failed to load latest commit information.
.github chore(ci): ensure that github actions are run on PRs Feb 24, 2020
docs docs(error): updates documentation about `throwUnlessCan` method [ski… Dec 22, 2019
packages chore(release): @casl/angular@3.0.5 [skip ci] Feb 21, 2020
tools chore(release): replaces npmignore with package.files list for ability Feb 17, 2020
.codeclimate.yml feat(ability): adds possibility to specify custom error messages (#245) Dec 22, 2019
.eslintrc style(eslint): disables max-class-per-file and arrow-parens Nov 10, 2019
.gitignore chore(rollup): merges rollup config for different ouput.formats into … Jan 12, 2020
.renovaterc chore(renovate): change babel6 monorepo to babel Jul 17, 2019 docs(fund): fixes link to backers Feb 6, 2020 docs(contribution): fixes indentation Mar 13, 2019
LICENSE docs(license): adds LICENSE file May 25, 2018 chore(ci): removes travis configuration because of migration to githu… Feb 17, 2020
babel.config.js chore(rollup): merges rollup config for different ouput.formats into … Jan 12, 2020
lerna.json chore(testing): migrates to jest Mar 21, 2018
package-lock.json Revert "chore(deps): update dependency typescript to ~3.8.0" Feb 24, 2020
package.json Revert "chore(deps): update dependency typescript to ~3.8.0" Feb 24, 2020

CASL Financial Contributors on Open Collective build CASL codecov CASL Code Climate CASL Documentation CASL Join the chat at

CASL (pronounced /ˈkæsəl/, like castle) is an isomorphic authorization JavaScript library which restricts what resources a given user is allowed to access. All permissions are defined in a single location (the Ability class) and not duplicated across UI components, API services, and database queries.

Heavily inspired by cancan.


  • supports MongoDB like conditions ($eq, $ne, $in, $all, $gt, $lt, $gte, $lte, $exists, $regex, $elemMatch, field dot notation)
  • supports direct and inverted rules (i.e., can & cannot)
  • provides ES6 build, so you are able to shake out unused functionality
  • provides easy integration with popular frontend frameworks
  • provides easy integration with mongoose and MongoDB
  • serializable rules which can be stored or cached in JWT token or any other storage

Getting started

CASL can be used together with any data layer, any HTTP framework and even any frontend framework because of its isomorphic nature. Also, it doesn't force you to choose a database (however currently is the best integrated with MongoDB). See the examples for details.

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

1. Define Abilities

Lets define Ability for a blog website where visitors:

  • can read everything.
  • can manage (i.e., create, update, delete, read) posts which were created by them
  • cannot delete post if it has at least 1 comment
import { AbilityBuilder } from '@casl/ability'

const ability = AbilityBuilder.define((can, cannot) => {
  can('read', 'all')
  can('manage', 'Post', { author: })
  cannot('delete', 'Post', { 'comments.0': { $exists: true } })

Yes, you can use some operators from MongoDB query language to define conditions for your abilities. See Defining Abilities for details. It's also possible to store CASL abilities in a database.

2. Check Abilities

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

class Post {
  constructor(props) {
    Object.assign(this, props)

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

// true if ability does not allow to read a post
const post = new Post({ title: 'What is CASL?' })
ability.cannot('read', post)

See Check Abilities for details.

3. MongoDB integration

CASL has a complementary package @casl/mongoose which provides easy integration with MongoDB database. That package provides mongoose middleware which hides all boilerplate under convenient accessibleBy method.

const { AbilityBuilder } = require('@casl/ability')
const { accessibleRecordsPlugin } = require('@casl/mongoose')
const mongoose = require('mongoose')


const ability = AbilityBuilder.define(can => {
  can('read', 'Post', { author: 'me' })

const Post = mongoose.model('Post', mongoose.Schema({
  title: String,
  author: String,
  content: String,
  createdAt: Date

// by default it asks for `read` rules
// returns mongoose Query, so you can chain it with other conditions
Post.accessibleBy(ability).where({ createdAt: { $gt: - 24 * 3600 } })

// also you can call it on existing query to enforce visibility.
// In this case it returns empty array because rules does not allow to read Posts of `someoneelse` author
Post.find({ author: 'someoneelse' }).accessibleBy(ability).exec()

See Database integration for details.

4. UI integration

CASL is written in pure ES6 and has no dependencies on Node.js or other environments. That means you can use it on UI side. It may be useful if you need to show/hide some UI functionality based on what user can do in the application.

There are also complementary libraries for major frontend frameworks which makes integration of CASL super easy in your application. Pick the package for your application and protect it with the power of CASL:


A lot of useful information about CASL can be found in documentation (check sidebar on the right hand ;)!

Documentation for complementary packages can be found in respective README files:

Have a question?: ask it in gitter chat or on stackoverflow


There are several repositories which show how to integrate CASL in popular frontend and backend frameworks:

Want to help?

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


Code Contributors

This project exists thanks to all the people who contribute. [Contribute].

Financial Contributors

Become a financial contributor and help us sustain our community. [Contribute]



Support this project with your organization. Your logo will show up here with a link to your website. [Contribute]


MIT License

You can’t perform that action at this time.