Google Zanzibar-style authorization for PHP. Works with Laravel and Symfony.
composer require sseffa/zanzibar-phpuse Zanzibar\Zanzibar;
use Zanzibar\Config\NamespaceConfig;
$zanzibar = Zanzibar::create()
->withNamespace(
NamespaceConfig::create('document')
->addRelation('owner')
->addRelationIncluding('editor', 'owner')
->addRelationIncluding('viewer', 'editor')
)
->build();
// Grant permission
$zanzibar->allow('document:123', 'viewer', 'user:alice');
// Check permission
$zanzibar->can('document:123', 'viewer', 'user:alice'); // true
// Owner inherits editor and viewer
$zanzibar->allow('document:123', 'owner', 'user:bob');
$zanzibar->can('document:123', 'viewer', 'user:bob'); // true- Tuple-based model:
(object, relation, subject) - Relation inheritance: owner -> editor -> viewer
- Group permissions:
group:team#member - Wildcards:
user:*for public access - Exclusion: subscriber AND NOT banned
- Folder hierarchy: inherit permissions from parent
Auto-discovered. Publish config:
php artisan vendor:publish --tag=zanzibar-config// config/zanzibar.php
'namespaces' => [
'document' => [
'owner' => null,
'editor' => 'owner',
'viewer' => 'editor',
],
],Usage:
use Zanzibar\Laravel\Facades\Zanzibar;
Zanzibar::allow('document:1', 'viewer', 'user:1');
Zanzibar::can('document:1', 'viewer', 'user:1');Register bundle:
// config/bundles.php
Zanzibar\Symfony\ZanzibarBundle::class => ['all' => true],# config/packages/zanzibar.yaml
zanzibar:
secret: '%env(APP_SECRET)%'
namespaces:
document:
owner: ~
editor: owner
viewer: editoruse Zanzibar\Core\SubjectRef;
$zanzibar->allow('group:team', 'member', 'user:alice');
$zanzibar->allow('document:1', 'viewer', SubjectRef::userset('group', 'team', 'member'));
$zanzibar->can('document:1', 'viewer', 'user:alice'); // true$zanzibar->allow('video:1', 'viewer', SubjectRef::wildcard('user'));
$zanzibar->can('video:1', 'viewer', 'user:anyone'); // trueuse Zanzibar\Config\Rewrite\{ComputedUserset, ExclusionUserset};
NamespaceConfig::create('channel')
->addRelation('subscriber')
->addRelation('banned')
->addRelationWithRewrite('can_view', new ExclusionUserset(
base: new ComputedUserset('subscriber'),
subtract: new ComputedUserset('banned'),
));use Zanzibar\Config\Rewrite\{DirectUserset, ComputedUserset, TupleToUserset, UnionUserset};
NamespaceConfig::create('folder')
->addRelation('parent')
->addRelationWithRewrite('viewer', new UnionUserset([
new DirectUserset(),
new TupleToUserset('parent', 'viewer'),
]));
$zanzibar->allow('folder:root', 'viewer', 'user:alice');
$zanzibar->allow('folder:child', 'parent', 'folder:root');
$zanzibar->can('folder:child', 'viewer', 'user:alice'); // truecomposer testMIT