Skip to content

Conversation

Copy link
Contributor

Copilot AI commented Jan 10, 2026

Users with millions of policies across multiple tenants need to create per-request enforcers with filtered policies, but couldn't safely modify policies without risking database overwrites.

Changes

New API

  • newFilteredEnforcer() - creates enforcer with filtered policies pre-loaded
  • Filter format: empty strings are wildcards, e.g., {p: ['', 'org1']} matches any subject with domain='org1'

Bug Fix

  • DefaultFilteredAdapter.loadFilteredPolicyFile() - fixed to use mustGetDefaultFileSystem().readFileSync() instead of broken readFile() util

Documentation

  • FILTERED_POLICIES.md - usage patterns (shared/filtered/cached/hybrid), filter format, performance considerations
  • filtered_policy_example.js - working examples for per-request enforcers, caching, incremental updates
  • Updated README with filtered policy section

Usage

const { newFilteredEnforcer } = require('casbin');

// Create per-request enforcer with filtered policies
const enforcer = await newFilteredEnforcer(
  'model.conf',
  adapter,
  { 
    p: ['', 'org1'],      // Filter: any subject, domain='org1'
    g: ['', '', 'org1']   // Filter: any user, any role, domain='org1'
  }
);

// Enforcement and incremental updates work normally
await enforcer.enforce('alice', 'org1', 'data1', 'read');  // ✓
await enforcer.addPolicy('bob', 'org1', 'data2', 'write'); // ✓ uses autoSave

// savePolicy() throws to prevent overwriting entire DB with filtered subset
await enforcer.savePolicy(); // ✗ throws "Cannot save a filtered policy"

Key Points

  • Filtered enforcers support enforcement, incremental policy changes (via adapter.addPolicy/removePolicy), and RBAC APIs
  • savePolicy() intentionally throws to prevent data loss
  • Filter fields match policy definition order after type identifier
  • Includes 10 comprehensive tests, all 209 tests passing
Original prompt

This section details on the original issue you should resolve

<issue_title>Prefered way to use casbin in a web framework with lots of users?</issue_title>
<issue_description>Hey there,

We were going through casbin for our new permission system, and loved the features it provides. But one thing that has been bothering us is the policies.

So each user in an organization will add their contribution to policies in one way or another, and the policies will keep on growing.

We went through the code and saw that, most of the examples use LoadPolicy which loads up the entire db into into in memory.

Then there was LoadFilteredPolicy which LazyLoad. We wanted to use LoadFilteredPolicy but the major doubt is can we create an enforcer instance per request.

That is

  1. A request comes in -> Using a middleware create a FilteredPolicy enforcer which could be for a domain like org or user
  2. This will be used just that request context.
  3. Repeat for next request. Use caching to save number of db hits

We know the express-authz, and other framework integrations are provided by the amazing casbin team. But all those does loadPolicy. Read other similiar Github Issues but still didn't had proper answer on the filtered part. Sorry if we missed any important thread or documentation.

Same happened inside documentation, policy subset loading did ans this loading feature, but then how would you save to db without loading entire database.

Thank you</issue_description>

Comments on the Issue (you are @copilot in this section)


✨ Let Copilot coding agent set things up for you — coding agent works faster and does higher quality work when set up for your repo.

@CLAassistant
Copy link

CLA assistant check
Thank you for your submission! We really appreciate it. Like many open source projects, we ask that you sign our Contributor License Agreement before we can accept your contribution.
You have signed the CLA already but the status is still pending? Let us recheck it.

@hsluoyz hsluoyz marked this pull request as ready for review January 10, 2026 07:47
@coveralls
Copy link

Pull Request Test Coverage Report for Build 20875152292

Details

  • 0 of 0 changed or added relevant lines in 0 files are covered.
  • No unchanged relevant lines lost coverage.
  • Overall coverage remained the same at 78.472%

Totals Coverage Status
Change from base Build 20874899852: 0.0%
Covered Lines: 1661
Relevant Lines: 2017

💛 - Coveralls

Copilot AI and others added 3 commits January 10, 2026 07:50
- Add newFilteredEnforcer() utility function for easy filtered enforcer creation
- Fix DefaultFilteredAdapter to use correct filesystem API
- Add comprehensive test suite for filtered policies
- Add FILTERED_POLICIES.md guide with usage patterns and best practices
- Add filtered_policy_example.js with working examples
- Update README with filtered policy section
- All 209 tests passing

Co-authored-by: hsluoyz <[email protected]>
- Update filtered_policy_example.js to use domain1/domain2 instead of org1
- Fix example to use DefaultFilteredAdapter for all filtered enforcer creation
- Example now runs successfully and demonstrates all features

Co-authored-by: hsluoyz <[email protected]>
Copilot AI changed the title [WIP] Add support for casbin filtered policy enforcer Add filtered policy support for per-request enforcers in web frameworks Jan 10, 2026
Copilot AI requested a review from hsluoyz January 10, 2026 08:07
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Prefered way to use casbin in a web framework with lots of users?

4 participants