Skip to content

Authorization

Authorization is a server-side gate for deciding which fields and forms a user may use. Unauthorized fields are silently excluded before the form is sent to the frontend. They do not render, they do not appear in the data, and their validation rules are skipped.

Use authorization for permissions and sensitive fields. Use visibleWhen() for reactive UI behavior based on form data, and use Laravel's when() / unless() for build-time PHP chaining.

Authorization, Visibility, and Conditional Chaining

These helpers solve different problems:

php
TextInput::make('company')
    ->when($this->model instanceof Business, fn ($field) => $field->required());

when() and unless() run while PHP builds the form. They conditionally call fluent methods, but the field still exists unless your callback changes its authorization.

php
TextInput::make('vat_number')
    ->visibleWhen('is_business', true);

visibleWhen() and hiddenWhen() keep the field in the serialized form so the browser may show or hide it as form data changes. Hidden fields may be excluded when validated through Inertia Forms, but the frontend still knows the field exists.

php
TextInput::make('salary')
    ->authorizedWhen(fn () => auth()->user()->isAdmin());

authorizedWhen() and authorizedUnless() decide whether the field is sent to the frontend at all. Use them when the current user or request should not know about a field, submit it, or receive its validation rules.

Authorization runs first when authorization and visibility are both used on a field. Unauthorized fields are removed before any client-side visibility behavior applies.

Field-Level Authorization

authorizedWhen

Include a field only when a condition is true:

php
TextInput::make('salary')
    ->number()
    ->authorizedWhen(fn () => auth()->user()->isAdmin()),

Combobox::make('role')
    ->options(['user' => 'User', 'admin' => 'Admin'])
    ->authorizedWhen(fn () => auth()->user()->can('assignRoles')),

You may also pass a boolean directly:

php
TextInput::make('internal_notes')
    ->authorizedWhen(auth()->user()->isStaff()),

authorizedUnless

The inverse excludes a field when a condition is true:

php
TextInput::make('ssn')
    ->authorizedUnless(fn () => auth()->guest()),

Toggle::make('featured')
    ->authorizedUnless($isArchived),

authorize

The base method that both authorizedWhen and authorizedUnless use under the hood:

php
TextInput::make('admin_notes')
    ->authorize(fn () => auth()->user()->hasRole('admin')),

// Same as
TextInput::make('admin_notes')
    ->authorizedWhen(fn () => auth()->user()->hasRole('admin')),

What Happens to Unauthorized Fields

Unauthorized fields have three effects:

  1. Not serialized: The field is excluded from the toArray() output, so it is never sent to the frontend and never rendered
  2. No data: The field's value is excluded from data(), so it is not included in the form's initial data
  3. No validation: The field's rules are excluded from rules(), so it is not validated on submission

This means an unauthorized field is completely absent. The frontend never knows it exists.

php
class EditUserForm extends Form
{
    public function fields(): array
    {
        return [
            TextInput::make('name')->required(),
            TextInput::make('email')->email()->required(),

            // Only admins see and may edit the role
            Combobox::make('role')
                ->options(['user' => 'User', 'editor' => 'Editor', 'admin' => 'Admin'])
                ->authorizedWhen(fn () => auth()->user()->isAdmin()),
        ];
    }
}

// For a regular user:
$form = EditUserForm::make();
$form->data();   // ['name' => ..., 'email' => ...] without 'role'
$form->rules();  // ['name' => [...], 'email' => [...]] without 'role'

Form-Level Authorization

You may authorize the entire form by calling authorize() on the form instance:

php
$form = EditProjectForm::make()
    ->authorize(fn () => auth()->user()->can('update', $project));

Or use authorizedWhen() / authorizedUnless():

php
$form = DeleteAccountForm::make()
    ->authorizedWhen(fn () => auth()->user()->isOwner());

Unauthorized forms return an empty structure from toArray():

json
{
    "action": null,
    "method": "POST",
    "fieldsets": [],
    "data": {},
    "dataAttributes": null,
    "meta": null,
    "unsavedWarning": false,
    "wizard": null
}

And calling validate() throws an AuthorizationException.

Throwing Exceptions

By default, unauthorized forms return the empty structure silently. You may enable config exceptions instead:

php
// config/inertia-forms.php
'authorization' => [
    'throw_on_unauthorized' => true,
],

With this enabled, calling toArray() on an unauthorized form throws an Illuminate\Auth\Access\AuthorizationException. This setting applies to form-level serialization. Unauthorized fields are always filtered silently.