All Projects → stalniy → Casl

stalniy / Casl

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

Programming Languages

javascript
184084 projects - #8 most used programming language
typescript
32286 projects

Projects that are alternatives of or similar to Casl

feathers-casl
feathers.js + casl: hooks & channels
Stars: ✭ 25 (-99.31%)
Mutual labels:  permissions, acl, authorization, casl
Simpleacl
Simple ACL for PHP
Stars: ✭ 105 (-97.09%)
Mutual labels:  authorization, permissions, acl
Vakt
Attribute-based access control (ABAC) SDK for Python
Stars: ✭ 92 (-97.45%)
Mutual labels:  authorization, permissions, acl
Laravel Authz
An authorization library that supports access control models like ACL, RBAC, ABAC in Laravel.
Stars: ✭ 136 (-96.23%)
Mutual labels:  authorization, permissions, acl
Accesscontrol
Role and Attribute based Access Control for Node.js
Stars: ✭ 1,723 (-52.27%)
Mutual labels:  authorization, permissions, acl
Brandenburg
Laravel Authentication Package
Stars: ✭ 79 (-97.81%)
Mutual labels:  authorization, permissions, acl
Laratrust
Handle roles and permissions in your Laravel application
Stars: ✭ 1,799 (-50.17%)
Mutual labels:  authorization, permissions, acl
Casbin4D
An authorization library that supports access control models like ACL, RBAC, ABAC in Delphi
Stars: ✭ 25 (-99.31%)
Mutual labels:  permissions, acl, authorization
Rbac
Hierarchical Role-Based Access Control for Node.js
Stars: ✭ 254 (-92.96%)
Mutual labels:  authorization, permissions, acl
Bouncer
Eloquent roles and abilities.
Stars: ✭ 2,763 (-23.46%)
Mutual labels:  authorization, permissions, acl
Think Authz
An authorization library that supports access control models like ACL, RBAC, ABAC in ThinkPHP 6.0 .
Stars: ✭ 155 (-95.71%)
Mutual labels:  authorization, permissions, acl
nova-permissions
Add Permissions based authorization for your Nova installation via User-based Roles and Permissions. Roles are defined in the database whereas Permissions are defined in the code base.
Stars: ✭ 115 (-96.81%)
Mutual labels:  permissions, acl, authorization
spicedb
Open Source, Google Zanzibar-inspired fine-grained permissions database
Stars: ✭ 3,358 (-6.98%)
Mutual labels:  permissions, acl, authorization
rbac-tool
Rapid7 | insightCloudSec | Kubernetes RBAC Power Toys - Visualize, Analyze, Generate & Query
Stars: ✭ 546 (-84.88%)
Mutual labels:  permissions, acl, authorization
riam
AWS IAM inspired policy engine in Rust
Stars: ✭ 19 (-99.47%)
Mutual labels:  permissions, authorization
ngx-security
Security directives for your Angular application to show/hide elements based on a user roles / permissions.
Stars: ✭ 18 (-99.5%)
Mutual labels:  permissions, acl
HeimGuard
🛡 A simple library that allows you to easily manage permissions in your .NET projects.
Stars: ✭ 77 (-97.87%)
Mutual labels:  permissions, authorization
browser-acl
Simple acceess control (ACL) library for the browser inspired by Laravel's guards and policies.
Stars: ✭ 36 (-99%)
Mutual labels:  acl, authorization
laravel-acl
Laravel ACL is a simple role, permission ACL for Laravel Framework.
Stars: ✭ 78 (-97.84%)
Mutual labels:  permissions, acl
fastapi-auth0
FastAPI authentication and authorization using auth0.com
Stars: ✭ 104 (-97.12%)
Mutual labels:  permissions, authorization

CASL logo

Financial Contributors on Open Collective build CASL codecov CASL Join the chat at https://gitter.im/stalniy-casl/casl

CASL (pronounced /ˈkæsəl/, like castle) is an isomorphic authorization JavaScript library which restricts what resources a given user is allowed to access. It's designed to be incrementally adoptable and can easily scale between a simple claim based and fully featured subject and attribute based authorization. It makes it easy to manage and share permissions across UI components, API services, and database queries.

Heavily inspired by cancan.

Features

  • Versatile
    An incrementally adoptable and can easily scale between a simple claim based and fully featured subject and attribute based authorization.
  • Isomorphic
    Can be used on frontend and backend and complementary packages make integration with major Frontend Frameworks and Backend ORMs effortless
  • TypeSafe
    Written in TypeScript, what makes your apps safer and developer experience more enjoyable
  • Tree shakable
    The core is only 6KB mingzipped and can be even smaller!
  • Declarative
    Thanks to declarative rules, you can serialize and share permissions between UI and API or microservices

Ecosystem

Project Status Description Supported envinronemnts
@casl/ability @casl/ability-status CASL's core package nodejs 8+ and ES5 compatible browsers (IE 9+)
@casl/mongoose @casl/mongoose-status integration with Mongoose nodejs 8+
@casl/prisma @casl/prisma-status integration with Prisma nodejs 12+
@casl/angular @casl/angular-status integration with Angular IE 9+
@casl/react @casl/react-status integration with React IE 9+
@casl/vue @casl/vue-status integration with Vue IE 11+ (uses WeakMap)
@casl/aurelia @casl/aurelia-status integration with Aurelia IE 11+ (uses WeakMap)

Documentation

A lot of detailed information about CASL, integrations and examples can be found in documentation.

Have a question?

