rivalex/clearance
A drop-in Laravel admin panel for spatie/laravel-permission. Manage permissions, roles, guards and settings via Livewire 4 + Flux UI, with contextual authorization, parent-bounded ceiling roles, and optional super admin.
What we're actually buying. Clearance is not an authorization engine — it is an operator interface for spatie/laravel-permission, plus a thin extension layer for contextual (per-model-instance) grants, role ceilings, and a Super Admin. The TPM framing matters here: the panel is the commodity, the contextual-authorization semantics are the differentiated and riskier part. If we don't need per-Store / per-Tenant / per-Project role scoping, we are adopting a large surface area for a CRUD UI we could otherwise justify as "Spatie + a Filament page."
Architecture fit.
clr_role_ctx, clr_ctx_overrides, RoleMeta, guards), and exposes a HasClearance trait that is a superset of HasRoles. Opt-in modules and per-section Livewire components are the right shape for incremental adoption.auth.guards at boot. Runtime mutation of framework config is high-leverage and interacts badly with config:cache, Octane, and queue/console bootstrapping. This is the item I would demand a written design review on before production.canIn / resolveFor / ContextService) that coexists with Gate/Policies. Two mental models of "can this user do X" is a durable source of defects and a real onboarding tax. The super_admin_gate_bypass flag, defaulting to false, is correctly conservative — but it means even the package's own blessed path leaves us with parallel checks.Integration feasibility. Genuinely low-friction on paper: composer require, clearance:install, one trait swap, panel at /clearance. clearance:backfill exists specifically for brownfield Spatie installs, which is the honest signal that the author has thought about real adoption. Constraints are tight though: PHP 8.3, Laravel 12–13 only, Livewire 3|4, spatie/laravel-permission ^6, and livewire/flux ^2.14 — Flux has commercial tiers, so confirm which tier satisfies the components used before we treat this as free-and-MIT. The MIT license covers the package, not necessarily its UI dependency.
Technical risk (ranked).
2026-10-28 last-release date should be verified — future-dated or misrecorded release metadata is exactly the kind of thing that hides an unmaintained repo.clearance-* reserved namespace and installer-written marker file (storage/.clearance-installed) create implicit state that must be reconciled in every environment.migrate on a fresh setup fails. That's a documented trap in CI pipelines and ephemeral preview environments.super_admin_gate_bypass is an application-wide privilege escalation switch. It should be locked to false by policy, not by config review.Key questions for the maintainer / our own reviewers.
config:cache, Octane, and php artisan config:cache in CI? Is there a documented failure mode?resolveFor() per call, and is there a supported caching strategy for per-request authorization?clearance-* permissions across minor versions?Bottom line: viable as a fast path to a permissions admin UI if we actually need contextual scoping and accept vendor-fork risk. Not viable as an unexamined dependency in a security-sensitive product without a named internal owner.
Stack fit. Strong fit for a conventional Blade/Livewire Laravel app, or a Filament app (components mount as standalone Livewire children, so a custom Filament page can host role-manager and permission-manager without adopting the package's routes). Poor fit for Inertia/React/Vue frontends, where the panel becomes an island with its own layout and design language — and a second UI idiom to maintain.
Recommended posture: embed, don't route. Start with the package's own routes behind a restrictive middleware stack for a pilot cohort; only commit to embedding individual components once we know which sections we're actually delegating. This preserves the option to keep /clearance as a stopgap while we design our own surface later.
Migration path.
clearance:backfill as a staging-only operation first. Pre-audit for the alias collisions the installer prompts on — super_admin, superadmin, super-admin, root, owner. Promotion renames in place and preserves model_has_roles via FK, which is good, but it mutates live role names and every hardcoded hasRole('owner') in our codebase becomes a latent bug. Inventory those strings before running anything.clearance:install is the only supported entry point; wire CI and local bootstrap scripts to call it rather than migrate.use HasRoles with use HasClearance deliberately, in a single PR, and confirm no subclass of User or custom permission model exists (the docs flag custom model subclasses as a migration hazard).Compatibility gates to clear before committing. PHP 8.3 on all environments including CI and any legacy Docker images; Laravel 12/13 (rules out anything pinned to 11); Livewire 3 vs 4 consistency; Flux 2.14 tier and license procurement; spatie/laravel-permission ^6 already satisfied.
Sequencing.
canIn() in a loop.canIn().clearance-access + clearance-roles-write only. Hold the other *-write grants back.modules.users separately — per-user overrides are the highest-blast-radius feature (deny overrides beat global roles; surprises live there).false permanently unless a written exception is approved.clr_* tables and reverting the trait — rehearse it).Maintenance ownership. Assume we own this. With 0 dependents and a single maintainer, the realistic operating model is pin the version and vendor a fork in-house, applying upstream patches opportunistically. Budget a standing ~10–15% of one engineer during the first two quarters, tapering to patch-watch. The 370-test Pest suite is the single biggest mitigator — it means a fork is credible, because we can run their regression suite against our changes. Make "vendor + run upstream tests in CI" the default posture rather than an emergency plan.
Support. No community, no StackOverflow corpus, no issue-tracker velocity to read. Our on-call runbook must therefore cover: panel 500s, panel authorization regressions, and "user says they should have access." Each maps to a specific diagnostic (permission resolution trace, ceiling check, override precedence). Write that runbook during the pilot, not after.
Scaling.
canIn() is used in policies, Blade loops, or API middleware: contextual resolution merges contextual roles, global roles, and overrides, which is multiple queries per check. Profile resolveFor() under realistic permission counts (hundreds of permissions, tens of roles) and cache the effective set per user/context per request before this reaches a hot path.model_has_roles and the context tables grow with users × contexts. Watch index coverage on clr_role_ctx.Failure modes to pre-write detection for.
config:cache, or behaving differently in queue workers vs web. Smoke-test in both contexts.storage/.clearance-installed present but migrations incomplete (new environment restored from a partial dump). Prefer idempotent re-runs and a health check endpoint over trusting the marker.forced_off override silently negating a global role. Log every deny-with-override at debug level; make "why can't I" answerable in under five minutes.clearance-* permission introduced upstream conflicting with a locally created one. Pin and read the changelog before every bump.Ramp-up. Docs site exists and the README is above average for a 0-star package; 9 tested locales suggest intended international reach. But there is no production corpus to learn from and no second implementation to compare against. Estimate: ~1–2 days for a mid-level Laravel dev to be productive on the panel, plus ~1 day of focused security reading on the contextual resolution order (contextual → global → overrides, deny-wins). The super_admin and ceiling concepts are the parts most likely to be misunderstood and mis-granted; make them the explicit subject of a team walkthrough rather than assigned reading.
How can I help you explore Laravel packages today?