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

Laravel Authorization Laravel Package

apavliukov/laravel-authorization

A Laravel authorization package for defining and enforcing access rules. It helps organize roles, permissions, and policy-style checks so you can control which users can perform actions in your application.

View on GitHub
Deep Wiki
Context7

Technical Evaluation

Architecture fit v1.6.0 is a strategic narrowing, not a feature release. The package is now scoped to "single-database organizations, roles inside them, one platform admin" — the union of what oohire and opiny actually use. That is a defensible product decision for the author, and the resulting package is smaller, easier to reason about, and has a tighter security surface. But it changes what kind of dependency this is for us.

The load-bearing security property from v1.4.0 — the tenant scope fix that made BelongsToTenant restoration non-bypassable by Eloquent's restore() / Livewire / SerializesModels hydration paths — is not named as removed, and the notes state remaining behaviour is unchanged. That is the single thing we must verify independently rather than accept from release notes, because the same refactor deleted BypassStrategy and the pre-tenancy policy wiring from the authorization path adjacent to it. Confirm the scope/restore behaviour and the accompanying regression tests still exist at v1.6.0.

Two architecture-fit concerns:

  1. The bypass model is no longer pluggable. Contracts\BypassStrategy, RoleBypass, NoBypass and Authorization::bypassUsing() are gone. The provider now registers one Gate::before with a fixed rule: super-admin passes (under teams, only the global assignment counts), everyone else falls through, and it never returns false. If our app implemented a stricter or conditional bypass — impersonation, service accounts, deny rules, scoped break-glass — that logic has no extension point and must move into application policy code. Note the direction of the change: a bypass gate that never denies is more permissive than a custom strategy that could. That is a security-review item, not a styling detail.
  2. The tenancy shape is now fixed. TeamResolver and friends are removed, so an application with teams but no tenancy must call setPermissionsTeamId() from its own middleware. TenantScopedPolicy now assumes Tenancy::id() compares against the model's tenancy.foreign_key. Both are conventions we must match or work around; they are no longer configurable seams.

The most important architecture statement in the release is procedural, not technical: "Public API is removed in a minor on purpose (two consumers, both the author's)." That tells us semver is not a contract for external consumers, and the package is effectively a private package published publicly. Any integration must be planned on the assumption that future minors may delete whatever we depend on.

Integration feasibility Mechanically simple, structurally blunt. Every removed symbol is a hard Class not found or Method does not exist at boot or first call — there is no deprecation layer or shim, so failures are loud and enumerable by grep rather than subtle and emergent. That is a favourable failure profile for a one-time upgrade.

Three items need real work rather than a rename:

  • Removed artisan commands. authorization:sync, authorization:repair-ownership and make:authorization-policy are deleted. The first two typically live in deploy scripts, runbooks, or scheduled tasks; their failure mode is a broken deployment or a silently skipped sync, not a runtime exception. AuthorizationSeeder still syncs permissions and roles and re-derives owner rows on every run, so a replacement exists — but the deploy step must be rewritten, not just deleted, if it was the only thing keeping permissions converged.
  • userCan() semantics. It is now plain $user->can(); Support\UserPermissionMemo and forgetUserPermissions() are gone. Correctness is preserved, but the memoization is not. Policy-heavy rendering (Livewire tables, nav builders, index pages that check per-row abilities) may now issue one or more queries per check. This must be measured against our own hot paths before we accept "performance unchanged."
  • UI areas. Tenancy\CurrentArea, the authorization.areas config and the Livewire original-route hook are removed. Consumers that referenced CurrentArea::SESSION_KEY — the notes name oohire's Support\Areas and laravel-starter's CurrentLayout — need their own key. This fails loudest in test, but if the key is re-invented inconsistently the production symptom is users being returned to the wrong route after login or a tenant switch. Test it explicitly.

We are upgrading from v1.4.0, so we would traverse v1.5.0 without having adopted it. The 1.5.0 tenant-entry knobs (enterable_scope, fallback_to_owned, TenantResolver::choose()) are added and then removed within the same jump. Recommendation: go 1.4.x → 1.6.0 directly and do not adopt 1.5.0 features.

