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 Laravel Package

sylius/rbac

Sylius RBAC is a Sylius plugin that adds role-based access control to the admin panel. Define roles and granular permissions for resources and actions, then restrict users to only the operations they need.

Deep Wiki
Context7

Getting Started

Treat sylius/rbac as an embedded domain component, not a full security solution. It is archived/read-only, so the first step is to confirm why it is present:

composer show sylius/rbac
composer why sylius/rbac

If you are in a Sylius application, it is almost certainly a transitive dependency; do not build new features directly against it unless you are already committed to the Sylius admin role model. If you are evaluating it for a new application, prefer Symfony’s native role hierarchy plus a small custom voter or a maintained RBAC package.

Where to look first:

  1. Model/Role.php, Model/Permission.php, and their interfaces — these define the data model.
  2. Provider/checker/voter classes, if present in your installed version — these define how permissions are resolved.
  3. Tests/specs — with an archived component, tests are often the most reliable documentation.
  4. The consuming bundle’s service configuration — the component itself usually has no bundle wiring.

Minimal integration shape:

  • Create Doctrine entities extending the package models, e.g. App\Entity\Role extends Sylius\Component\Rbac\Model\Role.
  • Map Role and Permission with Doctrine, including the role hierarchy relation and role-to-permission collection.
  • Register repositories and the role provider/checker services expected by the package.
  • Integrate roles with your user entity, typically a many-to-many association.
  • Expose role codes to Symfony Security and add a voter/checker for fine-grained permissions.

First use case: model an editor role that can edit products but not users.

$editor = new Role();
$editor->setCode('ROLE_EDITOR');
$editor->setName('Editor');
$editor->addPermission($productEditPermission); // "product.edit"
$editor->setParent($userRole); // ROLE_USER

Then check the permission in a controller, Twig template, or voter:

$this->denyAccessUnlessGranted('product.edit');

If your installed version does not provide a permission-aware voter, write a small one that walks the user’s roles and their hierarchy, rather than calling the component directly from controllers.

Implementation Patterns

Use role hierarchy for coarse access, permissions for fine access. Keep Symfony role codes such as ROLE_ADMIN and ROLE_EDITOR for firewall/access_control rules. Use permission strings such as product.edit, order.show, or user.delete for business-level checks. Do not overload role codes as permissions.

Seed roles and permissions through fixtures or migrations. Roles and permissions are data, not configuration. Create deterministic seed data so every environment has the same permission catalogue:

$permissions = [
    'product.edit' => 'Edit products',
    'product.delete' => 'Delete products',
    'user.manage' => 'Manage users',
];

Use constants or an enum for permission codes. Silent typos in string permissions are one of the most common failure modes.

Build a permission voter instead of coupling controllers to the model. A typical voter:

protected function voteOnAttribute(string $attribute, mixed $subject, TokenInterface $token): bool
{
    $user = $token->getUser();
    if (!$user instanceof UserInterface) {
        return false;
    }

    foreach ($user->getRoles() as $role) {
        if ($this->roleHasPermission($role, $attribute)) {
            return true;
        }
    }

    return false;
}

roleHasPermission() should walk the role hierarchy upward, so a child role inherits parent permissions. Cache the flattened permission map per role if checks are frequent.

Integrate hierarchy with Symfony’s RoleHierarchy. If your version stores parent/child roles, build a hierarchy map and pass it to Symfony’s role hierarchy voter. This lets ROLE_EDITOR inherit ROLE_USER without duplicating roles in the token. Remember that role hierarchy changes usually require a cache clear or a cache reset.

Use access_control for firewall-level checks and voters for object/permission checks. Example:

security:
    access_control:
        - { path: ^/admin, roles: ROLE_ADMIN }

Then use isGranted('product.edit') inside admin controllers for specific actions. Avoid trying to express every permission in access_control; it becomes unmaintainable.

Admin UI pattern. A role form usually contains: code, name, parent role, and a collection of permissions grouped by domain. Use a CollectionType or a checkbox group. Validate that role codes are unique and that a role cannot be its own ancestor.

Service decoration is the main extension point. If the package’s role provider or checker does not fit your needs, decorate it or replace it in services.yaml. Because the package is archived, prefer decorating over forking. Keep your custom logic in application code so a future migration is easier.

Testing pattern. Unit-test the voter with mocked roles and permissions. Functional-test that a seeded role can access one route and is denied another. Add a test for hierarchy inheritance and a test for cycle prevention.

Gotchas and Tips

Archived means no security fixes. Pin the version in composer.json, monitor Symfony security advisories, and plan an exit strategy. For new projects, a custom voter plus Symfony role hierarchy is usually less risk than adopting an archived RBAC component.

Role codes and permission codes are different concepts. A common mistake is checking isGranted('ROLE_EDITOR') for a feature that should be permission-based, or storing product.edit as a Symfony role. Keep the two layers explicit.

Hierarchy cycles are easy to create and hard to debug. A role whose parent chain loops back to itself can cause infinite recursion in permission resolution. Add validation on the form and a defensive visited-set in the checker.

Changes to roles may not take effect immediately. Role hierarchy and permission maps are often cached. Clear the cache after changing role data, and if you cache flattened permissions yourself, invalidate that cache on role/permission updates.

Watch for N+1 queries. Loading users, their roles, role parents, and permissions can trigger many queries. Use fetch joins or batch-load permissions when rendering admin lists or checking many permissions in a loop.

Doctrine inheritance mapping needs care. Extend the package models rather than mapping vendor classes directly. Configure resolved target entities so associations point to your application entities, not the component’s base classes.

Deletion constraints. Roles are referenced by users and by child roles. Decide whether deleting a role should be blocked, reassign children, or cascade. Without explicit handling, you will get foreign-key errors or orphaned hierarchy data.

Super-admin bypass can mask bugs. If ROLE_ADMIN bypasses permission checks, tests using an admin user will not catch missing permissions. Test with a narrowly scoped role.

Debugging authorization failures. Use the Symfony profiler’s Security panel and enable access decision logging in dev. Check the token’s roles first, then the voter’s decision, then the role hierarchy map. Most “permission denied” reports are caused by a role not being assigned, a stale cache, or a permission code typo.

Serialization and forms can loop. Parent/child role relations are circular by nature. Use serialization groups or view models for APIs, and avoid rendering the full role graph in forms.

Do not expect a bundle. This package is a component. If you need routes, forms, DI configuration, or admin CRUD, you either get them from a consuming bundle or write them yourself. That is a significant integration cost for a 12-star archived package.

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.
pharaonic/laravel-notification-dependencies
beautinow/translug
dev-brainiac/bot-cloaked
octoberrain/html
octoberrain/extension
octoberrain/exception
octoberrain/contracts
frankyso/ipaymu
3mdikram/worldmoneywords
snowsoft/config
itmosoft/laravel-subscriptions
larva/laravel-ai-qwen
adachsoft/api-version-bundle
cgv/localized-resource
noith/settings
kda/laravel-package
kda/filament-dynamic-navigation
bypersoft/signbox
pairus/product-data
fayne/laravel-filament-cms-core