Passer au contenu principal
Cet article s’appuie sur une analyse du code source (branche 1.x). Aucune documentation officielle n’existe encore et le package est en pré-release (à la date d’avril 2026).

Qu’est-ce que Sentinel ?

Laravel Sentinel est un package de middleware de sécurité qui contrôle l’accès aux routes via un pattern de drivers. Développé par Taylor Otwell et Mior Muhammad Zaki, il est compatible PHP ^8.0 et Laravel 8 à 13. Son usage principal est la protection des routes d’outils d’administration comme Telescope, Horizon ou Pulse. Il suffit d’appliquer SentinelMiddleware à une route pour contrôler l’accès selon la logique d’autorisation définie par le driver.

Comparaison avec l’approche classique

Telescope et Horizon disposent chacun d’un mécanisme d’autorisation basé sur des gate.
// Approche classique (TelescopeServiceProvider, etc.)
Gate::before(function ($user) {
    return $user->isAdmin() ? true : null;
});
Ce mécanisme dépend de l’état d’authentification et pose problème quand « on n’est pas connecté, donc on ne peut pas décider ». En tant que middleware, Sentinel contrôle l’accès par requête, indépendamment de l’authentification. Il permet aussi de définir les règles en un seul endroit pour plusieurs outils d’administration.

Installation

composer require laravel/sentinel
SentinelServiceProvider est déclaré dans extra.laravel.providers du composer.json, il est donc détecté automatiquement. Aucun fichier de configuration à publier.

Architecture du package

Fonctionnement du driver par défaut (driver Laravel)

Le driver par défaut Laravel ne contrôle l’accès qu’en environnement local (APP_ENV=local).
// src/Drivers/Laravel.php
public function authorize(Request $request): bool
{
    if (! $this->app()->environment('local')) {
        return true; // Toujours autorisé hors local
    }

    // Avertissement pour les accès via un service de tunneling
    if ($this->isPrivateIp($request->ip())
        && ! $request->isFromTrustedProxy()
        && Str::endsWith($request->host(), ['.sharedwithexpose.com', '.ngrok-free.app', '.ngrok.io'])) {
        throw new RuntimeException(
            'Unable to access "..." using "local" environment, ...'
        );
    }

    // Autorise l'environnement Docker local
    if ($this->isRunningOnDockerLocally($request)) {
        return true;
    }

    // Vérifie l'accès via reverse proxy
    return $this->authorizeAccessingViaReverseProxies($request);
}
Résumé du flux :
Le driver Laravel retourne toujours true (autorisé) en dehors de l’environnement local. Pour un contrôle d’accès en production, créez un driver personnalisé.

Détection d’IP privée

La méthode isPrivateIp() de la classe de base Driver utilise IpUtils de Symfony pour identifier les IP dans les plages suivantes comme privées.
PlageDescription
127.0.0.0/8Loopback (RFC1700)
10.0.0.0/8Privée (RFC1918)
192.168.0.0/16Privée (RFC1918)
172.16.0.0/12Privée (RFC1918)
169.254.0.0/16Link-local (RFC3927)
::1/128Loopback IPv6
fc00::/7Unique-local IPv6
fe80::/10Link-local IPv6

Détection d’environnement Docker local

// src/Drivers/Driver.php
protected function isRunningOnDockerLocally(Request $request): bool
{
    return $request->server->get('REMOTE_ADDR') === '127.0.0.1'
        && file_exists(base_path('.dockerenv'));
}
Considère l’environnement comme Docker local si REMOTE_ADDR vaut 127.0.0.1 et qu’un fichier .dockerenv existe à la racine du projet.

Utilisation comme middleware

Utilisation de base

use Laravel\Sentinel\Http\Middleware\SentinelMiddleware;

Route::middleware(SentinelMiddleware::class)->group(function () {
    Route::get('/telescope', function () { /* ... */ });
    Route::get('/horizon', function () { /* ... */ });
    Route::get('/pulse', function () { /* ... */ });
});

