Saltar al contenido principal
Este artículo se basa en la investigación del código fuente (rama 1.x). Todavía no existe documentación oficial y es un paquete previo al lanzamiento (a fecha de abril de 2026).

¿Qué es Sentinel?

Laravel Sentinel es un paquete de middleware de seguridad que controla el acceso a las rutas mediante drivers. Está desarrollado por Taylor Otwell y Mior Muhammad Zaki, y es compatible con PHP ^8.0 / Laravel 8–13. Su uso principal es proteger rutas de herramientas de administración como Telescope, Horizon o Pulse. Basta con aplicar SentinelMiddleware a la ruta para controlar el acceso con la lógica de autorización definida por el driver.

Comparación con los métodos tradicionales

Telescope y Horizon disponían cada uno de mecanismos de autorización basados en gate.
// Método tradicional (TelescopeServiceProvider, etc.)
Gate::before(function ($user) {
    return $user->isAdmin() ? true : null;
});
Este método dependía del estado de autenticación del usuario, y tenía el problema de “no se puede juzgar si no se ha iniciado sesión”. Como Sentinel actúa como middleware, puede controlar el acceso por petición independientemente de si hay autenticación o no. Además, permite definir las reglas en un único lugar para múltiples herramientas de administración.

Instalación

composer require laravel/sentinel
Como en composer.json, dentro de extra.laravel.providers, está registrado el SentinelServiceProvider, el service provider se detecta automáticamente. No hace falta publicar archivos de configuración adicionales.

Arquitectura del paquete

Comportamiento del driver por defecto (driver Laravel)

El driver Laravel por defecto controla el acceso solo en el entorno local (APP_ENV=local).
// src/Drivers/Laravel.php
public function authorize(Request $request): bool
{
    if (! $this->app()->environment('local')) {
        return true; // fuera de local siempre permite
    }

    // Advierte sobre accesos vía servicios 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, ...'
        );
    }

    // Permite el entorno Docker local
    if ($this->isRunningOnDockerLocally($request)) {
        return true;
    }

    // Comprueba el acceso a través de reverse proxies
    return $this->authorizeAccessingViaReverseProxies($request);
}
Resumen del flujo:
El driver Laravel devuelve siempre true (permite) fuera del entorno local. Si necesitas control de acceso en producción, crea un driver personalizado.

Detección de IP privada

isPrivateIp() de la clase base Driver usa IpUtils de Symfony y considera privadas las siguientes rangos.
RangoDescripción
127.0.0.0/8Loopback (RFC1700)
10.0.0.0/8Privado (RFC1918)
192.168.0.0/16Privado (RFC1918)
172.16.0.0/12Privado (RFC1918)
169.254.0.0/16Link-local (RFC3927)
::1/128Loopback IPv6
fc00::/7Unique local IPv6
fe80::/10Link-local IPv6

Detección del entorno 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'));
}
Cuando REMOTE_ADDR es 127.0.0.1 y existe el archivo .dockerenv en la raíz del proyecto, se considera entorno Docker local.

Uso como middleware

Uso básico

use Laravel\Sentinel\Http\Middleware\SentinelMiddleware;

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

Especificar el driver

Puedes pasar el nombre del driver como argumento del middleware. Si pasas un nombre de driver que no existe, cae al driver por defecto (comportamiento de driverOrFallback()).
Route::middleware([SentinelMiddleware::class . ':custom-driver'])->group(function () {
    // Autoriza con el driver personalizado
});

Implementación del 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() devuelve false, se interrumpe con HTTP 401. Usando Driver::authorizeOrFail() también se puede lanzar AuthorizationException (el middleware en sí no lo usa).

Crear un driver personalizado

Puedes crear un driver personalizado heredando la clase abstracta Driver e implementando el método 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
        {
            // Solo permite usuarios autenticados con rol admin
            $user = $request->user();

            return $user !== null && $user->hasRole('admin');
        }
    };
});
El registro con extend() se hace en AppServiceProvider::boot(), por ejemplo.

Aprovechar los métodos utilitarios de la clase base

La clase Driver ofrece métodos útiles como la detección de IP, que se pueden usar libremente desde un driver personalizado.
public function authorize(Request $request): bool
{
    // En producción, permite solo desde IPs privadas
    if ($this->app()->environment('production')) {
        return $this->isPrivateIp($request->ip());
    }

    // En local, solo Docker o acceso directo
    return $this->isRunningOnDockerLocally($request)
        || $this->authorizeAccessingViaReverseProxies($request);
}

Cómo funciona SentinelManager

SentinelManager hereda de Illuminate\Support\Manager. Manager es la clase base de Laravel para implementar el patrón driver, que resuelve la instancia con driver() cacheándola.
// 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  // no registrar en log
        );
    }
}
driverOrFallback() cae silenciosamente al driver por defecto aunque no se encuentre el driver indicado, por lo que pasar al middleware un nombre de driver inexistente no produce error. SentinelManager se registra como singleton con scope (scoped) desde el SentinelServiceProvider, por lo que la instancia del driver se reutiliza dentro de una misma petición.
// src/SentinelServiceProvider.php
public function register(): void
{
    $this->app->scoped(SentinelManager::class, fn ($app) => new SentinelManager($app));
}

Conclusión

laravel/sentinel es un paquete pequeño, pero con alta extensibilidad gracias al patrón driver basado en Illuminate\Support\Manager.
ElementoContenido
Versión1.x
PHP compatible^8.0
Laravel compatible8–13
Driver por defectoSolo controla en entorno local
Driver personalizadoSe añade con Sentinel::extend()
El driver Laravel por defecto se especializa en prevenir accesos vía servicios de tunneling durante el desarrollo local, y para proteger producción hay que crear un driver personalizado propio. Cuando se publique la documentación oficial, se aclararán patrones de uso más concretos.

Repositorio laravel/sentinel

Puedes ver el código fuente y los cambios más recientes en la rama 1.x de GitHub.
Última modificación el 13 de julio de 2026