Library / SDK
apache/casbin-node-casbin avatar
apache/casbin-node-casbin

node-casbin: policy-as-data authorization for Node.js, driven by .conf and .csv files

An authorization library that supports access control models like ACL, RBAC, ABAC in Node.js and Browser

2,918 stars231 forksTypeScriptApache-2.0

At a glance

What is it?
Apache node-casbin evaluates access decisions against a model file and a policy file instead of hardcoded permission checks. It fits teams that want RBAC or ABAC rules editable without a redeploy, and it is a poor fit for anyone who wants permissions wired directly into their ORM.
Who is it for?
Adopt node-casbin if your permission rules change independently of your code and you are willing to treat a .conf model plus a policy store as deployable artifacts. Do not adopt it if you want permissions expressed as queries against your own schema, or if a single-process in-memory policy is not enough for your write volume.
Can I use it commercially?
Yes. Apache-2.0 is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
Is it still maintained?
Yes. The repository last received commits 21 days ago.
What is it written in?
Mainly TypeScript, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on September 25, 2026, and from our analysis. They are not legal advice.

Editorial analysis

The problem node-casbin solves: permissions that outlive the code that checks them

Most Node.js services start with a role column and an if statement. That works until the third role, at which point the checks are scattered across route handlers and nobody can answer "who can read data1" without grepping. node-casbin moves the decision out of the handler and into two files: a model that describes the shape of the rule, and a policy that lists the actual subjects, objects and actions. The README frames the library as supporting "access control models like ACL, RBAC, ABAC", and the examples directory confirms that range with files such as basic_model.conf, abac_model.conf, abac_rule_model.conf, glob_model.conf, ipmatch_model.conf and keymatch_model.conf. The audience is backend engineers who already know what RBAC means and want the rule set to be data. It is not an authentication library. It never checks a password, issues a token or identifies a user. You hand it a subject string, and it tells you yes or no.

How enforcement works: a matcher expression evaluated against request tuples

The model file declares request and policy definitions plus a matcher. The enforcer loads that model alongside a policy file, and each enforce call is evaluated against the matcher rather than against a fixed lookup table. The README's basic example passes a subject, an object and an action, which map to the three request parameters the model declares. Because the matcher is an expression, the same engine covers plain ACL and role hierarchies and attribute checks, which is why the repository ships separate example models rather than one configurable switch. Policy storage is separate from evaluation. The README points to the adapters documentation for persistence and to the watchers documentation for keeping policy consistent across multiple nodes, which is the honest signal that a single process holding policy in memory is the starting point, not the ceiling. Two API surfaces exist: the Management API for primitive policy operations and the RBAC API as a friendlier subset. The README states the RBAC API "is a subset of Management API". If you need to manipulate grouping rules directly, you will end up on the management surface.

Installing node-casbin and making your first enforce call

The package is published as casbin, not node-casbin. The README gives both npm and Yarn forms:

bash
npm install casbin --save

The package.json declares main as lib/cjs/index.js and module as lib/esm/index.mjs, so both require and import resolve to built output. There is no build step for consumers. Next, construct an enforcer from a model file and a policy file. The README uses the bundled examples by name:

js
const { newEnforcer } = require('casbin');
const enforcer = await newEnforcer('basic_model.conf', 'basic_policy.csv');

In a browser the README shows the same call through an import instead of require. The enforcer is asynchronous to construct, so this belongs in your startup path, not inside a request handler. Once it exists, the enforcement hook goes immediately before the access happens:

js
const sub = 'alice';
const obj = 'data1';
const act = 'read';
const res = await enforcer.enforce(sub, obj, act);
if (res) {
  // permit alice to read data1
} else {
  // deny the request, show an error
}

enforce returns a boolean. The README also lists enforceSync for callers that cannot await, and getRolesForUser as an example of querying the policy at run time. The files you point at must exist relative to the process working directory, or you pass absolute paths; the examples directory is shipped in the published package under "files", so the names above resolve if you install and run from a project where those files are reachable.

Where node-casbin is the wrong tool

