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

laravel-doctrine/acl

Provides ACL support for Laravel Doctrine, letting you define roles and permissions as Doctrine entities and check access to resources through a Laravel-friendly API. Useful for adding role-based authorization to Doctrine-backed Laravel apps.

View on GitHub
Deep Wiki
Context7

Getting Started

laravel-doctrine/acl plugs Doctrine's ACL component into Laravel's authorization Gate, so $user->can('post.edit'), Gate::allows(...), @can in Blade and $this->authorize(...) in controllers all resolve through ACL entries stored in the database instead of hand-written policies. It sits on top of laravel-doctrine/orm, so you need the ORM package configured with an entity manager first.

  1. composer require laravel-doctrine/acl — as of 2.1.0 the constraint tracks Laravel 13 (see Gotchas if you're on an older major).
  2. Publish the package config (php artisan vendor:publish and pick the ACL provider/tag) and inspect config/acl.php. This is the file that matters most: it maps your User entity, the Role/Permission entities, the ACL table names and the default security identity.
  3. Add the package traits to your User entity (HasRoles, HasPermissions, or the combined permissible trait) and make sure the entity implements the package's security-identity contract.
  4. Create the ACL tables (acl_classes, acl_entries, acl_object_identities, acl_object_identity_ancestors, acl_security_identities) either through the Doctrine schema tool or published migrations — nothing works until these exist.
  5. First use case: seed a role and a permission, grant it programmatically, then call Gate::allows('post.edit') from a controller or @can('post.edit') in a view.

Look first at config/acl.php and the package's contracts directory; almost every "it returns false" problem is a mapping in that config or a missing ACL table row.

Implementation Patterns

Traits over custom policies. The usual workflow is to give User the role/permission traits and attach the permissible trait to entities you want to protect. Once wired, you stop writing per-action policy classes for CRUD permissions and instead grant post.edit / post.delete strings to roles at seed or admin time.

Gate as the single entry point. Because the package registers a Gate adapter backed by Doctrine ACL, all the Laravel ergonomics still apply: Gate::inspect() for denial messages, Gate::before() for super-admin bypass (fn ($user) => $user->hasRole('super-admin') ?: null), can middleware on routes, and @can/@cannot in Blade.

Seeding and admin UI. Manage grants through the ACL manager the service provider binds into the container rather than editing rows by hand. A typical pattern is a RoleSeeder that creates role entities and inserts object identities once, plus an admin screen that only ever inserts/deletes acl_entries for existing identities.

Policies as thin delegators. For anything with business rules beyond a flat permission, keep a Laravel policy and have it call the ACL check internally (return $user->can('post.edit', $post) || $post->isDraft()), so authorization logic stays discoverable via php artisan inspection but still benefits from centrally-managed grants.

Organisation / multi-tenant scoping. The package's organisation contract lets you scope roles to a tenant. Resolve the current organisation in a middleware and inject it when checking permissions rather than baking tenant IDs into permission slugs.

Long-running processes. In Octane/queued workers, ACL decisions can be cached in memory. Flush the ACL cache when a grant or revoke is written, or wire the Doctrine ACL cache to a shared store, otherwise a worker keeps serving stale "allowed" results.

Gotchas and Tips

  • Version pinning. 2.1.0 is a compatibility release (PR #76, "laravel 13") with no API changes. If you're still on Laravel 10/11/12, stay on the 2.0.x line and let Composer resolve; don't force the constraint without also bumping laravel-doctrine/orm and PHP, since Laravel 13 raises the PHP floor.
  • Silent denials. A misspelled permission slug or a role that was never granted is indistinguishable from "denied" — it just returns false. Log denials with Gate::inspect()->message() during development.
  • Identity requirements. ACL object identities are class + id + field. Checking permission on an unsaved entity, or on one with a non-standard identifier field, will miss or throw. Persist first; keep the identifier field stable.
  • Config FQCNs must be exact. If acl.php names an entity class that has been renamed or namespaced differently, you get confusing "class not found"-style errors or permanent denials. Re-run the config publish after upgrades and diff it.
  • Missing tables. The ACL schema is not created by your normal entity migrations by default. On a fresh environment, forgetting the ACL tables manifests as a SQL error only on the first can() call, not at boot.
  • Stale cache. The Doctrine ACL provider memoizes lookups per request/process; after any grant or revoke, invalidate explicitly. This bites hardest in tests that share a process.
  • Debugging. Read acl_entries and acl_object_identities directly to confirm what was actually written; a grant that "did nothing" is usually a failed flush or a transaction rollback in the seeder.
  • Extension points. Implement the package's Role/Permission contracts on your own entities if you need extra columns, and override the entity mappings in config/acl.php rather than extending the shipped entities.
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