Skip to content

Instantly share code, notes, and snippets.

@StevenACoffman
Last active April 7, 2024 02:43
Show Gist options
  • Save StevenACoffman/1644ec1157a793eb7d868aa22b260e91 to your computer and use it in GitHub Desktop.
Save StevenACoffman/1644ec1157a793eb7d868aa22b260e91 to your computer and use it in GitHub Desktop.
OPA vs Casbin

Information in this Gist originally from this github issue, which is outdated.

As @RomanMinkin mentioned, you can also consider Casbin (https://github.com/casbin/casbin). It is the most starred authorization library in Golang. There are several differences between Casbin and OPA.

Feature Casbin OPA
Library or service? Library/Service Library/Service
How to write policy? Two parts: model and policy. Model is general authorization logic. Policy is concrete policy rule. A single part: Rego
RBAC hierarchy Casbin supports role hierarchy (a role can have a sub-role) Role hierarchies can be encoded in data. Also with the new graph.reachable() built-in function queries over those hierarchies are much more feasible now.
RBAC separation of duties Not supported Supported: two roles cannot be assigned together
ABAC Casbin supports to directly retrieve Golang struct's members as attributes OPA needs to be provided with an attribute list (JSON) or Golang struct
Built-in functions RESTful match, IP match, regex are supported. You can also write your own Golang function and let Casbin use it Functions like regex, max, min, count, type conversion are supported. You can write your own built-in functions.
Policy storage All common databases are supported by dozens of middlewares, like SQL, NoSQL, Key-Value, AWS S3, etc. Not supported, you need to write your own code if you want to use DB like MySQL.
Conflict resolution Allow-override, Deny-override, Allow-and-no-Deny, Priority are built-in supported. You can also write your own Effector logic (in code) to have a custom conflict resolution Allow-override, Deny-override, Priority (but grammar is a little long). You can also resolve conflicts inside Rego itself.
Distributed authorization You can use multiple Casbin instances together. Sharding and policy change notification are supported One single OPA service
Other programming languages Golang, Java, PHP, Node.JS, Python, .NET, Delphi, Rust and others are supported (> 8) Golang, WASM (NodeJS in progress)
Adopters Intel, VMware, Docker, Cisco, Banzai Cloud, Orange, Tencent Cloud, Microsoft Netflix, Chef, SolarWinds, Cisco, Cloudflare, Pinterest, State Street Corporation

(let me know if the above table is not accurate)

Metric casbin OPA
Page rank 6.756345697844901e-05 2.1407964930428962e-05
Stars 6783 3413
Order by page rank 246 744
Order by page rank in github repos 133 583
Order by stars 166 436
Imported by 73 repos 23 repos
Imports 16 repos 71 repos

OPA

OPA is primarily developed by Styra Inc. Styra is building "authorization as a service" which is backed by OPA. The marketing is slicker, and it appears a little more focussed on commercial service integrations.

Casbin

Casbin's originator works for Microsoft Research, it doesn't have a group of sales people, but it appears more popular at a grassroots level.

@SPopenko
Copy link

@hsluoyz

Please name a scenario that Casbin cannot do.

Do you have any suggestions how to implement reverse db query case with Casbin like it was described here: https://blog.openpolicyagent.org/write-policy-in-opa-enforce-policy-in-sql-d9d24db93bf4

The problem is with collection endpoint and DB queries. Like you have sql db table with pets and api v1/pets that should return all pets that you have access to. That are the pets you own and for example any pet that you treat as a veterinarian.

The classical issue is how to apply policy without fetching all table data and then evaluating each record individually. Basically auth service should answer a question: “what pets user Bob could see?” and then convert this response into the query. I was failed to find solution with casbin :( I would appreciate if someone could share the ideas how to solve this pretty common task.

@Kingside88
Copy link

@hsluoyz

Please name a scenario that Casbin cannot do.

Do you have any suggestions how to implement reverse db query case with Casbin like it was described here: https://blog.openpolicyagent.org/write-policy-in-opa-enforce-policy-in-sql-d9d24db93bf4

The problem is with collection endpoint and DB queries. Like you have sql db table with pets and api v1/pets that should return all pets that you have access to. That are the pets you own and for example any pet that you treat as a veterinarian.

The classical issue is how to apply policy without fetching all table data and then evaluating each record individually. Basically auth service should answer a question: “what pets user Bob could see?” and then convert this response into the query. I was failed to find solution with casbin :( I would appreciate if someone could share the ideas how to solve this pretty common task.

I troubled also with this issue and solved it this way:

  1. I read out the permissions the user has: enforcer.GetImplicitPermissionsForUser(userId)
  2. Iterate these permissions and filter which of the permission types you need to filter your data itself. This data I stored in a seperate List of strings.
  3. Join all the result by String.Join(','myList) to a comma seperated string
  4. Query the Database by manipulating the Where clause: SELECT * FROM pets WHERE PetId IN (MyCommaSeperatedString).

I hope to see this feature further included in Casbi.

@vtolstov
Copy link

@hsluoyz

Please name a scenario that Casbin cannot do.

Do you have any suggestions how to implement reverse db query case with Casbin like it was described here: https://blog.openpolicyagent.org/write-policy-in-opa-enforce-policy-in-sql-d9d24db93bf4
The problem is with collection endpoint and DB queries. Like you have sql db table with pets and api v1/pets that should return all pets that you have access to. That are the pets you own and for example any pet that you treat as a veterinarian.
The classical issue is how to apply policy without fetching all table data and then evaluating each record individually. Basically auth service should answer a question: “what pets user Bob could see?” and then convert this response into the query. I was failed to find solution with casbin :( I would appreciate if someone could share the ideas how to solve this pretty common task.

I troubled also with this issue and solved it this way:

  1. I read out the permissions the user has: enforcer.GetImplicitPermissionsForUser(userId)
  2. Iterate these permissions and filter which of the permission types you need to filter your data itself. This data I stored in a seperate List of strings.
  3. Join all the result by String.Join(','myList) to a comma seperated string
  4. Query the Database by manipulating the Where clause: SELECT * FROM pets WHERE PetId IN (MyCommaSeperatedString).

I hope to see this feature further included in Casbi.

If you have 10000 pets, i think in clause and store this array before query is not good

@IceQub3
Copy link

IceQub3 commented Jan 14, 2022

I belive that knowing what animals you own isnt the responsibility of the auth service nor policy. The database itself shoud keep record on pet ownership and policy should be use to istruct service over joining the tables and filtering results. (Should user read only his own animals? Then use specific implementation. Shoud user get access to other animals, lets say Georges animals, than querying shoud be performed as all animals owned by george and the user.
The db dont understand why this user is allowed to query Georges animals. It is in the policy that user can query animals of direct employees.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment