Using Casbin for permission control in PHP

PHP-Casbin is a powerful and efficient open-source access control library for PHP projects. It provides support for enforcing authorization based on various access control models, like ACL, RBAC, ABAC etc.

This article will introduce how to use Casbin in PHP and implement an RBAC+RESTful permission control.

Get Started

The three core concepts of Casbin are: Model, Policy, Enforcer.

In Casbin, an access control model is abstracted into a CONF file based on the PERM metamodel (Policy, Effect, Request, Matchers).

Policy is the stored dynamic policy rules, which can be stored in a .csv file or in a database.

Enforcer decides whether a “subject” can access a “object” with the operation “action”.

Installation

Via composer.

composer require casbin/casbin

Try it

Create a model.conf and policy.csv file.

model.conf:

[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

policy.csv:

p, alice, data1, read
p, bob, data2, write

New a Casbin enforcer with a model file and a policy file:

use Casbin\Enforcer;

$enforcer = new Enforcer("path/to/model.conf", "path/to/policy.csv");

// Add an enforcement hook into your code right before the access happens
$enforcer->enforce('alice', 'data1', 'read'); // true
$enforcer->enforce('alice', 'data2', 'write'); // false
$enforcer->enforce('bob', 'data1', 'read'); // false
$enforcer->enforce('bob', 'data2', 'write'); // true

RBAC with Casbin

Here we use the officially provided DBAL Adapter.

composer require casbin/casbin
composer require casbin/dbal-adapter

Use RBAC Model

Our model.conf has the following contents:

[request_definition]
r = sub, obj, act

[policy_definition]
p = sub, obj, act

# the definition for the RBAC role inheritance relations
[role_definition]
g = _, _

[policy_effect]
e = some(where (p.eft == allow))

[matchers]
m = g(r.sub, p.sub) && keyMatch2(r.obj, p.obj) && regexMatch(r.act, p.act)

New a Casbin enforcer with RBAC Model

use Casbin\Enforcer;
use CasbinAdapter\DBAL\Adapter;

$adapter = Adapter::newAdapter([
  'driver' => 'pdo_mysql',
  'host' => '127.0.0.1',
  'dbname' => 'test',
  'user' => 'root',
  'password' => '',
  'port' => '3306',
]);

$enforcer = new Enforcer('path/to/model.conf', $adapter);

Add Policy

Assign roles to Alice and bob

// alice has the admin role
$enforcer->addRoleForUser('alice', 'admin');
// bob has the member role
$enforcer->addRoleForUser('bob', 'member');

Assign permissions to roles, member has all read operations:

$enforcer->addPermissionForUser('member', '/foo', 'GET');
$enforcer->addPermissionForUser('member', '/foo/:id', 'GET');

admin has all read and wirte operations:

// admin inherits all permissions of member
$enforcer->addRoleForUser('admin', 'member');

$enforcer->addPermissionForUser('admin', '/foo', 'POST');
$enforcer->addPermissionForUser('admin', '/foo/:id', 'PUT');
$enforcer->addPermissionForUser('admin', '/foo/:id', 'DELETE');

Now the policy rules in the database are probably like this:

g, alice, admin
g, bob, member

p, memeber, /foo, GET
p, memeber, /foo/:id, GET

g, admin, member

p, admin, /foo, POST
p, admin, /foo/:id, PUT
p, admin, /foo/:id, DELETE

Verify permissions

alice has all the permissions of /foo.

$enforcer->enforce('alice', '/foo', 'GET'); // true
$enforcer->enforce('alice', '/foo', 'GET'); // true

$enforcer->enforce('alice', '/foo', 'POST'); // true
$enforcer->enforce('alice', '/foo/1', 'PUT'); // true
$enforcer->enforce('alice', '/foo/1', 'DELETE'); // true

bob has member role, only read permission for /foo.

$enforcer->enforce('bob', '/foo', 'GET'); // true
$enforcer->enforce('bob', '/foo', 'GET'); // true

$enforcer->enforce('bob', '/foo', 'POST'); // false
$enforcer->enforce('bob', '/foo/1', 'PUT'); // false
$enforcer->enforce('bob', '/foo/1', 'DELETE'); // false

Conclusion

In this article, we demonstrated how to use Casbin in PHP. We created a Enforcer using model files and policy files. We also used a database adapter to store policies in the database, assigned roles to users, and added RBAC+RESTFul interface policies. Casbin is a versatile library that can be customized to your specific access control needs. It also provides many extensions that can quickly integrate Casbin in Laravel, Yii, and Codeigniter. You can find more information about PHP-Casbin in Github.