Weave Code
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

Sentinel Laravel Package

laravel/sentinel

Laravel Sentinel adds simple, lightweight tools for monitoring and reporting within Laravel apps. Built as a package you can drop in to capture key events, surface issues, and gain basic operational visibility without heavy setup or external services.

View on GitHub
Deep Wiki
Context7

Getting Started

Install via Composer:

composer require laravel/sentinel

Publish migrations and config:

php artisan vendor:publish --provider="Sentinel\SentinelServiceProvider" --tag="migrations"
php artisan vendor:publish --provider="Sentinel\SentinelServiceProvider" --tag="config"

Run migrations:

php artisan migrate

First Use Case: Authenticate a User

use Sentinel;

$user = Sentinel::authenticate(['email' => 'user@example.com', 'password' => 'password']);
if (Sentinel::check()) {
    // User is authenticated
    $user->roles; // Access roles
    $user->permissions; // Access permissions
}

First Use Case: Check User Permissions

if (Sentinel::getUser()->hasAccess(['edit-post', 'delete-comment'])) {
    // User has all required permissions
}

Implementation Patterns

Core Authentication Workflows

Login/Logout with Remember-Me

// Login with remember-me
Sentinel::authenticate(['email' => 'user@example.com'], false, true);

// Logout
Sentinel::logout();

Registration with Activation

$user = Sentinel::registerAndActivate([
    'email' => 'user@example.com',
    'password' => 'secure123',
    'first_name' => 'John',
    'last_name' => 'Doe',
    'activated' => true, // Skip email activation
]);

Password Reset

$credentials = ['email' => 'user@example.com'];
$attempts = Sentinel::attemptReset($credentials, 'new-password');
if ($attempts) {
    // Reset successful
}

Role-Based Access Control (RBAC)

Create and Assign Roles

$adminRole = Sentinel::createRole(['name' => 'admin']);
$user->roles()->attach($adminRole);

Check Role or Permission

if (Sentinel::getUser()->hasRole('admin')) {
    // Admin logic
}

if (Sentinel::getUser()->hasAccess('edit-post')) {
    // Permission granted
}

Bulk Role Assignment

$users = Sentinel::findWhere(['email' => ['like', '%@example.com']]);
$users->each->roles()->attach($adminRole);

Middleware and Route Integration

Custom Role Middleware

// app/Http/Middleware/CheckRole.php
public function handle($request, Closure $next, $role)
{
    if (!Sentinel::getUser()->hasRole($role)) {
        abort(403, 'Unauthorized action.');
    }
    return $next($request);
}

Register Middleware in app/Http/Kernel.php

protected $routeMiddleware = [
    'role' => \App\Http\Middleware\CheckRole::class,
];

Use in Routes

Route::get('/admin/dashboard', function () {
    return view('admin.dashboard');
})->middleware('role:admin');

Multi-Guard Configuration

Configure in config/auth.php

'guards' => [
    'web' => [
        'driver' => 'session',
        'provider' => 'sentinel',
    ],
    'api' => [
        'driver' => 'token',
        'provider' => 'sentinel',
    ],
],

Switch Guards Dynamically

Sentinel::switchToGuard('api');
$user = Sentinel::authenticate(['api_token' => 'abc123']);

Testing Patterns

Mock Authentication in Tests

public function test_admin_access()
{
    $admin = factory(\Sentinel\User::class)->create();
    $admin->roles()->attach(Sentinel::createRole(['name' => 'admin']));

    Sentinel::login($admin);

    $this->actingAs($admin, 'sentinel')
         ->get('/admin')
         ->assertOk();
}

Assert Permissions

$this->assertTrue(Sentinel::getUser()->hasAccess('edit-post'));
$this->assertFalse(Sentinel::getUser()->hasAccess('delete-all'));

Gotchas and Tips

