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

Acl Bundle Laravel Package

nuxia/acl-bundle

nuxia/acl-bundle is a lightweight ACL package for Laravel/PHP applications, providing role- and permission-based access control so you can protect routes, resources, and actions with configurable rules. It helps centralize authorization logic and keep application code clean.

View on GitHub
Deep Wiki
Context7

Getting Started

First, a reality check: despite the name pairing you'll often see in Laravel shops, nuxia/acl-bundle is a Symfony bundle, not a Laravel package. It wraps Symfony's symfony/security-acl component to provide annotation-driven permission checks. If you're committing to a Laravel codebase, this package will not drop in — there is no Laravel service provider, facade, or config file.

Assuming a Symfony (2.x/3.x era) project:

  1. Install the component the bundle depends on first, not just the bundle — the ACL component is standalone and was split out of the framework:
    composer require nuxia/acl-bundle symfony/security-acl
    
  2. Register the bundle in app/AppKernel.php (Symfony 2/3) or config/bundles.php (Symfony 3.3+):
    new Nuxia\AclBundle\NuxiaAclBundle(),
    
  3. Create the ACL schema. The ACL component stores grants in five Doctrine tables (acl_classes, acl_entries, acl_object_identities, acl_object_identity_ancestors, acl_security_identities). Run the schema tool or the ACL init console command before anything works.
  4. Configure the ACL provider and permission map under nuxia_acl: in config.yml — this is where you point at your user entity and declare which permission names map to which masks.

Where to look first: the bundle's annotation class (Nuxia\AclBundle\Annotations\Acl) and its manager service definition. There is essentially no README worth reading (2 stars, 0 dependents, 0 examples), so the annotations and service container config are the documentation.

First use case — annotate a controller action:

use Nuxia\AclBundle\Annotations\Acl;

/**
 * @Acl(permissions={"VIEW"}, object="post")
 */
public function showAction(Post $post) { /* ... */ }

This is the lowest-friction entry point and mirrors Symfony's native @Security annotation, but resolves permissions against the ACL provider instead of the voter system.

Implementation Patterns

Annotation guard on controller actions. The bundle's core value is letting you express required permissions declaratively on methods, resolving the target object from a route parameter or argument name. Use this for CRUD controllers where the permission is obvious and static per action.

Programmatic grant/revoke via the manager service. For admin tooling ("share this post with user X", "make Y an editor"), inject the ACL manager and call grant/revoke directly. This is the pattern that actually replaces hand-rolled permission tables:

$aclManager->grant($post, $user, ['EDIT']);
$aclManager->revoke($post, $role, ['VIEW']);

Object-level vs class-level. ACL supports two scopes: a class-wide identity (the equivalent of "all posts can be viewed") and a per-object identity (this specific post). Use class-level for coarse defaults and object-level only for per-item overrides — mixing the two without discipline is the #1 source of "why can this user see this?" tickets.

Mask building for fine-grained control. The underlying MaskBuilder composes atomic permissions (VIEW, EDIT, CREATE, DELETE, OWNER) into a bitmask. If your app needs "edit but not delete," build custom masks rather than granting EDIT and special-casing DELETE in a voter elsewhere.

Security identity is a user or a role. Grants are stored against a SecurityIdentity, which can be a UserSecurityIdentity (class + identifier) or a RoleSecurityIdentity. Effective permissions are the union of both. Design your permission model around "what does this role grant globally" plus "what does this user get on this object," and don't be surprised when a role grant shows up on an object check.

Integration tip: wrap annotation-driven checks so that a PermissionDeniedException produces a clean 403 rather than a 500 — the annotation listener throws, and without a kernel.exception handler you'll leak stack traces.

Gotchas and Tips

  • The Symfony ACL component is deprecated. It was deprecated in Symfony 4.0 and removed from the framework in 4.4; the standalone component is effectively unmaintained. Building new access control on this in a modern Symfony app is a dead end — use voters or a dedicated permissions package instead.
  • Not Laravel-compatible, period. There is no service provider. Do not try to port it; reimplement with policies/gates.
  • The schema is mandatory and easy to forget. No ACL tables = silent "denied" or a Doctrine error, depending on config. Verify the five tables exist before debugging logic.
  • Performance is the real cost. Every object-identity lookup is a Doctrine query, and inheritance walks the ancestor table. On list pages this becomes N+1 fast. Preload identities in bulk, cache resolved masks per user/request, and avoid per-row annotation checks in loops.
  • Object identity caching bites in dev. ACL results are cached aggressively (and object identities are per-entity). After changing grants, clear the cache or you'll chase phantom denials.
  • Annotation reader config. If annotations appear to be ignored, confirm framework.annotations (or the equivalent reader) is enabled and that the bundle's listener is registered — with doctrine/annotations absent, the guard silently no-ops on some Symfony versions.
  • Extension points are limited: decorate the ACL manager service to add logging or caching, and swap the permission map if you need custom mask names. Beyond that, the bundle is a thin wrapper — expect to reach into the underlying AclProviderInterface directly.
  • Risk assessment: 2 stars, 0 dependents, no meaningful docs or tests. Treat it as a reference implementation to copy from, not a long-term dependency. If you need its annotation ergonomics, read the two or three classes that matter and port the logic into your own voters — you'll get the same day-to-day feel without the abandoned-package liability.
  • Debugging checklist: (1) are the ACL tables populated and does the security identity match your user's class+identifier exactly? (2) is the object identity type registered? (3) did you grant the mask the annotation actually checks? Log the resolved mask, not just the boolean.
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.
uni-method/symfony-lib
tacticmedia/scim-server-bundle
neika-ai/symfony-bundle
mattleads/agent-publishing-bundle
glavweb/framework-bundle
glavweb/extra-bundle
glavweb/api-bundle
glavweb/admin-bundle
adachsoft/api-version-bundle
elsayed85/laravel-api-exceptions
ouhssini/laravel-demo-mode
daworks/ncloud-outbound-mailer-driver
gp247/cms
ignibyte/aic-gates
nexa-merchant/blog
novasa/laravel-language-center
opencage/geocode
adolfoholzer/parameters
livenetworks/ln-starter
cgv/localized-resource