The library decides authorization. It does not authenticate, and it does not filter data. A successful enforce call on 'data1' tells you alice may read that object; it does not tell you which rows alice may read when the query returns ten thousand of them. Teams that need row-level filtering in SQL end up either issuing one enforce call per row, which is a per-row cost, or building a separate query-side mechanism. Neither is provided here. The second boundary is state. Policy lives wherever your adapter puts it, and the README directs you to the adapters and watchers documentation rather than promising distributed consistency in the core. If several instances each hold a policy copy, a write through one instance is not automatically visible to the others; that is what watchers are for, and it is additional infrastructure you must run. Third, the matcher expression is a real evaluation step per call. The README does not publish latency figures, and none should be assumed. If your authorization check sits in a hot loop, measure it against your own model before you commit.

node-casbin compared with hand-rolled role checks and policy engines

The nearest alternative is not another library, it is the if statement you already have. A role column plus a middleware function is faster to write and has no model file to learn, and for two roles and three resources it is genuinely the better choice. The difference appears when rules change: with node-casbin you edit a policy file or call a management API, and the code path is untouched. With hand-rolled checks you edit and redeploy. Among policy engines, the distinguishing choice here is the model-plus-policy split. Casbin's own documentation describes the model as declaring the request and matcher, so the evaluation logic is itself a configuration artifact. Engines that express policy in a general-purpose language put the logic in code and only the data in storage, which is more expressive and harder to review. The Casbin model file is small enough to read in a pull request. The cost is that anything the matcher expression language cannot express is out of reach, and the README does not offer an escape hatch for that case.

Maintenance, release cadence and the Apache-2.0 licence

The repository is not archived, and its last push was on 2026-09-09. Recent releases listed are v5.51.1 on 2026-06-25, v5.51.0 on 2026-06-22 and v5.50.0 on 2026-04-25. Note the gap between the package.json version field, which reads 5.43.0, and the release tags, which are ahead of it; the version in the repository file is not the version you install from npm. The package is licensed Apache-2.0, and the repository carries both LICENSE and NOTICE files. Apache-2.0 permits commercial use and modification and includes a patent grant, with the usual obligations around retaining notices. That is a summary of the licence text, not legal advice; your own counsel decides what your distribution requires. Upgrade cost is mostly the model and policy files. Because the matcher is an expression evaluated by @casbin/expression-eval, a major bump in that dependency is the thing to watch when you upgrade, more than the enforcer API surface itself. The README does not document a rollback procedure for policy changes, so treat policy edits with the same care as schema migrations.

Editorial conclusion

Adopt node-casbin if your permission rules change independently of your code and you are willing to treat a .conf model plus a policy store as deployable artifacts. Do not adopt it if you want permissions expressed as queries against your own schema, or if a single-process in-memory policy is not enough for your write volume. Before committing, verify three things: that the model file you write actually parses under @casbin/expression-eval, that your chosen adapter persists policy across restarts, and that enforce() returns the boolean your middleware expects for the deny path.

Frequently asked questions

What is node-casbin used for?

It evaluates authorization decisions: you pass a subject, an object and an action to enforce, and it returns a boolean based on a model file and a policy file. The README describes it as supporting ACL, RBAC and ABAC models. It does not authenticate users.

How do I install node-casbin in a Node.js project?

Install the npm package named casbin, not node-casbin. The README gives npm install casbin --save, or yarn add casbin, and the package resolves through its exports field to lib/cjs/index.js or lib/esm/index.mjs.

Does node-casbin read its RBAC rules from a file or a database?

Both are possible. The README's getting-started example constructs an enforcer from a model file and a policy file, and it notes that you can initialize an enforcer with policy in a DB instead, pointing to the adapters documentation for persistence.

How does node-casbin keep policy consistent across multiple nodes?

The README links to the watchers documentation for policy consistency between multiple nodes, and to the adapters documentation for persistence. The core library itself does not promise distributed consistency; watchers are separate infrastructure.

What is the difference between the Management API and the RBAC API in node-casbin?

The README describes the Management API as the primitive API with full support for policy management, and the RBAC API as a more friendly API that is a subset of it. RBAC users can use the subset to simplify their code.

Official sources

  1. apache/casbin-node-casbin on GitHub
  2. License: Apache-2.0
  3. Project website
  4. README
  5. Releases
Add this badge to your README

If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.

Add this badge to your README

markdown
[![Hysen Labs](https://hysenlabs.com/badge/apache-casbin-node-casbin.svg)](https://hysenlabs.com/projects/apache-casbin-node-casbin)