Flexible role-based authorization solution that is a pleasure to use
Switch branches/tags
Clone or download
Fetching latest commit…
Cannot retrieve the latest commit at this time.
Failed to load latest commit information.


Version Dependency Status Build Status


Miracle is an ACL for NodeJS that was designed to be well-structuted, simple yet exhaustive. It uses permissions defined on resources, and roles are granted with the access to them.

To be a universal tool, it does not include any special cases, does not force you to persist and does not insist on any formats or conventions.

Maximum flexibility and total control. Enjoy! :)

Inspired by https://github.com/optimalbits/node_acl and https://npmjs.org/package/nod.



Define The Structure


To start using miracle, instantiate the Acl object:

var Acl = require('miracle').Acl;

var acl = new Acl();

The Acl object keeps track of your resources and permissions defined on them, handles grants over roles and provides utilities to manage them. When configured, you can check the access against the defined state.


Methods from this section allow you to build the structure: list of roles, resources and permissions.

It's not required that you have the structure defined before you start granting the access: the grant() method implicitly creates all resources and permissions that were not previously defined.

Start with defining the resources and permissions on them, then you can grant a role with the access to some permissions on a resource.


Define role[s].

  • roles: the role[s] to define.

The role will have no permissions granted, but will appear in listRoles().

acl.addRole(['anonymous', 'registered']);

acl.listRoles(); // -> ['admin', 'anonymous', 'registered']


Define resource[s].

  • resources: resource[s] to define.

The resource will have no permissions defined but will list in listResources().

acl.addResource(['page', 'article']);

acl.listResources(); // -> ['blog', 'page', 'article']

addPermission(resources, permissions)

Define permission[s] on resource[s].

  • resources: resource[s] to define the permission on. Are created if were not previously defined.
  • permissions: permission[s] to define.

The defined permissions are not granted to anyone, but will appear in listPermissions().

acl.addPermission('blog', 'post');
acl.addPermission(['page', 'article'], ['create', 'read', 'update', 'delete']);

acl.listPermissions('page'); // -> ['create', 'read', 'update', 'delete']


Define the whole resource/permission structure with a single object.

  • structure: an object that maps resources to an array of permissions.
    blog: ['post'],
    page: ['create', 'read', 'update', 'delete'],
    article: ['create', 'read', 'update', 'delete'],



Remove role[s] and their grants.

  • roles: role[s] to remove.
acl.removeRole(['anonymous', 'registered']);


Remove resource[s] along with their grants and permissions.

  • resources: resource[s] to remove.
acl.removeResource(['page', 'article']);

removePermission(resources, permissions)

Remove permission[s] from resource[s].

  • resources: resource[s] to remove the permissions from.
  • permissions: permission[s] to remove.

The resource is not implicitly removed: it remains with an empty set of permissions.

acl.removePermissions('blog', 'post');
acl.removePermissions(['page', 'article'], ['create', 'update']);



Get the list of defined roles.

acl.listRoles(); // -> ['admin', 'anonymous', 'registered']


Get the list of defined resources, including those with empty permissions list.

acl.listResources(); // -> ['blog', 'page', 'article']


Get the list of permissions for a resource, or for multiple resources.

  • resources: resource[s] to get the permissions for. Optional.
acl.listPermissions('page'); // -> ['create', 'read', 'update', 'delete']
acl.listPermissions(['blog', 'page']); // -> ['post', 'create', ... ]
acl.listPermissions(); // -> [ ..all.. ]


Get the structure: list of resources mapped to their permissions.

  • resources: resource[s] to get the structure for. Optional.

Returns an object: { resource: [perm, ...] }.

acl.list(); // -> { blog: ['post'], page: ['create', ...] }
acl.list('blog'); // -> { blog: ['post'] }
acl.list(['blog', 'page']); // -> { blog: ['post'], page: ['create', ...] }

Export and Import

There's no single 'export everything' method: instead, you sequentially export the list of roles, the structure (resources and permissions), and the grants:

var miracle = require('miracle');

var acl = new miracle.Acl();

// Export
var save = {
    roles: acl.listRoles(),
    struct: acl.list(),
    grants: acl.show()

// Import

Note: As the grant() method creates resources and roles implicitly, it's usually enough to export the grants. You'll only lose roles & resources with empty grants.

Grant Permissions

grant(roles, resources, permissions)

Grant permission[s] over resource[s] to the specified role[s].

Has multiple footprints:

  • grant(roles, resources, permissions) - grant the listed roles with permissions to the listed resources ;
  • grant(roles, grants) - grant permissions using a grant object that maps a list of permissions to a resource: { resource: [perm, ...] }.

Roles, resources and permissions are implicitly created if missing.

acl.grant(['admin', 'manager'], 'blog', ['create', 'update']);
acl.grant('anonymous', { page: ['view'] });

revoke(roles[, resources[, permissions]])

Revoke permission[s] over resource[s] from the specified role[s].

Has multiple footprints:

  • revoke(roles) remove grants from all resources ;
  • revoke(roles, resources) remove all grants from the listed resources ;
  • revoke(roles, resources, permissions) remove specific grants from the listed resources ;
  • revoke(roles, grants) - revoke grants using a grant object that maps a list of permissions to a resource: { resource: [perm, ...], ... }.

No roles, resources or permissions are removed implicitly.

acl.revoke(['admin', 'manager'], 'blog', ['create', 'update']);
acl.revoke('anonymous', { page: ['view'] });


check(roles[, resources[, permissions]])

Check whether the named role[s] have access to resource[s] with permission[s].

Has multiple footprints:

  • check(roles, resources): check whether the role[s] have any access to the named resource[s].
  • check(roles, resources, permissions): check with a specific set of permissions.
  • check(roles, grants): check using a grants object.

In order to pass the test, all roles must have access to all resources.

Returns a boolean.

acl.check('admin', 'blog'); // -> true
acl.check(['anonymous'], 'blog', 'read'); // -> true
acl.check('registered', { page: ['update', 'delete'] });

checkAny(roles[, resources[, permissions]])

Same as check, but the united permissions are checked.

In order to pass the test, any role having access to any resource is sufficient.

Also supports the checkAny(roles, grants) footprint.

Show Grants


Collect grants that each of the provided roles have (intersection).

acl.which('admin'); // -> { blog: ['post'] }


Collect grants that any of the provided roles have (union).

acl.which(['anonymous', 'registered']); // -> { page: ['view'] }


Get all grants for the specified roles.

  • roles: role[s] to get the grants for.

Returns an object { role: { resource: [perm, ...] } }. Roles that were not defined are not mentioned in the result.

acl.show(); // -> { admin: { blog: ['post'] } }
acl.show(['admin', 'anonymous']);