# Authorization & security

> Control which records and fields a table can expose.

Source: https://docs.inertiax.dev/table/guide/security/

Your application authorizes access to records and actions. InertiaX applies table controls to the source you supply; it does not call your policies or add tenant scopes.

## Authorize and scope the query

Authorize the page and constrain its query before passing it to `data()`. For an application with an account-scoped users page and a `UserPolicy::viewAny` policy:

```php
use App\Models\User;
use App\Tables\UsersTable;
use Illuminate\Support\Facades\Gate;
use Inertia\Inertia;

Gate::authorize('viewAny', User::class);

$users = User::query()->where('account_id', $request->user()->account_id);

return Inertia::render('users/index', [
    UsersTable::make('users')->data($users),
]);
```

A `viewAny` check does not filter individual records. The query must enforce the application’s tenant, ownership, or other record-level access rules on every request, including partial reloads.

Passing `User::class` creates `User::query()` with its global scopes. It does not infer a scope from the authenticated user. Collections and arrays must already contain only permitted records.

## Choose fields deliberately

Treat every column value, cell metadata field, filter option, and definition sent to React as readable by the user. Explicit columns are a useful way to review the fields a table exposes. Model `$hidden` settings are not a substitute for reviewing explicitly declared columns and custom transformers, which can read model attributes directly.

Automatic columns send every field the model serializes: its columns and `$appends`, except `$hidden` ones, or only the `$visible` ones. The row key is always sent. Unless `$visible` or an explicit `select()` lists the fields, a column that a later migration adds appears automatically. Before enabling `autoColumns()`, check that `$hidden` covers every sensitive column and appended value. See [Automatic columns](https://docs.inertiax.dev/table/reference/column/#automatic-columns).

## Visibility is presentation

`visible(false)` hides a column in the UI. Its data still reaches the browser. `toggleable(false)` only removes the user’s visibility control. Omit sensitive columns entirely and avoid putting sensitive values into custom metadata or filter options.

## Validate actions independently

Selection contains row IDs in the browser. If you use it for an application action, validate the submitted IDs and authorize the action on each record at the receiving endpoint. Selection state, hidden controls, and disabled buttons do not grant permission.

## Custom query behavior

InertiaX validates requested search, filters, sorting, and pagination against the table definition. Custom callbacks still own their query behavior: keep the supplied scope intact, bind user values through the query builder, and validate custom clause values. Do not replace a scoped source with an unrestricted query inside a callback.
