xlite-dev/filament-impersonate
Filament plugin to switch between accounts without signing out. Supports linked accounts, impersonation with a switch-back banner, and environment-gated developer logins, plus an audit trail and a fluent per-panel API. Formerly xlite-dev/filament-impersonate.
Architecture fit. This is a native Filament plugin (v4/v5) with a thin, well-shaped surface area: a HasLinkedAccounts trait on the User model, an AccountSwitcherPlugin registered per panel, a facade/service (AccountSwitcher), two domain events (AccountSwitching/AccountSwitched), and a single migration (account_switches). It slots into the panel's existing guard and route group rather than inventing its own auth stack — the 4.0.0 rewrite removed the lab404/laravel-impersonate dependency and moved the "leave" route to a CSRF-protected POST inside the authenticated panel group. For a TPM, that translates to low architectural intrusion and a clear blast radius: three feature toggles (impersonation(), linkedAccounts(), developerLogins()), one table, one trait, two events to hook.
Integration feasibility. Installation is a two-command Composer flow plus a published config and migration, and authorization is delegated to your model (canImpersonate() / canBeImpersonated()) with optional closure overrides (canImpersonateUsing, canSwitchUsing). That means policy stays in your codebase where security review can see it — a genuine plus versus packages that ship their own RBAC assumptions. Effort estimate for a competent Laravel dev: under a day to demo, two to three days to production-hardened (policies, audit export, runbook).
Technical risk. The dominant risk is not code quality — it's project continuity and trust signals:
xlite-dev/filament-impersonate → packstub/filament-account-switcher) in 4.0.0 with a namespace change and a removed Blade component. The old Packagist name is now frozen, which fragments the user base and explains the low dependent count. Any existing internal code referencing XliteDev\... will break.packstub.dev, security reports go to [email protected], and CI ("package health") is self-referential (Plumb). There is no foundation, no co-maintainers listed, and no external security audit — for a package whose entire purpose is privilege escalation inside an admin panel, that is a material governance gap you must accept explicitly rather than assume away.2026-10-15 (future-dated). Verify tag provenance, Packagist signature/metadata, and diff the dist archive before pinning. Treat this as a supply-chain check, not a nitpick.Missing required parameter [tenant] exception on tenant-aware panels. Three patch releases in quick succession on rendered UI and tenant routing is normal for a rewrite but argues for pinning above 4.0.4, never 4.0.0.Key questions to resolve before committing:
lab404/laravel-impersonate anywhere? Two impersonation mechanisms sharing session keys is a debugging nightmare.User, so extraction is non-trivial but bounded.AccountSwitched events land — and is a missed event an audit gap we can tolerate?Stack fit. Viable only on Filament 4/5 with Laravel 12/13 and PHP 8.2+. Anything older is a no-go rather than a workaround: the 3.x line is the pre-rename package and receives no forward investment. Confirm the matrix in CI before writing a single line of integration code.
Migration path. Treat this as a replacement decision, not an additive one. Enumerate what it displaces: password sharing with customers, screen-share debugging, bespoke "login as user" admin code, manual Auth::login() switches in tinker, and any lab404 usage. For each, write down the current workaround and the observable improvement — this becomes the pilot's success criteria. If we are already on xlite-dev/filament-impersonate, the upgrade is a breaking one (namespace, config filename packstub-account-switcher.php, removed guard/redirect_to/leave_middlewares keys, removed <x-filament-impersonate::banner />); budget a dedicated PR with a full grep for the old namespace rather than folding it into a feature branch.
Compatibility guardrails. Pin ~4.0.4 or later. Do not allow 4.0.0–4.0.3 anywhere, including lockfiles on long-lived branches. Confirm the Composer require constraints on filament/filament, laravel/framework, and php actually intersect our platform — the README table is a claim, composer.json is the contract. Check that the dist archive is lean (4.0.4 claims export-ignore hygiene) and that no composer.lock ships in it.
Sequencing (deliberately feature-by-feature, lowest risk first):
APP_ENV=production — test this, don't assume it.canImpersonate() to a single support role and canBeImpersonated() to exclude staff/admin accounts. Ship the persistent banner + switch-back as the default UX; do not customize the banner position until 4.0.2's layout fix is verified in our theme.AccountSwitched into our logging/SIEM, define retention and PII redaction, and only then consider logSwitches() non-negotiable. If the switch log is off, the feature is a compliance liability, not a control.Rollback. Because the trait is on User and the plugin is registered per panel, rollback is a config-level toggle plus a migration down — but only if we never let downstream code depend on HasLinkedAccounts methods (linkAccount, hasRole-adjacent authorization). Keep the integration behind a single registration point and avoid calling package APIs from our own domain code.
Maintenance. This is a pin-and-watch dependency, not a set-and-forget one. With one maintainer and near-zero dependents, we are effectively the QA function. Concretely: pin exact versions, subscribe to the GitHub releases feed, and maintain a fork mirror in our org (the package is MIT, so this is legally clean and the cheapest insurance available). Assign a named owner. Re-evaluate at each Filament major — the 4.0.0 rewrite exists precisely because the Filament 4/5 transition forced it, so expect the same at Filament 6.
Support. The package sits directly on the authentication path, so any defect is a P1 by default. Required runbook entries: how to end an impersonation when the banner is unreachable (switch-back is a CSRF-protected POST — a stale tab after a session rotation will fail), what happens when a session expires mid-impersonation, how a locked-out admin recovers, and how to confirm the audit row was written. Escalation path to the vendor is a single email address with no SLA — plan accordingly, and never let a customer-facing incident depend on it.
Scaling. Runtime cost is negligible — one session write plus one insert per switch. The scaling concern is the account_switches table: it is append-only, grows with every switch, and will accumulate IPs and user agents indefinitely. Plan index strategy (actor, target, created_at), partition or prune on a defined retention window, and confirm the write is non-blocking on the request path for your DB. Multi-tenant panels need a per-tenant scoping decision on that table — the schema is the vendor's, the data-governance model is ours.
Failure modes to instrument.
APP_ENV misconfiguration or a staging clone promoted to prod. Enforce a deploy-time assertion, not just the config gate.logSwitches() producing silent non-compliance. Assert on event delivery in monitoring./app/new paths remain the highest-churn area of the codebase; add smoke tests.Ramp-up. Engineering ramp is genuinely short — the docs are complete (installation, linked accounts, impersonation, developer logins, configuration, security), the README doubles as a runnable walkthrough, screenshots are current, and there is a Pest suite plus composer test. Budget roughly one engineer-day to a working spike and three to a hardened rollout. The real ramp-up cost is organizational: security review of the escalation model, legal sign-off on IP/UA retention, support-team training on the impersonation etiquette (never impersonate without a ticket reference — the reason field is only useful if policy enforces it), and a written decision record stating that we accepted a 46-star, single-maintainer dependency on our auth path, with the fork as our contingency. That decision record is the TPM's actual deliverable here.
How can I help you explore Laravel packages today?