🎭 Laravel Masquerade v1.0.0 🎉
The first stable release of Laravel Masquerade.
Laravel Masquerade provides secure user impersonation for Laravel applications, allowing trusted administrators, support agents, and internal staff to temporarily act as another user while preserving the original user session, enforcing authorization checks, limiting impersonation duration, blocking sensitive actions, and recording detailed audit history.
This release focuses on safe impersonation workflows, auditability, session protection, developer-friendly customization, and a clean Laravel package experience.
✨ Features
- Secure session-backed user impersonation
- Original user restoration after masquerade sessions
- Configurable authentication guard support
- Configurable user model support
- Optional built-in routes
- Controller-driven start and stop flows
- Model-level permission methods
- Protection against nested impersonation
- Protection against impersonating yourself
- Optional required reason before starting a session
- Session ID regeneration when starting and stopping
- Configurable maximum masquerade duration
- Automatic session expiration handling
- Sensitive-route blocking middleware
- Middleware for routes requiring an active masquerade session
- Request context middleware for masquerade-aware applications
- Full audit logging with impersonator and target morph relationships
- Reason, IP address, user agent, metadata, start time, and end time logging
- Denied-attempt audit logging
- Runtime metadata updates
- Session extension support
- Remaining and elapsed time helpers
- Identity helper methods for impersonator and target checks
- Typed masquerade session data object
- Start, stop, denied, expired, and extended lifecycle events
- Blade conditional directive
- Blade banner directive
- Publishable banner view
- Facade support
- Global helper support
- Install command
- Audit-log pruning command
- Configurable routes, redirects, messages, table names, and middleware behavior
- Laravel Pint, PHPStan/Larastan, PHPUnit, Testbench, and GitHub Actions setup
- Expanded PHPUnit coverage
- Full documentation with icon-led headings
🎭 Masquerading
Start a masquerade session:
use EloquentWorks\Masquerade\Facades\Masquerade;
Masquerade::start(
target: $user,
impersonator: $admin,
reason: 'Helping user troubleshoot account issue.',
metadata: [
'ticket_id' => 'SUP-1042',
],
);Stop the active masquerade session:
Masquerade::stop();Check whether the current request is masquerading:
Masquerade::isMasquerading();Read the current impersonator and target:
$impersonator = Masquerade::impersonator();
$target = Masquerade::target();🔐 Permissions
Laravel Masquerade supports model-level authorization methods.
Add the HasMasquerade trait to your user model:
<?php
namespace App\Models;
use EloquentWorks\Masquerade\Traits\HasMasquerade;
use Illuminate\Contracts\Auth\Authenticatable;
use Illuminate\Foundation\Auth\User as AuthenticatableUser;
class User extends AuthenticatableUser
{
use HasMasquerade;
public function canMasquerade(Authenticatable $target): bool
{
return $this->is_admin && ! $this->is($target);
}
public function canBeMasqueradedBy(Authenticatable $impersonator): bool
{
return ! $this->is_owner;
}
}The package can prevent:
- Non-authorized users from starting masquerade sessions
- Users from masquerading as themselves
- Nested masquerade sessions
- Masquerading into protected users
- Masquerading without a required reason
🧠 Session Context
Laravel Masquerade stores active masquerade state in the session.
The session tracks:
- Masquerade UUID
- Original impersonator ID
- Original impersonator model type
- Target user ID
- Target user model type
- Authentication guard
- Reason
- Metadata
- Start time
- Expiration time
Example:
$session = Masquerade::session();
$session?->uuid;
$session?->reason;
$session?->metadata;Applications can also update session metadata at runtime:
Masquerade::updateMetadata([
'ticket_status' => 'waiting-on-customer',
]);Metadata may be merged or replaced depending on application needs.
⏱️ Duration Limits
Masquerade sessions can be limited by duration.
Example configuration:
'duration' => [
'enabled' => true,
'max_minutes' => 60,
],Check time information:
Masquerade::elapsedMinutes();
Masquerade::remainingMinutes();Extend a session when allowed:
Masquerade::extend(
minutes: 15,
reason: 'Support call is still active.',
);Laravel Masquerade can cap extensions so sessions cannot exceed the configured maximum duration.
🧩 Middleware
Laravel Masquerade includes middleware for common protection flows.
Block sensitive routes while masquerading:
Route::middleware(['auth', 'masquerade.block'])->group(function (): void {
Route::get('/billing', BillingController::class);
Route::post('/password', UpdatePasswordController::class);
});Expire masquerade sessions automatically:
Route::middleware(['auth', 'masquerade.duration'])->group(function (): void {
Route::get('/dashboard', DashboardController::class);
});Require an active masquerade session:
Route::middleware(['auth', 'masquerade.required'])->group(function (): void {
Route::get('/support/masquerade/tools', SupportToolsController::class);
});Attach masquerade context to requests:
Route::middleware(['auth', 'masquerade.context'])->group(function (): void {
Route::get('/dashboard', DashboardController::class);
});🛡️ Sensitive Route Protection
Some actions should usually be blocked while masquerading.
Recommended blocked areas include:
- Password changes
- Email address changes
- Two-factor authentication settings
- Billing and payment methods
- API token management
- Connected accounts
- Account deletion
- Destructive admin actions
- Security settings
Example:
Route::middleware(['auth', 'masquerade.block'])
->group(function (): void {
Route::get('/settings/security', SecurityController::class);
Route::get('/billing', BillingController::class);
});📜 Audit Logging
Laravel Masquerade includes a dedicated audit log model and migration.
Logs may include:
- Masquerade UUID
- Action
- Authentication guard
- Impersonator model
- Target model
- Reason
- IP address
- User agent
- Metadata
- Started timestamp
- Ended timestamp
Example:
use EloquentWorks\Masquerade\Models\MasqueradeLog;
$logs = MasqueradeLog::query()
->latest()
->get();🔎 Audit Log Scopes
Laravel Masquerade includes query scopes for common audit lookups.
MasqueradeLog::query()->started()->get();
MasqueradeLog::query()->ended()->get();
MasqueradeLog::query()->denied()->get();
MasqueradeLog::query()->expired()->get();
MasqueradeLog::query()->extended()->get();Filter by masquerade UUID:
MasqueradeLog::query()
->forMasqueradeUuid($uuid)
->get();Filter by impersonator:
MasqueradeLog::query()
->forImpersonator($admin)
->get();Filter by target:
MasqueradeLog::query()
->forTarget($user)
->get();📣 Events
Laravel Masquerade dispatches lifecycle events for integration with your application.
Bundled events include:
MasqueradeStartedMasqueradeEndedMasqueradeDeniedMasqueradeExpiredMasqueradeExtended
Example listener use cases:
- Notify security teams
- Write external audit records
- Track support activity
- Send internal alerts
- Update observability dashboards
- Record ticket metadata
🧭 Built-In Routes
Laravel Masquerade can register optional built-in routes.
Example usage:
Route::post('/masquerade/{user}', StartMasqueradeController::class)
->middleware(['auth']);
Route::delete('/masquerade', StopMasqueradeController::class)
->middleware(['auth']);Built-in routes support configurable redirects and safer redirect handling.
🖼️ Blade Directives
Use the Blade conditional directive:
@masquerading
<p>You are currently masquerading as another user.</p>
@endmasqueradingRender the built-in banner:
@masqueradeBannerOr include the publishable view manually:
@include('masquerade::banner')🎨 Publishable Views
Publish the banner view:
php artisan vendor:publish --tag=masquerade-viewsPublished views are placed in:
resources/views/vendor/masquerade/banner.blade.php
Applications can customize:
- Banner text
- Button styling
- Stop masquerade form
- Warning language
- Layout placement
- Icons and colors
⚙️ Configuration
Publish the configuration file:
php artisan vendor:publish --tag=masquerade-configConfiguration supports:
- Auth guard
- User model
- Route registration
- Route middleware
- Redirect targets
- Required reasons
- Maximum duration
- Audit logging
- Table names
- Session keys
- Messages
- View behavior
Example:
'guard' => 'web',
'require_reason' => true,
'duration' => [
'enabled' => true,
'max_minutes' => 60,
],
'logging' => [
'enabled' => true,
'table_name' => 'masquerade_logs',
],🗃️ Database Changes
Laravel Masquerade v1.0.0 includes a migration for audit logging.
The default table is:
masquerade_logs
The table stores:
id
masquerade_uuid
action
guard
impersonator_type
impersonator_id
target_type
target_id
reason
ip_address
user_agent
metadata
started_at
ended_at
created_at
updated_at
The table name is configurable:
'logging' => [
'table_name' => 'masquerade_logs',
],🧰 Commands
Laravel Masquerade includes installation and maintenance commands.
Install the package:
php artisan masquerade:installInstall and run migrations:
php artisan masquerade:install --migratePrune old audit logs:
php artisan masquerade:prune --days=90 --forcePreview pruning without deleting records:
php artisan masquerade:prune --days=90 --dry-run🧪 PHPUnit Coverage
Laravel Masquerade includes PHPUnit coverage for:
- Starting masquerade sessions
- Stopping masquerade sessions
- Restoring the original user
- Preventing self-masquerading
- Preventing nested masquerade sessions
- Required reason enforcement
- Model-level permission checks
- Disabling model permission checks
- Denied-attempt audit logging
- Session context creation
- Session metadata updates
- Metadata merge behavior
- Metadata replacement behavior
- Session extension
- Maximum duration caps
- Remaining time helpers
- Elapsed time helpers
- Event dispatching
- Duration expiration
- Sensitive route blocking
- Masquerade-required middleware
- Request context middleware
- Safe redirect handling
- Audit log scopes
- Log duration helpers
- Prune command dry-run behavior
- Prune command forced deletion
📚 Documentation
The documentation includes icon-led guides for:
- Installation
- Configuration
- Architecture
- Masquerading
- Permissions
- Routes
- Middleware
- Audit logs
- Views and Blade
- Events
- Commands and scheduling
- Advanced features
- Customization
- Security
- Testing
- Release guidance
- Upgrade guidance
- Contribution guidance
✅ Supported Versions
- Laravel 11.15+ with PHP 8.2+
- Laravel 12 with PHP 8.2+
- Laravel 13 with PHP 8.3+
🚀 Installation
Install Laravel Masquerade through Composer:
composer require eloquent-works/masqueradeInstall the package:
php artisan masquerade:installInstall and run migrations:
php artisan masquerade:install --migrate⬆️ Upgrading
Laravel Masquerade v1.0.0 is the first stable release.
No upgrade steps are required when installing v1.0.0 into a new application.
If upgrading from a pre-release version, update the package:
composer require eloquent-works/masquerade:^1.0Publish the latest migrations:
php artisan vendor:publish --tag=masquerade-migrationsRun migrations:
php artisan migratePublish the latest configuration:
php artisan vendor:publish --tag=masquerade-configPublish the optional banner view:
php artisan vendor:publish --tag=masquerade-viewsClear cached configuration and views:
php artisan optimize:clearReview the new configuration options:
'require_reason' => true,
'duration' => [
'enabled' => true,
'max_minutes' => 60,
],
'logging' => [
'enabled' => true,
'table_name' => 'masquerade_logs',
],🧰 Quality Checks
Before deploying, run:
composer validate --strict
composer format
composer analyse
composer testOr run the complete quality suite:
composer quality🔐 Security
Only highly trusted users should be allowed to masquerade.
Recommended security practices:
- Require strong authorization before starting a session
- Require a reason for every session
- Keep duration limits enabled
- Regenerate sessions when starting and stopping
- Block sensitive routes while masquerading
- Log every start, stop, denial, expiration, and extension
- Review audit logs regularly
- Avoid allowing support staff to change authentication, billing, or security settings while masquerading
Security vulnerabilities should be reported privately according to SECURITY.md.
❤️ Thank You
Thank you for using Laravel Masquerade.
Feedback, bug reports, feature requests, documentation improvements, and pull requests are always welcome.