Skip to content
Laravel Warrant is in beta and still being tested — expect API changes between releases. Report an issue.

Middleware API

Reference for Warrant\Middleware\WarrantMiddleware. Conceptual coverage is in Route middleware.

The $target throughout is either a schema key (no-model check) or a route parameter name bound to a model (targeted check).

public static function string(
string $target,
string|array $abilities,
AbilityMatchMode $matchMode = AbilityMatchMode::ALL,
): string;

Produces a warrant:... middleware string, e.g. warrant:documents,view. The match-mode segment (any / all) is inserted only when $matchMode isn’t the default ALL:

WarrantMiddleware::string('document', 'view');
// -> "warrant:document,view"
WarrantMiddleware::string('document', ['view', 'approve'], AbilityMatchMode::ANY);
// -> "warrant:document,any,view,approve"
public static function guard(
string $target,
string|array $abilities,
Closure $routes,
AbilityMatchMode $matchMode = AbilityMatchMode::ALL,
): void;
WarrantMiddleware::guard('documents', 'view', function () {
Route::get('/documents', [DocumentController::class, 'index']);
});

Each takes the target and an optional route-group closure. With a closure they guard the group; without one they return the middleware string.

public static function canView(string $target, ?Closure $routes = null): ?string;
public static function canCreate(string $target, ?Closure $routes = null): ?string;
public static function canUpdate(string $target, ?Closure $routes = null): ?string;
public static function canDelete(string $target, ?Closure $routes = null): ?string;
public static function canArchive(string $target, ?Closure $routes = null): ?string;

canView…canArchive map to the matching StandardAbilities constant.

Guards backed by the reachability system — a purely structural check that runs no conditions and no SQL. Each returns the middleware string when called without a $routes closure, or guards the group when given one.

public static function couldEver(
string $target,
string|array $abilities,
?Closure $routes = null,
AbilityMatchMode $matchMode = AbilityMatchMode::ALL,
): ?string; // passes when reachability !== NEVER
public static function always(
string $target,
string|array $abilities,
?Closure $routes = null,
AbilityMatchMode $matchMode = AbilityMatchMode::ALL,
): ?string; // passes when reachability === ALWAYS
public static function never(
string $target,
string|array $abilities,
?Closure $routes = null,
AbilityMatchMode $matchMode = AbilityMatchMode::ALL,
): ?string; // passes when reachability === NEVER

The aliases are warrant.could-ever, warrant.always, and warrant.never, each with an .any variant for AbilityMatchMode::ANY (e.g. warrant.could-ever.any).

These guards are target-free: $target is a schema key or a schema/model class, never a route parameter. The schema is resolved by key only (it throws if the target isn’t a key), and the middleware abort(403)s when the reachability predicate fails. See Reachability.

public function handle(
Request $request,
Closure $next,
string $target,
string $matchModeOrFirstAbility,
string ...$remainingAbilities,
): Response;

At request time it:

  1. Resolves $target as a schema key first.
  2. Failing that, treats it as a route parameter name, resolves it to a model instance, and finds the schema from the model’s class.
  3. Reads the segment after the target: all / any is the match mode; anything else is the first ability.
  4. Calls authorize, which throws WarrantAuthorizationException (rendered as 403, carrying the responsible rule’s denial message) if unauthenticated or unauthorized.
Condition Exception
No abilities supplied (warrant:) InvalidArgumentException — “Access control middleware requires at least one ability.”
No abilities supplied (reachability guards) InvalidArgumentException — “Warrant reachability middleware requires at least one ability.”
Route parameter isn’t a model instance InvalidArgumentException — “must resolve to a model instance.”
Target resolves to no schema (warrant:) InvalidArgumentException — “Unable to resolve access control schema for […]”
Target isn’t a schema key (reachability guards) InvalidArgumentException — “Unable to resolve Warrant schema for […]; reachability guards take a schema key.”
Unauthenticated / unauthorized WarrantAuthorizationException (HTTP 403)