Ask it in chat or on stackoverflow. Please don't ask questions in issues, the issue list of this repo is exclusively for bug reports and feature requests. Questions in the issue list may be closed immediately without answers.

CASL crash course

CASL operates on the abilities level, that is what a user can actually do in the application. An ability itself depends on the 4 parameters (last 3 are optional):

  1. User Action
    Describes what user can actually do in the app. User action is a word (usually a verb) which depends on the business logic (e.g., prolong, read). Very often it will be a list of words from CRUD - create, read, update and delete.
  2. Subject
    The subject or subject type which you want to check user action on. Usually this is a business (or domain) entity name (e.g., Subscription, BlogPost, User).
  3. Conditions
    An object or function which restricts user action only to matched subjects. This is useful when you need to give a permission on resources created by a user (e.g., to allow user to update and delete own BlogPost)
  4. Fields
    Can be used to restrict user action only to matched subject's fields (e.g., to allow moderator to update hidden field of BlogPost but not update description or title)

Using CASL you can describe abilities using regular and inverted rules. Let's see how

Note: all the examples below will be written in TypeScript but CASL can be used in similar way in ES6+ and Nodejs environments.

1. Define Abilities

Lets define Ability for a blog website where visitors:

  • can read blog posts
  • can manage (i.e., do anything) own posts
  • cannot delete a post if it was created more than a day ago
import { AbilityBuilder, Ability } from '@casl/ability'
import { User } from '../models'; // application specific interfaces

/**
 * @param user contains details about logged in user: its id, name, email, etc
 */
function defineAbilitiesFor(user: User) {
  const { can, cannot, rules } = new AbilityBuilder(Ability);

  // can read blog posts
  can('read', 'BlogPost');
  // can manage (i.e., do anything) own posts
  can('manage', 'BlogPost', { author: user.id });
  // cannot delete a post if it was created more than a day ago
  cannot('delete', 'BlogPost', {
    createdAt: { $lt: Date.now() - 24 * 60 * 60 * 1000 }
  });

  return new Ability(rules);
});

Do you see how easily business requirements were translated into CASL's rules?

Note: you can use class instead of string as a subject type (e.g., can('read', BlogPost))

And yes, Ability class allow you to use some MongoDB operators to define conditions. Don't worry if you don't know MongoDB, it's not required and explained in details in Defining Abilities

2. Check Abilities

Later on you can check abilities by using can and cannot methods of Ability instance.

// in the same file as above
import { ForbiddenError } from '@casl/ability';

const user = getLoggedInUser(); // app specific function
const ability = defineAbilitiesFor(user);

class BlogPost { // business entity
  constructor(props) {
    Object.assign(this, props);
  }
}

// true if ability allows to read at least one Post
ability.can('read', 'BlogPost');
// the same as
ability.can('read', BlogPost);

// true, if user is the author of the blog post
ability.can('manage', new BlogPost({ author: user.id }));

// true if there is no ability to read this particular blog post
const ONE_DAY = 24 * 60 * 60 * 1000;
const postCreatedNow = new BlogPost({ createdAt: new Date() });
const postCreatedAWeekAgo = new BlogPost({ createdAt: new Date(Date.now() - 7 * ONE_DAY) });

// can delete if it's created less than a day ago
ability.can('delete', postCreatedNow); // true
ability.can('delete', postCreatedAWeekAgo); // false

// you can even throw an error if there is a missed ability
ForbiddenError.from(ability).throwUnlessCan('delete', postCreatedAWeekAgo);

Of course, you are not restricted to use only class instances in order to check permissions on objects. See Introduction for the detailed explanation.

3. Database integration

CASL has a complementary package @casl/mongoose which provides easy integration with MongoDB and mongoose.

import { AbilityBuilder } from '@casl/ability';
import { accessibleRecordsPlugin } from '@casl/mongoose';
import mongoose from 'mongoose';

mongoose.plugin(accessibleRecordsPlugin);

const user = getUserLoggedInUser(); // app specific function

const ability = defineAbilitiesFor(user);
const BlogPost = mongoose.model('BlogPost', mongoose.Schema({
  title: String,
  author: mongoose.Types.ObjectId,
  content: String,
  createdAt: Date,
  hidden: { type: Boolean, default: false }
}))

// returns mongoose Query, so you can chain it with other conditions
const posts = await BlogPost.accessibleBy(ability).where({ hidden: false });

// you can also call it on existing query to enforce permissions
const hiddenPosts = await BlogPost.find({ hidden: true }).accessibleBy(ability);

// you can even pass the action as a 2nd parameter. By default action is "read"
const updatablePosts = await BlogPost.accessibleBy(ability, 'update');

See Database integration for details.

4. Advanced usage

CASL is incrementally adoptable, that means you can start your project with simple claim (or action) based authorization and evolve it later, when your app functionality evolves.

CASL is composable, that means you can implement alternative conditions matching (e.g., based on joi, ajv or pure functions) and field matching (e.g., to support alternative syntax in fields like addresses.*.street or addresses[0].street) logic.

See Advanced usage for details.

5. Examples

Looking for examples? Check CASL examples repository.

Want to help?

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

If you'd like to help us sustain our community and project, consider to become a financial contributor on Open Collective

Contributors

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]

Individuals

Organizations

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

License

MIT License

Copyright (c) 2017-present, Sergii Stotskyi

Note that the project description data, including the texts, logos, images, and/or trademarks, for each open source project belongs to its rightful owner. If you wish to add or remove any projects, please contact us at [email protected].