Weave Code
Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Rbac Bundle Laravel Package

sylius/rbac-bundle

Sylius RBAC Bundle adds role-based access control to Sylius applications, with roles, permissions, and resource-level authorization for admin and storefront access. It integrates with Symfony Security to simplify managing user privileges securely.

View on GitHub
Deep Wiki
Context7

Getting Started

This is a Symfony 2-era bundle, not a Laravel package. There is no service provider, facade, config file, migration set, or Artisan command to publish. You cannot composer require it into a modern Laravel app without hitting dependency conflicts against Symfony/Doctrine constraints. The realistic day-to-day use is as a reference implementation for hierarchical RBAC that you port into your own Laravel codebase.

Where to look first, in order:

  1. composer.json — confirm the version pins and the fact that it is archived. This tells you immediately that you are reading, not installing.
  2. The model layer — Role, Permission, RoleInterface, PermissionInterface. This is the schema you actually want: a self-referencing roles table plus a role↔permission pivot and a user↔role pivot.
  3. Doctrine mappings and repositories — the relational intent is the most reusable asset. Port them to migrations; ignore the mapping annotations themselves.
  4. Security wiring — how the bundle plugs into Symfony's hierarchy/voters. This is the logic to re-implement behind Laravel's Gate.

First use case to validate the design end to end: create ROLE_ADMIN > ROLE_MANAGER > ROLE_USER, attach permissions such as user.create and user.delete to the appropriate roles, assign a role to a user, and assert that an inherited permission resolves as granted. If you can prove that loop in ~50 lines of Eloquent, you have extracted everything the package is worth to you.

Implementation Patterns

Model the hierarchy as data, not config. The package's core idea is a self-referencing role table (parent_id) plus a pivot. Port it directly:

// roles: id, name, parent_id
// permissions: id, name
// permission_role: role_id, permission_id
// role_user: role_id, user_id

Resolve permissions by walking ancestors. Do not flatten this into Symfony-style security.role_hierarchy arrays if roles are user-editable; the database is the source of truth.

public function permissionsFor(User $user): array
{
    return $user->roles()
        ->with('ancestors.permissions')   // eager-load the chain
        ->get()
        ->flatMap(fn ($role) => $role->selfAndAncestors())
        ->flatMap(fn ($role) => $role->permissions->pluck('name'))
        ->unique()
        ->values()
        ->all();
}

Expose it through a single authorization surface. Wrap the resolver in one service and register Gates against it — never sprinkle in_array('user.delete', ...) or role-string checks through controllers.

foreach (['user.create', 'user.delete', 'order.refund'] as $perm) {
    Gate::define($perm, fn (User $u) => $this->rbac->can($u, $perm));
}

// or generically, via a single before() closure or Policy base class

Seed the hierarchy idempotently. Roles and permissions are configuration-like data; use updateOrCreate in a seeder or a rbac:sync command so redeploys don't duplicate or clobber. Treat the seeder as code-reviewed and versioned.

Cache the resolved map and bust it deliberately. Role graphs change rarely; permission expansion on every request does not scale in spirit. Cache user:{id}:permissions (or a role→permissions map keyed by role) and invalidate on role/permission/assignment writes through model events.

For non-role checks, map the package's voter concept to Policies. The bundle's extension point is Symfony voters; the Laravel equivalent is a Policy or a closure added to Gate. Anything that isn't pure role/permission (ownership, tenant scoping) belongs there, not in the RBAC resolver.

Gotchas and Tips

  • Archived and unmaintained. Treat this as a spec, not a dependency. If you fork or vendor the underlying sylius/rbac component, you own it and its CVE response — budget for that or don't do it.
  • No Laravel integration exists. There is no service provider, no publishable config, no migration. Every integration point is code you write. If your team's instinct is "install and configure," the correct answer is "port the schema and reimplement the resolver."
  • Cycle risk is real. A parent/child role graph can contain a cycle from a bad admin edit. Guard your ancestor walk with a visited-set or a max-depth; a runaway traversal is a hard failure, not a graceful denial.
  • N+1 on hierarchy traversal. Naive $role->parent->parent->... access will fan out queries. Prefer an eager-loaded ancestor path, a recursive CTE, or a materialized closure table if depth grows.
  • String-permission drift. The package relies on permission names being consistent. Centralize permission names as constants or an enum; free-typed strings in seeders and Gates diverge quickly and fail silently (deny rather than error).
  • Superuser short-circuit. Almost every RBAC implementation ends up needing a "can do everything" escape hatch. Add it explicitly and document it, or you get scattered admin bypasses in controllers.
  • Deny-by-default. Permission checks should fail closed when the resolver is empty, throws, or cache is cold. Do not let a caught exception default to "allow."
  • Cache invalidation is the sharp edge. Invalidating on role.permissions pivot writes, role parent changes, and user role assignment requires model event coverage on the pivot models too, not just Role/Permission. Missing one produces stale grants — the worst kind of bug in authorization.
  • Watch the config-vs-data boundary. If you follow Symfony and put hierarchy in a config file, admins can't change roles at runtime. If you follow the DB, you need cache invalidation. Choose deliberately; the bundle chose the DB.
  • Extension point to mirror, not copy: Symfony voters map cleanly to Laravel Policies. Don't port Symfony security contracts — the framework coupling is exactly why this bundle can't run here.
Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
gmostafa/php-graphql-client
xeviant/paystack
snowsoft/faker
meditationsteps/blogetc
animalyoung/laravel-influxdb
onix-solutions/sms-telera
lonely-lights/prosetta
oxygen/data
oxygen/core
jengo/base
xiloryx/log-collector
a21ns1g4ts/filament-stripe
la-php/laravel-admin
artisan-build/community-prompts
vleroy/smart
ayles-software/laravel-australian-public-holidays
cboxdk/laravel-id-spatie
cboxdk/laravel-id-billing
cboxdk/laravel-id-billing-bridge
simple-as-fuck/php-performance-log