Technical risk

  • High (process) — deleted deploy commands. A pipeline or scheduled task invoking authorization:sync or authorization:repair-ownership breaks with no runtime signal until the deploy fails or permission drift accumulates unnoticed.
  • High (performance) — permission memo removal. userCan() losing memoization is a plausible p95 regression in Livewire-heavy admin screens and any policy evaluated per row. Benchmark before and after on representative pages.
  • High (security) — bypass semantics. A hardcoded Gate::before that never returns false replaces a pluggable strategy. Any prior custom bypass must be re-expressed in app code, and the new default must be explicitly reviewed for permissiveness. Super-admin under teams now counts only the global assignment — confirm admin seeding still produces a passing user.
  • Medium (shape) — teams without tenancy no longer supported. Applications that used the package purely as a team/role layer (or with non-single-DB tenancy) lose TeamResolver, SetPermissionsTeam and resolver wiring and must implement middleware themselves. Confirm we are inside the supported shape before committing.
  • Medium — CurrentArea session-key migration. Silent misrouting rather than an exception if re-implemented inconsistently.
  • Medium — TenantScopedPolicy FK convention. Policy wiring now hard-codes the tenancy.foreign_key comparison; models with a different or legacy FK name will fail authorization checks without an obvious cause.
  • Low — config key leftovers. enterable_scope, fallback_to_owned, areas must be dropped from a published config/authorization.php. Usually inert, but clean them so future readers do not believe they work.
  • Low — v1.4.0 security fix regression. Not reported as changed, but the surrounding code was cut. Re-run the existing tenant-switch restoration and soft-delete restoration tests against 1.6.0.

Key questions

  1. Is the v1.4.0 tenant-scope/restore fix untouched by the cut, and do its regression tests still ship and pass? Evidence, not release-note assurance.
  2. What were the v1.5.0 notes, and does skipping 1.5.0 entirely carry any migration we would miss (config renames, seeder changes, schema expectations)?
  3. Which of the removed symbols do we actually reference — full inventory across app code, tests, config, and CI/CD definitions? In particular, does any deploy step or scheduler call the three deleted commands?
  4. If we had a custom BypassStrategy, what was its exact rule, and where will it live now? Does the new "never returns false" Gate::before widen access for any role we currently grant?
  5. Does TenantScopedPolicy's tenancy.foreign_key comparison match every model we scope, including any legacy tables with non-standard FK names?
  6. What is the measured cost of userCan() → $user->can() on our top five policy-heavy screens, and is a replacement memo (application-level cache) needed?
  7. Who owns CurrentArea::SESSION_KEY now, and is there a single definition in our codebase?
  8. Given "removed in a minor on purpose," do we pin exactly (1.6.0) rather than ^1.6, and do we fork/vendor? What is the exit cost if the author cuts the next thing we depend on?

Integration Approach

Stack fit Same Laravel queue + Livewire stack as before; the tenancy-isolation blast radius described in the prior assessment (model-carrying jobs, serialized payloads, Livewire model properties) is unchanged and still the dominant integration concern. What v1.6.0 adds is a second, independent workstream: authorization surface removal. The two are largely disjoint and should be staffed and sequenced separately — the tenancy work is behavioural and needs staging soak time, the removal work is mechanical and can land earlier.

Applications that pass IDs rather than models into jobs, and that use the default bypass and a single-database org model, see the smallest delta. Anything with custom bypass logic, teams-without-tenancy, or UI-area routing sees the largest.

Migration path

  1. Pin exactly 1.6.0. Given the stated stance on minor-version removals, do not float a caret constraint across this package.
  2. Inventory references to every removed symbol: TeamResolver, DefaultTeamResolver, CallbackTeamResolver, SetPermissionsTeam, resolveTeamsUsing, BypassStrategy, RoleBypass, NoBypass, BypassGate, bypassUsing, resolveTenantUsing, tenantColumn, systemAbilities, currentTenant, tenantColumnName, UserPermissionMemo, forgetUserPermissions, CurrentArea, choose, clearChoice, TenantChoiceDropped, PermissionSync::plan, apply(prune: true). Include tests and config.
  3. Grep CI configs, Dockerfiles, composer.json scripts, deploy playbooks and scheduler definitions for authorization:sync, authorization:repair-ownership, make:authorization-policy. Rewrite the deploy step to run AuthorizationSeeder (or your own seeder) instead of deleting it outright.
  4. Re-express any custom bypass as application policy code, in one place, with a test that asserts the super-admin path and at least one negative path.
  5. Add non-tenancy team wiring if needed: own middleware calling setPermissionsTeamId().
  6. Define and centralize a replacement session key for the UI area.
  7. Drop enterable_scope, fallback_to_owned, areas from the published config.
  8. Re-run the v1.4.0 tenancy regression suite against 1.6.0: serialize under Tenant A, switch to Tenant B, assert ModelNotFoundException; plus soft-delete restore semantics.
  9. Benchmark permission-check hot paths before and after; add a memo at the application layer only if the numbers justify it.
  10. Treat the 1.4.0 queue workstream (strict mode in non-prod, scan for tenant-less dispatches, phase out model-carrying jobs) as a separate, parallel track.

