### Install Node-Casbin Source: https://github.com/apache/casbin-node-casbin/blob/master/README.md Install the Node-Casbin library using either NPM or Yarn package managers. ```shell # NPM npm install casbin --save ``` ```shell # Yarn yarn add casbin ``` -------------------------------- ### Get Roles for User Source: https://github.com/apache/casbin-node-casbin/blob/master/README.md Retrieve all roles assigned to a specific user at runtime. This is part of the dynamic permission management capabilities. ```javascript const roles = await enforcer.getRolesForUser('alice'); ``` -------------------------------- ### Enforce with Explanation in Casbin Source: https://context7.com/apache/casbin-node-casbin/llms.txt Use `enforceEx` or `enforceExSync` to get both the enforcement decision (allow/deny) and the specific policy rule that led to the decision. Useful for auditing and debugging. ```typescript import { newEnforcer } from 'casbin'; const e = await newEnforcer('examples/basic_model.conf', 'examples/basic_policy.csv'); const [allowed, matchedRule] = await e.enforceEx('alice', 'data1', 'read'); // allowed => true // matchedRule => ['alice', 'data1', 'read'] const [denied, noRule] = await e.enforceEx('alice', 'data2', 'write'); // denied => false // noRule => [] ``` -------------------------------- ### Initialize Node-Casbin Enforcer Source: https://github.com/apache/casbin-node-casbin/blob/master/README.md Initialize a new enforcer instance with a model configuration file and a policy data file. For browser environments, use the 'import' statement. ```javascript // For Node.js: const { newEnforcer } = require('casbin'); // For browser: // import { newEnforcer } from 'casbin'; const enforcer = await newEnforcer('basic_model.conf', 'basic_policy.csv'); ``` -------------------------------- ### Create Casbin Enforcer from Files or Adapter Source: https://context7.com/apache/casbin-node-casbin/llms.txt Initialize a Casbin enforcer using model and policy files, or a custom adapter. Logging can be enabled with a trailing boolean. ```typescript import { newEnforcer } from 'casbin'; // From files const e = await newEnforcer('examples/basic_model.conf', 'examples/basic_policy.csv'); // From files with logging enabled const eLogged = await newEnforcer('examples/rbac_model.conf', 'examples/rbac_policy.csv', true); // From a model instance + custom adapter import { newModel, StringAdapter } from 'casbin'; const m = newModel(` [request_definition] r = sub, obj, act [policy_definition] p = sub, obj, act [policy_effect] e = some(where (p.eft == allow)) [matchers] m = r.sub == p.sub && r.obj == p.obj && r.act == p.act `); const policy = `p, alice, data1, read\np, bob, data2, write`; const eInMem = await newEnforcer(m, new StringAdapter(policy)); ``` -------------------------------- ### Runtime Configuration Source: https://context7.com/apache/casbin-node-casbin/llms.txt Provides runtime flags to control enforcer behavior, including temporarily disabling enforcement, disabling auto-save to the adapter, and controlling automatic role-link rebuilding. Also supports accepting JSON-encoded request parameters. ```APIDOC ## `enableEnforce` / `enableAutoSave` / `enableAutoBuildRoleLinks` — Runtime configuration ### Description Runtime flags to control enforcer behavior: temporarily disable enforcement, disable auto-save to the adapter on policy mutations, and control automatic role-link rebuilding. ### Methods - `enableEnforce(enable)`: Enables or disables enforcement. When disabled, all access is allowed regardless of policy. - `enableAutoSave(enable)`: Enables or disables auto-persistence. When disabled, policy changes are not automatically saved to the adapter. - `enableAutoBuildRoleLinks(enable)`: Enables or disables automatic role-link rebuilding. Useful for batch grouping changes. - `enableAcceptJsonRequest(enable)`: Enables or disables accepting JSON-encoded request parameters, useful for ABAC via JSON strings. ### Request Example ```typescript import { newEnforcer } from 'casbin'; const e = await newEnforcer('examples/rbac_model.conf', 'examples/rbac_policy.csv'); // Disable enforcement e.enableEnforce(false); await e.enforce('nobody', 'any', 'action'); // true (enforcement off) e.enableEnforce(true); // Disable auto-persistence e.enableAutoSave(false); await e.addPolicy('alice', 'data3', 'read'); await e.addPolicy('alice', 'data4', 'write'); e.enableAutoSave(true); await e.savePolicy(); // manually flush all changes // Disable auto role-link rebuild e.enableAutoBuildRoleLinks(false); await e.addGroupingPolicy('alice', 'admin'); await e.addGroupingPolicy('bob', 'editor'); e.enableAutoBuildRoleLinks(true); await e.buildRoleLinks(); // rebuild once after bulk changes // Accept JSON-encoded request parameters e.enableAcceptJsonRequest(true); await e.enforce('{"name":"alice"}', '{"Owner":"alice"}', 'read'); ``` ``` -------------------------------- ### Query Policy Rules with Casbin Source: https://context7.com/apache/casbin-node-casbin/llms.txt Use these read-only helpers to inspect the current policy state. Ensure the enforcer is initialized with a model and policy. ```typescript import { newEnforcer } from 'casbin'; const e = await newEnforcer('examples/rbac_model.conf', 'examples/rbac_policy.csv'); // All permission rules const policy = await e.getPolicy(); // string[][] // All grouping (role) rules const grouping = await e.getGroupingPolicy(); // string[][] // Unique subjects (users/roles) across p rules const subjects = await e.getAllSubjects(); // string[] // Unique objects const objects = await e.getAllObjects(); // string[] // Unique actions const actions = await e.getAllActions(); // string[] // All role names appearing in g rules const roles = await e.getAllRoles(); // string[] // Check if a rule exists const exists = await e.hasPolicy('alice', 'data1', 'read'); // boolean // Filtered query: rules where field[0] == 'alice' const aliceRules = await e.getFilteredPolicy(0, 'alice'); // string[][] // Check existence of grouping rule const hasGroup = await e.hasGroupingPolicy('alice', 'admin'); // boolean ``` -------------------------------- ### RBAC API - Role Assignment and Queries Source: https://context7.com/apache/casbin-node-casbin/llms.txt Manage role-user assignments with support for multi-domain scenarios using the RBAC API. ```APIDOC ## RBAC API — Role Assignment and Queries ### Description The RBAC API provides convenient methods for managing role-user assignments built on top of the grouping policy (`g`), with support for multi-domain (tenant) scenarios. ### Methods - `addRoleForUser(user, role)`: Assigns a role to a user. - `hasRoleForUser(user, role)`: Checks if a user has a specific role. - `getRolesForUser(user)`: Retrieves all roles assigned to a user. - `getUsersForRole(role)`: Retrieves all users assigned to a specific role. - `getImplicitRolesForUser(user)`: Gets all roles for a user, traversing role hierarchy. - `getImplicitPermissionsForUser(user)`: Gets all permissions, including inherited ones from all roles. - `deleteRoleForUser(user, role)`: Removes a specific role assignment for a user. - `deleteRolesForUser(user)`: Removes all role assignments for a user. - `getImplicitUsersForPermission(resource, action)`: Gets all users who can perform an action, resolving role inheritance. ### Request Example (Add Role) ```typescript import { newEnforcer } from 'casbin'; const e = await newEnforcer('examples/rbac_model.conf', 'examples/rbac_policy.csv'); await e.addRoleForUser('alice', 'admin'); ``` ### Response Example (Get Roles) ```typescript [json] ['admin'] ``` ``` -------------------------------- ### newEnforcer Source: https://context7.com/apache/casbin-node-casbin/llms.txt Creates and initializes a Casbin enforcer. It can be initialized from model/policy file paths, a custom adapter, or a model instance. Logging can be enabled with a boolean flag. ```APIDOC ## newEnforcer — Create an enforcer from files or an adapter Creates and initializes a Casbin enforcer. Accepts model/policy file paths, a custom adapter, a model instance, or a combination thereof. An optional trailing boolean enables logging. ```typescript import { newEnforcer } from 'casbin'; // From files const e = await newEnforcer('examples/basic_model.conf', 'examples/basic_policy.csv'); // From files with logging enabled const eLogged = await newEnforcer('examples/rbac_model.conf', 'examples/rbac_policy.csv', true); // From a model instance + custom adapter import { newModel, StringAdapter } from 'casbin'; const m = newModel(` [request_definition] r = sub, obj, act [policy_definition] p = sub, obj, act [policy_effect] e = some(where (p.eft == allow)) [matchers] m = r.sub == p.sub && r.obj == p.obj && r.act == p.act `); const policy = `p, alice, data1, read\np, bob, data2, write`; const eInMem = await newEnforcer(m, new StringAdapter(policy)); ``` ``` -------------------------------- ### RBAC with Domains (Multi-Tenancy) Source: https://context7.com/apache/casbin-node-casbin/llms.txt Implement RBAC where roles are scoped to specific domains, enabling multi-tenancy. Roles are defined as `g = _, _, _` (user, role, domain). ```typescript import { newEnforcer } from 'casbin'; // Model: g = _, _, _ (user, role, domain) // Policy: g, alice, admin, domain1 // p, admin, domain1, data1, read const e = await newEnforcer( 'examples/rbac_with_domains_model.conf', 'examples/rbac_with_domains_policy.csv' ); // alice is admin in domain1, so she can read data1 there const r1 = await e.enforce('alice', 'domain1', 'data1', 'read'); // true const r2 = await e.enforce('alice', 'domain2', 'data1', 'read'); // false // Query roles within a domain const roles = await e.getRolesForUserInDomain('alice', 'domain1'); // ['admin'] const users = await e.getUsersForRoleInDomain('admin', 'domain1'); // ['alice'] // Get all domains a user participates in const domains = await e.getDomainsForUser('alice'); // ['domain1'] // Add a role in a domain at runtime await e.addRoleForUser('carol', 'editor', 'domain2'); ``` -------------------------------- ### Builtin Matcher Functions Source: https://context7.com/apache/casbin-node-casbin/llms.txt Provides built-in functions like `keyMatch`, `keyMatch2`, `ipMatch`, and `globMatch` that can be used within matcher expressions for flexible path, IP, and glob-based matching. ```APIDOC ## Builtin Matcher Functions — `keyMatch`, `keyMatch2`, `ipMatch`, `globMatch` ### Description Casbin provides a set of builtin functions available inside matcher expressions for flexible URL/IP/glob-based matching without custom code. ### KeyMatch2 Example (RESTful paths) ```typescript import { newEnforcer, newModel, StringAdapter } from 'casbin'; const m = newModel(` [request_definition] r = sub, obj, act [policy_definition] p = sub, obj, act [policy_effect] e = some(where (p.eft == allow)) [matchers] m = r.sub == p.sub && keyMatch2(r.obj, p.obj) && r.act == p.act `); const policy = `p, alice, /user/:id, GET\np, bob, /admin/*, POST`; const e = await newEnforcer(m, new StringAdapter(policy)); await e.enforce('alice', '/user/123', 'GET'); // true (matches :id) await e.enforce('alice', '/user/456', 'GET'); // true await e.enforce('alice', '/user/123', 'POST'); // false (wrong action) await e.enforce('bob', '/admin/settings', 'POST'); // true (wildcard *) ``` ### IpMatch Example (Network-level access control) ```typescript import { newEnforcer, newModel, StringAdapter } from 'casbin'; const mIp = newModel(` [request_definition] r = sub, obj, act [policy_definition] p = sub, obj, act [policy_effect] e = some(where (p.eft == allow)) [matchers] m = ipMatch(r.sub, p.sub) `); const ipPolicy = `p, 192.168.1.0/24, /api, GET`; const eIp = await newEnforcer(mIp, new StringAdapter(ipPolicy)); await eIp.enforce('192.168.1.55', '/api', 'GET'); // true (in CIDR range) await eIp.enforce('10.0.0.1', '/api', 'GET'); // false ``` ``` -------------------------------- ### Custom Role Manager and Matching Functions Source: https://context7.com/apache/casbin-node-casbin/llms.txt Allows for customization of role management and pattern matching within Casbin. This includes replacing the default role manager or adding custom matching functions for roles and domains, supporting wildcard and glob patterns. ```APIDOC ## Custom Role Manager and Matching Functions Replace the default role manager or add pattern-matching functions to allow wildcard/glob role and domain matching. ```typescript import { newEnforcer, DefaultRoleManager } from 'casbin'; import { minimatch } from 'minimatch'; const e = await newEnforcer('examples/rbac_with_pattern_model.conf', 'examples/rbac_with_pattern_policy.csv'); // Add a matching function so "alice_*" matches any role starting with "alice_" await e.addNamedMatchingFunc('g', (name, pattern) => minimatch(name, pattern)); // Add a domain matching function for glob-style tenant matching await e.addNamedDomainMatchingFunc('g', (domain, pattern) => minimatch(domain, pattern)); // Use a custom RoleManager with a higher hierarchy depth const customRM = new DefaultRoleManager(20); e.setRoleManager(customRM); await e.buildRoleLinks(); // rebuild after replacing role manager // Add a custom function available in matcher expressions await e.addFunction('myCustomMatch', (key1: string, key2: string) => key1.startsWith(key2)); // Now usable in model: m = myCustomMatch(r.sub, p.sub) && r.obj == p.obj ``` ``` -------------------------------- ### RBAC with Domains (Multi-Tenancy) Source: https://context7.com/apache/casbin-node-casbin/llms.txt Utilize RBAC with domains for multi-tenancy, scoping roles to specific domains. ```APIDOC ## RBAC with Domains (Multi-Tenancy) ### Description When using the `rbac_with_domains` model, roles are scoped to a named domain. This allows the same user to have different roles in different tenants. ### Methods - `enforce(user, domain, resource, action)`: Enforces policy within a specific domain. - `getRolesForUserInDomain(user, domain)`: Queries roles within a specific domain for a user. - `getUsersForRoleInDomain(role, domain)`: Queries users within a specific domain for a role. - `getDomainsForUser(user)`: Retrieves all domains a user participates in. - `addRoleForUser(user, role, domain)`: Adds a role for a user within a specific domain at runtime. ### Request Example (Add Role in Domain) ```typescript import { newEnforcer } from 'casbin'; const e = await newEnforcer('examples/rbac_with_domains_model.conf', 'examples/rbac_with_domains_policy.csv'); await e.addRoleForUser('carol', 'editor', 'domain2'); ``` ### Response Example (Get Roles in Domain) ```typescript [json] ['admin'] ``` ``` -------------------------------- ### batchEnforce Source: https://context7.com/apache/casbin-node-casbin/llms.txt Enforces multiple requests at once by running them in parallel and returning an array of boolean results, preserving the order of the requests. ```APIDOC ## `batchEnforce` — Enforce multiple requests at once Runs multiple enforce calls in parallel and returns an array of boolean results, preserving order. ```typescript import { newEnforcer } from 'casbin'; const e = await newEnforcer('examples/basic_model.conf', 'examples/basic_policy.csv'); const results = await e.batchEnforce([ ['alice', 'data1', 'read'], ['alice', 'data1', 'write'], ['bob', 'data2', 'write'], ['bob', 'data1', 'read'], ]); // results => [true, false, true, false] ``` ``` -------------------------------- ### Customize Role Manager and Matching Functions Source: https://context7.com/apache/casbin-node-casbin/llms.txt Extend Node-Casbin by adding custom matching functions for roles and domains, or by replacing the default role manager. This allows for wildcard/glob matching and deeper hierarchy levels. ```typescript import { newEnforcer, DefaultRoleManager } from 'casbin'; import { minimatch } from 'minimatch'; const e = await newEnforcer('examples/rbac_with_pattern_model.conf', 'examples/rbac_with_pattern_policy.csv'); // Add a matching function so "alice_*" matches any role starting with "alice_" await e.addNamedMatchingFunc('g', (name, pattern) => minimatch(name, pattern)); // Add a domain matching function for glob-style tenant matching await e.addNamedDomainMatchingFunc('g', (domain, pattern) => minimatch(domain, pattern)); // Use a custom RoleManager with a higher hierarchy depth const customRM = new DefaultRoleManager(20); e.setRoleManager(customRM); await e.buildRoleLinks(); // rebuild after replacing role manager // Add a custom function available in matcher expressions await e.addFunction('myCustomMatch', (key1: string, key2: string) => key1.startsWith(key2)); // Now usable in model: m = myCustomMatch(r.sub, p.sub) && r.obj == p.obj ``` -------------------------------- ### RBAC API for Role Assignment and Queries Source: https://context7.com/apache/casbin-node-casbin/llms.txt Manage role-user assignments and perform role-related queries. Supports multi-domain scenarios. ```typescript import { newEnforcer } from 'casbin'; const e = await newEnforcer('examples/rbac_model.conf', 'examples/rbac_policy.csv'); // Assign a role to a user await e.addRoleForUser('alice', 'admin'); // Check if a user has a role const isAdmin = await e.hasRoleForUser('alice', 'admin'); // true // Get all roles for a user const roles = await e.getRolesForUser('alice'); // ['admin'] // Get all users with a given role const admins = await e.getUsersForRole('admin'); // ['alice'] // Get all roles, traversing role hierarchy (alice -> admin -> super-admin) const allRoles = await e.getImplicitRolesForUser('alice'); // Get all permissions including inherited ones from all roles const perms = await e.getImplicitPermissionsForUser('alice'); // Remove a specific role assignment await e.deleteRoleForUser('alice', 'admin'); // Remove all roles from a user await e.deleteRolesForUser('alice'); // Get all users who can perform an action (resolving role inheritance) const users = await e.getImplicitUsersForPermission('data1', 'read'); // => ['alice', 'bob'] (includes users via role inheritance) ``` -------------------------------- ### enforceEx / enforceExSync Source: https://context7.com/apache/casbin-node-casbin/llms.txt Enforces a request and returns both the boolean result and the specific policy rule that led to the decision. Useful for auditing and debugging. ```APIDOC ## enforceEx / enforceExSync — Enforce with explanation Returns both the boolean result and the matched policy rule that caused the decision — useful for audit logging or debugging. ```typescript import { newEnforcer } from 'casbin'; const e = await newEnforcer('examples/basic_model.conf', 'examples/basic_policy.csv'); const [allowed, matchedRule] = await e.enforceEx('alice', 'data1', 'read'); // allowed => true // matchedRule => ['alice', 'data1', 'read'] const [denied, noRule] = await e.enforceEx('alice', 'data2', 'write'); // denied => false // noRule => [] ``` ``` -------------------------------- ### Load Filtered Policy with Casbin Source: https://context7.com/apache/casbin-node-casbin/llms.txt Use `loadFilteredPolicy` and `loadIncrementalFilteredPolicy` with `FilteredAdapter` implementations to load only a subset of policy rules. This reduces memory usage for large policies. Ensure the adapter supports filtering. ```typescript import { newEnforcer } from 'casbin'; const e = await newEnforcer('examples/rbac_model.conf', 'examples/rbac_policy.csv'); // Load only rules where subject is 'alice' (adapter-specific filter format) await e.loadFilteredPolicy({ p: ['alice', '', ''] }); // Check if policy is filtered const isFiltered = e.isFiltered(); // true // Append more filtered rules without clearing await e.loadIncrementalFilteredPolicy({ p: ['bob', '', ''] }); ``` -------------------------------- ### Permission Management API Source: https://context7.com/apache/casbin-node-casbin/llms.txt Convenience methods for directly adding, removing, and querying permissions for users or roles without manual policy tuple construction. ```typescript import { newEnforcer } from 'casbin'; const e = await newEnforcer('examples/basic_model.conf', 'examples/basic_policy.csv'); // Add a permission await e.addPermissionForUser('alice', 'data2', 'write'); // Check if a user has a specific permission const has = await e.hasPermissionForUser('alice', 'data2', 'write'); // true // Get all permissions for a user const perms: string[][] = await e.getPermissionsForUser('alice'); // => [['alice', 'data1', 'read'], ['alice', 'data2', 'write']] // Remove a specific permission await e.deletePermissionForUser('alice', 'data2', 'write'); // Remove all permissions for a user await e.deletePermissionsForUser('alice'); // Delete a global permission rule across all subjects await e.deletePermission('data1', 'read'); ``` -------------------------------- ### Permission Management Source: https://context7.com/apache/casbin-node-casbin/llms.txt Manage permissions directly for users or roles using convenience RBAC-layer methods. ```APIDOC ## Permission Management — `addPermissionForUser`, `getPermissionsForUser` ### Description Convenience RBAC-layer methods to add/remove/query permissions directly for a user or role without constructing raw policy tuples. ### Methods - `addPermissionForUser(user, resource, action)`: Adds a permission for a user. - `hasPermissionForUser(user, resource, action)`: Checks if a user has a specific permission. - `getPermissionsForUser(user)`: Retrieves all permissions for a user. - `deletePermissionForUser(user, resource, action)`: Removes a specific permission for a user. - `deletePermissionsForUser(user)`: Removes all permissions for a user. - `deletePermission(resource, action)`: Deletes a global permission rule across all subjects. ### Request Example (Add Permission) ```typescript import { newEnforcer } from 'casbin'; const e = await newEnforcer('examples/basic_model.conf', 'examples/basic_policy.csv'); await e.addPermissionForUser('alice', 'data2', 'write'); ``` ### Response Example (Get Permissions) ```typescript [json] [['alice', 'data1', 'read'], ['alice', 'data2', 'write']] ``` ``` -------------------------------- ### newSyncedEnforcer Source: https://context7.com/apache/casbin-node-casbin/llms.txt Provides a thread-safe enforcer by wrapping policy-mutating and enforcement operations with an async mutex lock. This ensures safe concurrent access in scenarios where multiple asynchronous tasks might call methods like `loadPolicy`, `savePolicy`, or `enforce` simultaneously. ```APIDOC ## `newSyncedEnforcer` — Thread-safe enforcer with mutex lock `SyncedEnforcer` wraps all policy-mutating and enforcement operations with an async mutex lock (`await-lock`), making it safe to use in concurrent scenarios where multiple async tasks may call `loadPolicy`, `savePolicy`, `enforce`, etc. simultaneously. ```typescript import { newSyncedEnforcer } from 'casbin'; const e = await newSyncedEnforcer('examples/rbac_model.conf', 'examples/rbac_policy.csv'); // All operations are automatically serialized via internal lock const [r1, r2] = await Promise.all([ e.enforce('alice', 'data1', 'read'), e.enforce('bob', 'data2', 'write'), ]); // r1 => true, r2 => true (safe under concurrent load) // Policy reload is also lock-protected await e.loadPolicy(); ``` ``` -------------------------------- ### setWatcher Source: https://context7.com/apache/casbin-node-casbin/llms.txt Sets up a watcher to synchronize policy changes across multiple enforcer instances, typically used in distributed systems. The watcher implementation should handle receiving update notifications and calling the provided callback to reload policies. ```APIDOC ## `setWatcher` — Policy synchronization across nodes A `Watcher` notifies all enforcer instances (e.g., across multiple server nodes) when policies change, triggering automatic `loadPolicy()` to keep them in sync. ```typescript import { newEnforcer } from 'casbin'; const e = await newEnforcer('examples/basic_model.conf', 'examples/basic_policy.csv'); // Implement the Watcher interface (e.g., backed by Redis pub/sub) const watcher = { setUpdateCallback(cb: () => void) { // Store cb and call it whenever a remote update event arrives this.cb = cb; }, async update(): Promise { // Publish a "policy updated" message to the message bus // await redis.publish('casbin', 'update'); return true; }, cb: null as any, }; e.setWatcher(watcher); // Now whenever another node changes a policy, it calls watcher.update(), // which triggers the callback to reload policy on all nodes. await e.addPolicy('carol', 'data5', 'read'); // automatically notifies watcher ``` ``` -------------------------------- ### Policy Management API Source: https://context7.com/apache/casbin-node-casbin/llms.txt Provides a comprehensive API for managing policy rules, including CRUD operations for permission (`p`) and grouping (`g`) policies. Policies can be optionally persisted using the configured adapter. ```APIDOC ## Policy Management API — `addPolicy`, `removePolicy`, `updatePolicy` The Management API provides full CRUD over `p` (permission) policy rules and `g` (grouping/role) policy rules, with optional persistence via the configured adapter. ```typescript import { newEnforcer } from 'casbin'; const e = await newEnforcer('examples/rbac_model.conf', 'examples/rbac_policy.csv'); // Add a single permission rule const added = await e.addPolicy('carol', 'data3', 'read'); // true if new, false if duplicate // Add multiple rules at once await e.addPolicies([ ['dave', 'data4', 'read'], ['dave', 'data4', 'write'], ]); // Add policies, skipping duplicates (no error) await e.addPoliciesEx([ ['carol', 'data3', 'read'], // duplicate, skipped ['eve', 'data5', 'write'], // new, added ]); // Update an existing rule await e.updatePolicy(['carol', 'data3', 'read'], ['carol', 'data3', 'write']); // Remove a specific rule await e.removePolicy('dave', 'data4', 'read'); // Remove rules matching a field filter (fieldIndex=0 => subject field) await e.removeFilteredPolicy(0, 'dave'); // removes all rules where sub == 'dave' // Query all rules const allRules: string[][] = await e.getPolicy(); // => [['carol', 'data3', 'write'], ['eve', 'data5', 'write'], ...] // Query rules filtered by field const carolRules = await e.getFilteredPolicy(0, 'carol'); // => [['carol', 'data3', 'write']] // Save all in-memory rules back to the adapter await e.savePolicy(); ``` ``` -------------------------------- ### Filtered Policy Loading Source: https://context7.com/apache/casbin-node-casbin/llms.txt Allows loading only a subset of policy rules that match a specific filter, which is useful for reducing memory usage with large policy stores. Supports incremental loading. ```APIDOC ## `loadFilteredPolicy` — Partial policy loading ### Description `FilteredAdapter` implementations support loading only a subset of policy rules matching a filter, reducing memory usage in large policy stores. ### Methods - `loadFilteredPolicy(filter)`: Loads policy rules matching the provided filter. The filter format is adapter-specific. - `isFiltered()`: Checks if the policy is currently filtered. - `loadIncrementalFilteredPolicy(filter)`: Appends filtered policy rules without clearing existing ones. ### Request Example ```typescript import { newEnforcer } from 'casbin'; const e = await newEnforcer('examples/rbac_model.conf', 'examples/rbac_policy.csv'); // Load only rules where subject is 'alice' (adapter-specific filter format) await e.loadFilteredPolicy({ p: ['alice', '', ''] }); // Check if policy is filtered const isFiltered = e.isFiltered(); // true // Append more filtered rules without clearing await e.loadIncrementalFilteredPolicy({ p: ['bob', '', ''] }); ``` ``` -------------------------------- ### enforce Source: https://context7.com/apache/casbin-node-casbin/llms.txt The primary asynchronous enforcement method. Evaluates a request (subject, object, action) against loaded policies and returns `true` for allow or `false` for deny. ```APIDOC ## enforce — Check if a request is allowed (async) The primary enforcement method. Evaluates the request `(sub, obj, act)` — or any custom token set defined in the model — against loaded policies and returns `true` (allow) or `false` (deny). ```typescript import { newEnforcer } from 'casbin'; const e = await newEnforcer('examples/basic_model.conf', 'examples/basic_policy.csv'); // basic_policy.csv: "p, alice, data1, read" / "p, bob, data2, write" const allow1 = await e.enforce('alice', 'data1', 'read'); // true const allow2 = await e.enforce('alice', 'data1', 'write'); // false const allow3 = await e.enforce('bob', 'data2', 'write'); // true if (!(await e.enforce('alice', 'data2', 'read'))) { throw new Error('Access denied'); } ``` ``` -------------------------------- ### Policy Query API Source: https://context7.com/apache/casbin-node-casbin/llms.txt Provides read-only helper functions to inspect the current policy state, retrieve all rules, grouping rules, unique subjects, objects, actions, and roles. ```APIDOC ## Policy Query API — `getPolicy`, `getAllSubjects`, `getAllRoles` ### Description Exposes read-only helpers to introspect the current policy state. ### Methods - `getPolicy()`: Retrieves all permission rules. - `getGroupingPolicy()`: Retrieves all grouping (role) rules. - `getAllSubjects()`: Retrieves unique subjects (users/roles) across p rules. - `getAllObjects()`: Retrieves unique objects. - `getAllActions()`: Retrieves unique actions. - `getAllRoles()`: Retrieves all role names appearing in g rules. - `hasPolicy(subject, object, action)`: Checks if a specific policy rule exists. - `getFilteredPolicy(field_index, ...field_values)`: Retrieves filtered policy rules based on specified fields. - `hasGroupingPolicy(subject, group)`: Checks if a specific grouping rule exists. ### Request Example ```typescript import { newEnforcer } from 'casbin'; const e = await newEnforcer('examples/rbac_model.conf', 'examples/rbac_policy.csv'); const policy = await e.getPolicy(); const grouping = await e.getGroupingPolicy(); const subjects = await e.getAllSubjects(); const objects = await e.getAllObjects(); const actions = await e.getAllActions(); const roles = await e.getAllRoles(); const exists = await e.hasPolicy('alice', 'data1', 'read'); const aliceRules = await e.getFilteredPolicy(0, 'alice'); const hasGroup = await e.hasGroupingPolicy('alice', 'admin'); ``` ### Response - `getPolicy()`: `string[][]` - `getGroupingPolicy()`: `string[][]` - `getAllSubjects()`: `string[]` - `getAllObjects()`: `string[]` - `getAllActions()`: `string[]` - `getAllRoles()`: `string[]` - `hasPolicy()`: `boolean` - `getFilteredPolicy()`: `string[][]` - `hasGroupingPolicy()`: `boolean` ``` -------------------------------- ### enforceWithMatcher Source: https://context7.com/apache/casbin-node-casbin/llms.txt Evaluates a request against a custom matcher string provided at runtime, overriding the model's default matcher. Useful for A/B testing or temporary policy adjustments. ```APIDOC ## enforceWithMatcher — Enforce with a runtime matcher override Evaluates a request against a custom matcher string at runtime, bypassing the model's default matcher. Useful for A/B testing policies or temporary overrides. ```typescript import { newEnforcer } from 'casbin'; const e = await newEnforcer('examples/basic_model.conf', 'examples/basic_policy.csv'); // Override matcher to always allow if sub matches const result = await e.enforceWithMatcher('r.sub == p.sub', 'alice', 'data1', 'read'); // true const result2 = await e.enforceWithMatcher('r.sub == p.sub', 'alice', 'data_other', 'delete'); // true (matcher is loose) ``` ``` -------------------------------- ### Runtime Configuration of Casbin Enforcer Source: https://context7.com/apache/casbin-node-casbin/llms.txt Control enforcer behavior at runtime using flags like `enableEnforce`, `enableAutoSave`, and `enableAutoBuildRoleLinks`. These flags allow for temporary disabling of enforcement, batching policy changes, and controlling role-link rebuilding. ```typescript import { newEnforcer } from 'casbin'; const e = await newEnforcer('examples/rbac_model.conf', 'examples/rbac_policy.csv'); // Disable enforcement (all access allowed regardless of policy) e.enableEnforce(false); await e.enforce('nobody', 'any', 'action'); // true (enforcement off) e.enableEnforce(true); // Disable auto-persistence (batch policy changes without hitting DB) e.enableAutoSave(false); await e.addPolicy('alice', 'data3', 'read'); await e.addPolicy('alice', 'data4', 'write'); e.enableAutoSave(true); await e.savePolicy(); // manually flush all changes // Disable auto role-link rebuild for bulk grouping changes e.enableAutoBuildRoleLinks(false); await e.addGroupingPolicy('alice', 'admin'); await e.addGroupingPolicy('bob', 'editor'); e.enableAutoBuildRoleLinks(true); await e.buildRoleLinks(); // rebuild once after bulk changes // Accept JSON-encoded request parameters (for ABAC via JSON strings) e.enableAcceptJsonRequest(true); await e.enforce('{"name":"alice"}', '{"Owner":"alice"}', 'read'); ``` -------------------------------- ### Asynchronous Enforcement Check with Casbin Source: https://context7.com/apache/casbin-node-casbin/llms.txt Use the `enforce` method to check if a request (subject, object, action) is allowed by the loaded policies. Returns true for allow, false for deny. Throws an error if access is denied. ```typescript import { newEnforcer } from 'casbin'; const e = await newEnforcer('examples/basic_model.conf', 'examples/basic_policy.csv'); // basic_policy.csv: "p, alice, data1, read" / "p, bob, data2, write" const allow1 = await e.enforce('alice', 'data1', 'read'); // true const allow2 = await e.enforce('alice', 'data1', 'write'); // false const allow3 = await e.enforce('bob', 'data2', 'write'); // true if (!(await e.enforce('alice', 'data2', 'read'))) { throw new Error('Access denied'); } ``` -------------------------------- ### Synchronous Enforcement Check with Casbin Source: https://context7.com/apache/casbin-node-casbin/llms.txt Use `enforceSync` for synchronous permission checks when the matcher does not involve asynchronous functions. This can reduce overhead in low-latency scenarios. ```typescript import { newEnforcer } from 'casbin'; const e = await newEnforcer('examples/basic_model.conf', 'examples/basic_policy.csv'); const result: boolean = e.enforceSync('alice', 'data1', 'read'); // true const denied: boolean = e.enforceSync('alice', 'data2', 'write'); // false ``` -------------------------------- ### Implement Watcher for Policy Synchronization Source: https://context7.com/apache/casbin-node-casbin/llms.txt Implement the Watcher interface to synchronize policy changes across multiple enforcer instances. The watcher's update method should publish a message, triggering a callback to reload policies on all nodes. ```typescript import { newEnforcer } from 'casbin'; const e = await newEnforcer('examples/basic_model.conf', 'examples/basic_policy.csv'); // Implement the Watcher interface (e.g., backed by Redis pub/sub) const watcher = { setUpdateCallback(cb: () => void) { // Store cb and call it whenever a remote update event arrives this.cb = cb; }, async update(): Promise { // Publish a "policy updated" message to the message bus // await redis.publish('casbin', 'update'); return true; }, cb: null as any, }; e.setWatcher(watcher); // Now whenever another node changes a policy, it calls watcher.update(), // which triggers the callback to reload policy on all nodes. await e.addPolicy('carol', 'data5', 'read'); // automatically notifies watcher ``` -------------------------------- ### Export Permissions for Casbin.js Frontend Source: https://context7.com/apache/casbin-node-casbin/llms.txt Use casbinJsGetPermissionForUser to serialize a user's full model and filtered policy into a JSON string. This is suitable for passing to Casbin.js on the frontend to enable client-side authorization checks. ```typescript import { newEnforcer, casbinJsGetPermissionForUser } from 'casbin'; const e = await newEnforcer('examples/basic_model.conf', 'examples/basic_policy.csv'); const permJson = await casbinJsGetPermissionForUser(e, 'alice'); // Returns a JSON string like: // { // "m": "[request_definition]\nr = sub, obj, act\n...", // "p": [["p", "alice", "data1", "read"], ...] // } // Send permJson to the browser; Casbin.js uses it to enforce locally // res.json({ permissions: permJson }); ``` -------------------------------- ### newCachedEnforcer Source: https://context7.com/apache/casbin-node-casbin/llms.txt Creates an enforcer with an in-memory cache for enforcement results. Identical requests are resolved from the cache without re-evaluating the policy, improving performance. The cache must be invalidated after policy mutations. ```APIDOC ## `newCachedEnforcer` — Enforcer with in-memory decision cache `CachedEnforcer` wraps the standard enforcer and caches `enforce()` results keyed by the request values. Subsequent identical requests are resolved from cache without re-evaluating the policy. Call `invalidateCache()` after policy mutations. ```typescript import { newCachedEnforcer } from 'casbin'; const e = await newCachedEnforcer('examples/basic_model.conf', 'examples/basic_policy.csv'); // First call evaluates and caches const r1 = await e.enforce('alice', 'data1', 'read'); // true (cached after) // Subsequent call served from cache const r2 = await e.enforce('alice', 'data1', 'read'); // true (from cache) // After policy changes, invalidate cache await e.addPolicy('alice', 'data2', 'write'); e.invalidateCache(); const r3 = await e.enforce('alice', 'data2', 'write'); // true (re-evaluated) // Disable caching dynamically e.setEnableCache(false); ``` ``` -------------------------------- ### EnforceContext / newEnforceContext Source: https://context7.com/apache/casbin-node-casbin/llms.txt Enables an enforcer to evaluate requests against specific, named policy types when a model defines multiple policy sections. This is useful for multi-tenant or multi-role scenarios within a single enforcer instance. ```APIDOC ## `EnforceContext` / `newEnforceContext` — Multiple policy types `EnforceContext` allows a single enforcer to evaluate a request against a named policy type (e.g., `p2`, `r2`) when the model defines multiple policy sections, enabling multi-tenant or multi-role patterns within one enforcer instance. ```typescript import { newEnforcer, newEnforceContext } from 'casbin'; const e = await newEnforcer('examples/multiple_policy_definitions_model.conf', 'examples/multiple_policy_definitions_policy.csv'); // Default context (r, p, e, m) const r1 = await e.enforce('alice', 'data1', 'read'); // uses p section // Named context for the second policy section (r2, p2, e2, m2) const ctx2 = newEnforceContext('2'); const r2 = await e.enforce(ctx2, 'alice', 'data1'); // uses p2 section ``` ``` -------------------------------- ### Create Thread-Safe Enforcer with Mutex Lock Source: https://context7.com/apache/casbin-node-casbin/llms.txt Use `newSyncedEnforcer` for concurrent scenarios. It automatically serializes policy mutations and enforcement operations using an async mutex lock, ensuring thread safety. ```typescript import { newSyncedEnforcer } from 'casbin'; const e = await newSyncedEnforcer('examples/rbac_model.conf', 'examples/rbac_policy.csv'); // All operations are automatically serialized via internal lock const [r1, r2] = await Promise.all([ e.enforce('alice', 'data1', 'read'), e.enforce('bob', 'data2', 'write'), ]); // r1 => true, r2 => true (safe under concurrent load) // Policy reload is also lock-protected await e.loadPolicy(); ``` -------------------------------- ### casbinJsGetPermissionForUser Source: https://context7.com/apache/casbin-node-casbin/llms.txt Serializes the model and filtered policy for a specific user into a JSON string. This output is intended for use with Casbin.js on the frontend, allowing for client-side authorization checks. ```APIDOC ## `casbinJsGetPermissionForUser` — Frontend permission export Serializes the full model and filtered policy for a specific user into a JSON string suitable for passing to [Casbin.js](https://github.com/casbin/casbin.js) on the frontend, enabling client-side authorization checks. ```typescript import { newEnforcer, casbinJsGetPermissionForUser } from 'casbin'; const e = await newEnforcer('examples/basic_model.conf', 'examples/basic_policy.csv'); const permJson = await casbinJsGetPermissionForUser(e, 'alice'); // Returns a JSON string like: // { // "m": "[request_definition]\nr = sub, obj, act\n...", // "p": [["p", "alice", "data1", "read"], ...] // } // Send permJson to the browser; Casbin.js uses it to enforce locally // res.json({ permissions: permJson }); ``` ``` -------------------------------- ### enforceSync Source: https://context7.com/apache/casbin-node-casbin/llms.txt Synchronous variant of `enforce()`. Use when no asynchronous custom functions are present in the matcher expression to avoid Promise overhead. ```APIDOC ## enforceSync — Synchronous enforcement (no async matchers) Synchronous variant of `enforce()`. Use when no async custom functions are used in the matcher expression — avoids Promise overhead for low-latency paths. ```typescript import { newEnforcer } from 'casbin'; const e = await newEnforcer('examples/basic_model.conf', 'examples/basic_policy.csv'); const result: boolean = e.enforceSync('alice', 'data1', 'read'); // true const denied: boolean = e.enforceSync('alice', 'data2', 'write'); // false ``` ``` -------------------------------- ### Casbin Built-in Matcher Functions Source: https://context7.com/apache/casbin-node-casbin/llms.txt Utilize built-in functions like keyMatch2, ipMatch, and globMatch within matcher expressions for flexible access control. These functions are defined in the model configuration. ```typescript import { newEnforcer, newModel, StringAdapter } from 'casbin'; // keyMatch2 matches RESTful paths with :param placeholders const m = newModel(` [request_definition] r = sub, obj, act [policy_definition] p = sub, obj, act [policy_effect] e = some(where (p.eft == allow)) [matchers] m = r.sub == p.sub && keyMatch2(r.obj, p.obj) && r.act == p.act `); const policy = `p, alice, /user/:id, GET p, bob, /admin/*, POST`; const e = await newEnforcer(m, new StringAdapter(policy)); await e.enforce('alice', '/user/123', 'GET'); // true (matches :id) await e.enforce('alice', '/user/456', 'GET'); // true await e.enforce('alice', '/user/123', 'POST'); // false (wrong action) await e.enforce('bob', '/admin/settings', 'POST'); // true (wildcard *) // ipMatch for network-level access control const mIp = newModel(` [request_definition] r = sub, obj, act [policy_definition] p = sub, obj, act [policy_effect] e = some(where (p.eft == allow)) [matchers] m = ipMatch(r.sub, p.sub) `); const ipPolicy = `p, 192.168.1.0/24, /api, GET`; const eIp = await newEnforcer(mIp, new StringAdapter(ipPolicy)); await eIp.enforce('192.168.1.55', '/api', 'GET'); // true (in CIDR range) await eIp.enforce('10.0.0.1', '/api', 'GET'); // false ``` -------------------------------- ### Perform Access Control Check Source: https://github.com/apache/casbin-node-casbin/blob/master/README.md Add an enforcement hook to check if a user (subject) is allowed to perform an action on a resource (object). Supports both asynchronous and synchronous checks. ```javascript const sub = 'alice'; // the user that wants to access a resource. const obj = 'data1'; // the resource that is going to be accessed. const act = 'read'; // the operation that the user performs on the resource. // Async: const res = await enforcer.enforce(sub, obj, act); // Sync: // const res = enforcer.enforceSync(sub, obj, act); if (res) { // permit alice to read data1 } else { // deny the request, show an error } ``` -------------------------------- ### Batch Enforce Multiple Requests Source: https://context7.com/apache/casbin-node-casbin/llms.txt Use `batchEnforce` to run multiple enforcement checks in parallel. It returns a boolean array corresponding to the input requests, preserving order. ```typescript import { newEnforcer } from 'casbin'; const e = await newEnforcer('examples/basic_model.conf', 'examples/basic_policy.csv'); const results = await e.batchEnforce([ ['alice', 'data1', 'read'], ['alice', 'data1', 'write'], ['bob', 'data2', 'write'], ['bob', 'data1', 'read'], ]); // results => [true, false, true, false] ```