메인 콘텐츠로 건너뛰기
이 글은 소스 코드 조사(1.x 브랜치)에 기반한 정보입니다. 공식 문서는 아직 존재하지 않으며, 정식 릴리스 전의 패키지입니다 (2026년 4월 시점).

Sentinel이란

Laravel Sentinel은 라우트로의 접근을 드라이버 기반으로 제어하는 보안 미들웨어 패키지입니다. Taylor Otwell과 Mior Muhammad Zaki에 의해 개발되었으며, PHP ^8.0 / Laravel 8~13에 대응하고 있습니다. 주요 용도는 Telescope · Horizon · Pulse 같은 관리 도구 계열 라우트의 보호입니다. SentinelMiddleware를 라우트에 적용하는 것만으로, 드라이버가 정의한 인가 로직으로 접근을 제어할 수 있습니다.

기존 방법과의 비교

Telescope나 Horizon에는 각각 gate를 사용한 인가 구조가 준비되어 있었습니다.
// 기존 방법 (TelescopeServiceProvider 등)
Gate::before(function ($user) {
    return $user->isAdmin() ? true : null;
});
이 방식은 사용자의 인증 상태에 의존하고 있어, “로그인하지 않으면 판정할 수 없다”는 문제가 있었습니다. Sentinel은 미들웨어로 동작하므로, 인증의 유무와 관계없이 요청 단위로 접근을 제어할 수 있습니다. 또한 여러 관리 도구에 대해 한 곳에서 룰을 정의할 수 있습니다.

설치

composer require laravel/sentinel
composer.jsonextra.laravel.providersSentinelServiceProvider가 등록되어 있으므로, 서비스 프로바이더는 자동 감지됩니다. 추가 설정 파일 공개는 불필요합니다.

패키지의 아키텍처

기본 드라이버 (Laravel 드라이버)의 동작

기본 Laravel 드라이버는 로컬 환경(APP_ENV=local)에서만 제어를 수행합니다.
// src/Drivers/Laravel.php
public function authorize(Request $request): bool
{
    if (! $this->app()->environment('local')) {
        return true; // local 이외에는 항상 허가
    }

    // 터널링 서비스 경유의 접근에 경고
    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, ...'
        );
    }

    // Docker 로컬 환경은 허가
    if ($this->isRunningOnDockerLocally($request)) {
        return true;
    }

    // 리버스 프록시 경유의 접근을 확인
    return $this->authorizeAccessingViaReverseProxies($request);
}
흐름을 정리하면 다음과 같습니다.
Laravel 드라이버는 local 환경 이외에서는 항상 true(허가)를 반환합니다. 프로덕션 환경에서의 접근 제어가 필요한 경우에는 커스텀 드라이버를 작성해 주세요.

프라이빗 IP의 판정

Driver 기저 클래스의 isPrivateIp()는 Symfony의 IpUtils를 사용하여, 이하의 IP 범위를 프라이빗 IP로 판정합니다.
범위설명
127.0.0.0/8루프백 (RFC1700)
10.0.0.0/8프라이빗 (RFC1918)
192.168.0.0/16프라이빗 (RFC1918)
172.16.0.0/12프라이빗 (RFC1918)
169.254.0.0/16링크 로컬 (RFC3927)
::1/128IPv6 루프백
fc00::/7IPv6 유니크 로컬
fe80::/10IPv6 링크 로컬

Docker 로컬 환경 검출

// 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'));
}
REMOTE_ADDR127.0.0.1이고, 프로젝트 루트에 .dockerenv 파일이 존재하는 경우를 Docker 로컬 환경으로 판정합니다.

미들웨어로서 사용하기

기본 사용법

use Laravel\Sentinel\Http\Middleware\SentinelMiddleware;

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

드라이버 지정

미들웨어의 인자로 드라이버 이름을 전달할 수 있습니다. 존재하지 않는 드라이버 이름을 전달한 경우에는 기본 드라이버로 폴백합니다 (driverOrFallback()의 동작).
Route::middleware([SentinelMiddleware::class . ':custom-driver'])->group(function () {
    // 커스텀 드라이버로 인가
});

미들웨어의 구현

// 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);
}
authorize()false를 반환하면 HTTP 401로 중단합니다. Driver::authorizeOrFail()을 사용하면 AuthorizationException을 던질 수도 있습니다 (미들웨어 자체는 이것을 사용하지 않습니다).

커스텀 드라이버 작성

Driver 추상 클래스를 상속하여 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
        {
            // 인증되어 있고 admin 롤을 가진 사용자만 허가
            $user = $request->user();

            return $user !== null && $user->hasRole('admin');
        }
    };
});
extend()의 등록은 AppServiceProvider::boot() 등에서 수행합니다.

기저 클래스의 유틸리티 메서드 활용

Driver 클래스에는 IP 판정 등의 편리한 메서드가 준비되어 있으며, 커스텀 드라이버에서 자유롭게 이용할 수 있습니다.
public function authorize(Request $request): bool
{
    // 프로덕션 환경에서는 프라이빗 IP에서만 허가
    if ($this->app()->environment('production')) {
        return $this->isPrivateIp($request->ip());
    }

    // 로컬에서는 Docker나 직접 접근만
    return $this->isRunningOnDockerLocally($request)
        || $this->authorizeAccessingViaReverseProxies($request);
}

SentinelManager의 구조

SentinelManagerIlluminate\Support\Manager를 상속하고 있습니다. Manager는 드라이버 패턴을 구현하기 위한 Laravel의 기반 클래스로, driver()로 드라이버 인스턴스를 캐시하면서 해결합니다.
// 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  // 로그에 기록하지 않음
        );
    }
}
driverOrFallback()은 지정한 드라이버가 발견되지 않는 경우에도 기본 드라이버로 조용히 폴백하므로, 미들웨어 인자에 존재하지 않는 드라이버 이름을 전달해도 오류가 나지 않습니다. SentinelManagerSentinelServiceProvider에 의해 스코프 부여 싱글톤(scoped)으로 등록되므로, 1요청 내에서 드라이버의 인스턴스가 재이용됩니다.
// src/SentinelServiceProvider.php
public function register(): void
{
    $this->app->scoped(SentinelManager::class, fn ($app) => new SentinelManager($app));
}

정리

laravel/sentinel은 작은 패키지이지만, Illuminate\Support\Manager를 사용한 드라이버 패턴에 의해 높은 확장성을 가집니다.
항목내용
버전1.x
대응 PHP^8.0
대응 Laravel8~13
기본 드라이버local 환경만 제어
커스텀 드라이버Sentinel::extend()로 추가 가능
기본 Laravel 드라이버는 로컬 개발 시 터널링 서비스 경유의 접근을 방지하는 것에 특화되어 있으며, 프로덕션 환경의 보호에는 자체 커스텀 드라이버를 작성해야 합니다. 공식 문서가 정비되면 보다 구체적인 이용 패턴이 명확해질 것입니다.

laravel/sentinel 리포지토리

소스 코드와 최신 변경은 GitHub의 1.x 브랜치에서 확인할 수 있습니다.
마지막 수정일 2026년 7월 13일