alchemy/acl-bundle
Alchemy ACL bundle adds configurable access control entries to Symfony entities, with REST endpoints to list, create, update, and remove permissions per user, group, or object. Supports Redis-cached access tokens and flexible query filters.
/permissions/aces, /permissions/ace) instead of a bespoke permissions table. The buy case is legitimate only if you're on Symfony (or willing to run it as a service) — see the stack caveat below.objectId applies an ACE to every object of a type; null userId applies to everyone. That maps cleanly to product language users already understand: "all editors can view all publications, except this draft, which only the author can edit."publication/asset for a user or group is the feature set behind "share this document," "give the agency access to their listing," "invite a reviewer to this draft." Each of these is normally a multi-sprint feature; here it's configuration plus a controller.userType: group) let you model org-level access without a second system.mask: 7 is an integer with no shipped semantics — product must define what each bit means (view/edit/delete/share), document it, and enforce it consistently. That's a real design task, not a config line.Consider it when:
Gate/Policy doesn't cover out of the box.accessToken.cache pool, and you're comfortable with a YAML-configured, code-deployed list of ACL-able entities.Look elsewhere when:
UserRepositoryInterface aliasing, Symfony cache pools. In Laravel you would be either (a) standing up a small Symfony service purely for ACL, or (b) porting the logic into Eloquent, at which point you've built it yourself. For a Laravel-native product, spatie/laravel-permission plus policies is the lower-risk path; note that spatie is role/permission-centric, not per-object, so per-object still needs custom work.department AND clearance), policy languages, or inheritance hierarchies. This is ACE-based, not a policy engine.if checks. Don't adopt an ACL system to solve a three-line problem.Executives: "Object-level permissions — 'this editor can change this draft, not all drafts' — are normally a custom build. This package provides the data model and an API for it. Two honest caveats: it's a Symfony component, so the cost depends on whether we're a Symfony shop; and it's a small, thinly-adopted open-source project, so we'd be owning the risk. If we're Symfony, this is a weeks-not-months saving on the backend. If we're Laravel, the realistic version of this proposal is borrow the design, build the small piece — and I'd rather tell you that now than after a sprint of integration work."
Engineering: "Reusable ACL model: principals (user or group), targets (registered entities), ACEs with a numeric mask, plus global fallbacks via null IDs. Enforcement is a lookup; Redis caches tokens. Integration work if we're not on Symfony: replace the Doctrine user repository with our own, replace the cache pool, and define what the mask bits mean — that last one is ours to design regardless. Also note the entity registry is static YAML, so adding a permission-able model is a deploy. Recommendation: adopt as-is only on Symfony; otherwise treat the README as a spec and port ~200 lines into our own service, wired to Laravel policies. Either way, write the mask contract and test it."
Product managers: "This turns 'who can touch which record' into a managed, queryable thing instead of scattered checks in controllers. What you get: per-record sharing, group access, and an API that a future admin screen can use without backend changes. What you don't get: an admin screen, a permission vocabulary (we define the bits), or dynamic entity registration. Next steps — pick one entity, define the mask meanings in writing, ship enforcement behind a flag, and only build the management UI once support requests prove the need."
How can I help you explore Laravel packages today?