Skip to content

v1.0.0 — Initial Stable Release

Latest

Choose a tag to compare

@SignalByNick SignalByNick released this 19 Jul 15:50

🎭 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:

  • MasqueradeStarted
  • MasqueradeEnded
  • MasqueradeDenied
  • MasqueradeExpired
  • MasqueradeExtended

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>
@endmasquerading

Render the built-in banner:

@masqueradeBanner

Or include the publishable view manually:

@include('masquerade::banner')

🎨 Publishable Views

Publish the banner view:

php artisan vendor:publish --tag=masquerade-views

Published 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-config

Configuration 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:install

Install and run migrations:

php artisan masquerade:install --migrate

Prune old audit logs:

php artisan masquerade:prune --days=90 --force

Preview 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/masquerade

Install the package:

php artisan masquerade:install

Install 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.0

Publish the latest migrations:

php artisan vendor:publish --tag=masquerade-migrations

Run migrations:

php artisan migrate

Publish the latest configuration:

php artisan vendor:publish --tag=masquerade-config

Publish the optional banner view:

php artisan vendor:publish --tag=masquerade-views

Clear cached configuration and views:

php artisan optimize:clear

Review 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 test

Or 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.