Compatibility Semver-compatible tag, breaking in practice. No migrations, no dependency changes, no schema changes. All breaks are symbol removals and command removals in consumer code and consumer deployment tooling. No deprecation period was offered and none should be expected in future releases.

Sequencing

  • Phase 1 (days 1–2): Symbol and command inventory. Size both workstreams separately. Confirm we are inside the supported shape (single-DB orgs, default bypass, no non-tenancy teams).
  • Phase 2 (week 1): Land the removal work — bypass re-expression, teams middleware, session key, config cleanup, command rewiring in CI. This is low-risk and unblocks the pin.
  • Phase 3 (weeks 1–2): Benchmark permission checks; decide on an app-level memo. Re-run tenancy regression tests against 1.6.0.
  • Phase 4 (weeks 2–3): Execute the v1.4.0 queue workstream — strict mode in local/CI/staging, scan and fix tenant-less dispatch sites, coordinated worker restart at deploy.
  • Phase 5 (post-deploy): Monitor for MissingTenantContextException, ModelNotFoundException, unexpected authorization denials, and permission-query volume for one full business cycle including scheduled-job windows.

Operational Impact

Maintenance Maintenance cost rises even though the code surface shrinks. The remaining invariant from 1.4.0 still applies (do not dispatch tenant models outside tenant context) and still needs to live in review guidance or a static check. On top of that, we now carry a vendor-risk obligation: this package deletes public API in minors by design, for an audience of two internal consumers. Track upstream commits, not just tags, and budget a standing review each time a minor lands. Evaluate vendor/fork now — not because 1.6.0 is bad, but because the release notes state plainly that external consumers are not a design constraint. If forking, the fork point is 1.6.0 and it is small enough to be tractable.

Support Two new runbook entries on top of the tenancy ones. First, authorization anomalies: unexpected access denials after deploy most likely mean TenantScopedPolicy's tenancy.foreign_key comparison does not match a model's actual FK, or a custom bypass was not re-expressed. Second, deploy failures referencing deleted artisan commands — these should be caught in Phase 1, but the runbook should name them. The v1.4.0 runbook entries remain: MissingTenantContextException (fix the dispatch site) and ModelNotFoundException (check strict mode before treating as data loss). Support should also be told that permission drift after a failed seeder step is a possible follow-on symptom of a mis-rewired deploy command. Customer notification obligations for the v1.4.0 cross-tenant exposure remain open and unaffected by this release.

Scaling No change to hydration cost. The scaling item is new: dropping UserPermissionMemo means permission verdicts are recomputed per call. In a Livewire admin rendering hundreds of rows with per-row ability checks, that is a multiplicative query load against the roles/permissions tables. Benchmark the specific screens, and if a memo is reintroduced, keep it request-scoped and invalidated on role assignment — the package no longer does this for you. The queue-throughput guidance from 1.4.0 also stands: lower tries on high-volume queued classes during rollout so tenant-less dispatch failures surface fast.

Failure modes

  • Cross-tenant hydration (pre-1.4.0) — the original vulnerability; fixed as of 1.4.0 and expected to remain fixed. Verify at 1.6.0.
  • Tenant-less dispatch — MissingTenantContextException under strict, ModelNotFoundException otherwise. Unchanged from 1.4.0.
  • Broken deploy step — removed artisan commands still referenced in CI. Fails at deploy time; may leave permissions unsynced if the step is dropped rather than replaced.
  • Widened bypass — the fixed Gate::before never returns false; if it replaces a stricter local strategy, access is silently broader than before.
  • Policy FK mismatch — TenantScopedPolicy denies or mis-scopes because a model's foreign key does not match tenancy.foreign_key. Presents as an authorization bug, not a misconfiguration.
  • Session-area misrouting — CurrentArea::SESSION_KEY re-implemented inconsistently; users land on the wrong route after login or tenant switch.
  • Permission-query amplification — memo removal drives load on roles/permissions tables under per-row ability checks.
  • Future minor removes something else we use — the stated release philosophy makes this a live operational risk, not a tail case. Mitigation is exact pinning plus fork readiness.
  • Overly broad withoutTenant() — still the most likely next security bug; unchanged, and still worth a review rule.

Ramp-up Two bounded workstreams rather than one. The 1.6.0 removal work is roughly two to four engineer-days for a mid-size codebase: grep-driven, low ambiguity, mostly deletion and one bypass re-implementation. The 1.4.0 tenancy workstream remains about one engineer-week to scan, triage and fix dispatch sites with tests. Add a day for permission-check benchmarking. The durable output is the same as before — model-carrying jobs are a tenant boundary — plus a new one: this dependency's public API is not a contract, so upgrades are projects, not chores.

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