Spécifier un driver

Passez le nom du driver en argument du middleware. Si le driver n’existe pas, un fallback vers le driver par défaut est effectué (comportement de driverOrFallback()).
Route::middleware([SentinelMiddleware::class . ':custom-driver'])->group(function () {
    // Autorisation via le driver personnalisé
});

Implémentation du middleware

// src/Http/Middleware/SentinelMiddleware.php
public function handle(Request $request, Closure $next, ?string $driver = null)
{
    abort_unless(Sentinel::driverOrFallback($driver)->authorize($request), 401);

    return $next($request);
}
Si authorize() retourne false, la requête est interrompue avec un HTTP 401. Driver::authorizeOrFail() permet également de lever une AuthorizationException (non utilisée par le middleware lui-même).

Créer un driver personnalisé

Étendez la classe abstraite Driver et implémentez la méthode authorize().
use Laravel\Sentinel\Sentinel;
use Laravel\Sentinel\Drivers\Driver;
use Illuminate\Http\Request;

Sentinel::extend('admin-only', function ($app) {
    return new class extends Driver {
        public function authorize(Request $request): bool
        {
            // Autoriser uniquement les utilisateurs authentifiés avec le rôle admin
            $user = $request->user();

            return $user !== null && $user->hasRole('admin');
        }
    };
});
Enregistrez le driver dans AppServiceProvider::boot() ou équivalent.

Utiliser les méthodes utilitaires de la classe de base

La classe Driver propose des méthodes utiles (détection d’IP, etc.) réutilisables librement.
public function authorize(Request $request): bool
{
    // En production, autoriser uniquement les IP privées
    if ($this->app()->environment('production')) {
        return $this->isPrivateIp($request->ip());
    }

    // En local, uniquement Docker ou accès direct
    return $this->isRunningOnDockerLocally($request)
        || $this->authorizeAccessingViaReverseProxies($request);
}

Fonctionnement de SentinelManager

SentinelManager étend Illuminate\Support\Manager. Manager est la classe de base Laravel qui implémente le pattern de drivers en résolvant l’instance via driver() avec mise en cache.
// src/SentinelManager.php
class SentinelManager extends Manager
{
    protected function createLaravelDriver()
    {
        return new Laravel(fn () => $this->getContainer());
    }

    public function getDefaultDriver()
    {
        return 'laravel';
    }

    public function driverOrFallback(?string $driver)
    {
        return rescue(
            fn () => $this->driver($driver),
            value(fn () => $this->driver()),
            false  // Ne pas journaliser
        );
    }
}
driverOrFallback() retombe silencieusement sur le driver par défaut si le driver spécifié n’est pas trouvé, ce qui permet de passer sans erreur un nom de driver inexistant en argument du middleware. SentinelManager est enregistré en singleton scopé (scoped) par SentinelServiceProvider : l’instance du driver est réutilisée durant une requête.
// src/SentinelServiceProvider.php
public function register(): void
{
    $this->app->scoped(SentinelManager::class, fn ($app) => new SentinelManager($app));
}

Conclusion

laravel/sentinel est un petit package, mais son utilisation de Illuminate\Support\Manager lui confère une bonne extensibilité.
ÉlémentContenu
Version1.x
PHP pris en charge^8.0
Laravel pris en charge8 à 13
Driver par défautContrôle uniquement en environnement local
Driver personnaliséAjoutable via Sentinel::extend()
Le driver par défaut Laravel est spécialisé dans la prévention des accès via un service de tunneling en développement local ; pour protéger la production, il faut écrire un driver personnalisé. La documentation officielle, à venir, précisera les patrons d’utilisation.

Dépôt laravel/sentinel

Retrouvez le code source et les changements récents sur la branche 1.x du dépôt GitHub.
Dernière modification le 13 juillet 2026