Common Pitfalls

  1. Database Table Conflicts

    • Sentinel uses sentinel_users, sentinel_roles, and sentinel_permissions tables. If Laravel’s default users table exists, either:
      • Disable Laravel’s migrations for users table.
      • Use a separate database connection for Sentinel.
  2. Deprecated Laravel Features

    • Assumes older Laravel patterns (e.g., Hash::make()). Override in SentinelServiceProvider for Laravel 9+:
      use Illuminate\Support\Facades\Hash;
      $this->app->bind('hash', function () {
          return Hash::getDriver();
      });
      
  3. No Active Development

    • Last update: 2017. Monitor for security risks (none reported yet, but use at own risk). Avoid for new projects.
  4. Docker/Localhost Issues

    • Ensure Dockerfile mounts storage:
      VOLUME ["/var/www/html/storage"]
      
    • Clear cache after role/permission changes:
      php artisan sentinel:clear-cache
      
  5. Permission Caching

    • Permissions are cached by default. Clear cache manually if changes aren’t reflected:
      Sentinel::clearResolvedPermissions();
      

Debugging Tips

Auth Conflicts If Sentinel::user() and Auth::user() differ:

  • Override the guard in AuthServiceProvider:
    protected $guards = [
        'sentinel' => [
            'driver' => 'session',
            'provider' => 'sentinel',
        ],
    ];
    

Role/Permission Not Updating

  • Check for typos in role/permission names (case-sensitive).
  • Verify database changes with:
    dd(Sentinel::getUser()->roles->pluck('name'));
    

Throttling Issues

  • Customize throttling logic:
    Sentinel::throttling(function ($user) {
        return !$user->isAdmin(); // No throttling for admins
    });
    

Extension Points

  1. Custom User Model Extend Sentinel\User and rebind in SentinelServiceProvider:

    $this->app->bind('Sentinel.User', function () {
        return new \App\Models\CustomUser();
    });
    
  2. Event Listeners Listen to Sentinel events (e.g., activating, authenticated):

    // app/Providers/EventServiceProvider.php
    protected $listen = [
        'Sentinel.activating' => \App\Listeners\LogActivation::class,
        'Sentinel.authenticated' => \App\Listeners\SendWelcomeEmail::class,
    ];
    
  3. Multi-Tenant Support Override Sentinel::getUser() to scope by tenant:

    Sentinel::extend(function ($app) {
        $app['Sentinel'] = $app->share(function () {
            return new Sentinel\Sentinel(new TenantAwareUserProvider());
        });
    });
    
  4. Custom Permission Logic Extend permission checks:

    Sentinel::extendPermissionLogic(function ($user, $permission) {
        if ($permission === 'edit-post' && $user->isEditor()) {
            return true;
        }
        return false;
    });
    

Performance Tips

  • Eager Load Relationships:
    $user = Sentinel::findById(1)->withRoles()->withPermissions();
    
  • Batch Permission Checks:
    $admins = Sentinel::all()->filter(fn($user) => $user->hasRole('admin'));
    
  • Disable Debug Mode in production (config/sentinel.php):
    'debug' => env('APP_DEBUG', false),
    

Security Considerations

  1. Password Hashing

    • Ensure config/sentinel.php uses a secure hashing driver:
      'hash_driver' => 'bcrypt',
      
    • For Laravel 9+, override the hash driver binding as shown above.
  2. Session Security

    • Use sanctum or api guards for token-based auth to avoid session fixation:
      Sentinel::switchToGuard('api');
      
  3. Permission Hardcoding

    • Avoid hardcoding permissions in routes/middleware. Use a centralized config:
      config(['sentinel.permissions' => ['edit-post', 'delete-comment']]);
      

Migration Strategies

From Sentinel to Modern Auth (e.g., Breeze/Jetstream)

  1. Data Migration:
    • Export Sentinel users/roles/permissions to Laravel’s default tables:
      $users = Sentinel::all();
      foreach ($users as $user) {
          \App\Models\User::updateOrCreate(
              ['email' => $user->email],
              ['password' => bcrypt(str_random(10))]
          );
      }
      
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.
davejamesmiller/laravel-breadcrumbs
artisanry/parsedown
christhompsontldr/phpsdk
enqueue/dsn
bunny/bunny
enqueue/test
enqueue/null
enqueue/amqp-tools
bower-asset/punycode
bower-asset/inputmask
bower-asset/jquery
bower-asset/yii2-pjax
laravel/nova
spatie/laravel-mailcoach
spatie/laravel-superseeder
laravel/liferaft
nst/json-test-suite
danielmiessler/sec-lists
jackalope/jackalope-transport
twbs/bootstrap4