Skip to content

Authorization

Every Lattice definition is Authorizable. Override authorize() to decide whether the current request may use it; it returns true by default, so a definition is open until you say otherwise.

use Illuminate\Http\Request;
public function authorize(Request $request): bool
{
return $request->user()?->can('update', $this->product($request)) ?? false;
}

The check runs on the definition’s own endpoint before any work happens:

  • An action or bulk action that fails authorize() never reaches handle().
  • A form is validated and handled only when authorized.
  • A table or fragment that fails resolves to nothing rather than leaking data.

Because the same definition class owns both the rendered component and the endpoint that backs it, the authorization lives in one place and can’t be bypassed by calling the endpoint directly.

A definition often needs the record it acts on. Pass it as context when placing the component, and read it back with context():

Action::use(ArchiveProductAction::class)->context(['product_id' => $row['id']]);
// inside the action:
protected function product(Request $request): Product
{
return Product::query()->findOrFail($this->context($request, 'product_id'));
}

The context is sealed into the component’s signed reference, so the value authorize() and handle() read is the value the server issued — not something a client can change. See Security for how that sealing works.