# `Ash.Authorizer`
[🔗](https://github.com/ash-project/ash/blob/v3.27.4/lib/ash/authorizer.ex#L5)

The interface for an ash authorizer

These will typically be implemented by an extension, but a custom
one can be implemented by defining an extension that also adopts this behaviour.

Then you can extend a resource with `authorizers: [YourAuthorizer]`

# `context`

```elixir
@type context() :: map()
```

# `state`

```elixir
@type state() :: map()
```

# `add_calculations`
*optional* 

```elixir
@callback add_calculations(Ash.Query.t() | Ash.Changeset.t(), state(), context()) ::
  {:ok, Ash.Query.t() | Ash.Changeset.t(), state()} | {:error, Ash.Error.t()}
```

# `alter_filter`
*optional* 

```elixir
@callback alter_filter(filter :: Ash.Filter.t(), state(), context()) ::
  {:ok, Ash.Filter.t()} | {:error, Ash.Error.t()}
```

# `alter_results`
*optional* 

```elixir
@callback alter_results(state(), [Ash.Resource.Record.t()], context()) ::
  {:ok, [Ash.Resource.Record.t()]} | {:error, Ash.Error.t()}
```

# `apply_field_level_auth`
*optional* 

```elixir
@callback apply_field_level_auth(
  resource :: Ash.Resource.t(),
  records :: [Ash.Resource.Record.t()],
  opts :: Keyword.t()
) :: {:ok, [Ash.Resource.Record.t()]} | {:error, Ash.Error.t()}
```

Apply field-level authorization to a list of records that already have
values populated in memory, without re-fetching them through a read.

Implementations should walk each record and substitute `%Ash.ForbiddenField{}`
for any field the actor isn't allowed to see (typically via field policies).

This is the lightweight counterpart to `add_calculations/3` + the read
pipeline's field-policy scrubbing — used when you have records in hand and
just need to enforce field-level visibility without running a load.

# `check`

```elixir
@callback check(state(), context()) ::
  :authorized
  | {:data, [Ash.Resource.Record.t()]}
  | {:error, :forbidden, state()}
  | {:error, Ash.Error.t()}
```

# `check_context`

```elixir
@callback check_context(state()) :: [atom()]
```

# `exception`
*optional* 

```elixir
@callback exception(atom(), state()) :: Exception.t()
```

# `initial_state`

```elixir
@callback initial_state(
  Ash.Resource.t(),
  Ash.Resource.Record.t(),
  Ash.Resource.Actions.action(),
  Ash.Domain.t()
) :: state()
```

# `strict_check`

```elixir
@callback strict_check(state(), context()) ::
  {:authorized, state()}
  | {:continue, state()}
  | {:filter, Keyword.t()}
  | {:filter, Keyword.t(), state()}
  | {:filter_and_continue, Keyword.t(), state()}
  | {:error, term()}
```

# `strict_check_context`

```elixir
@callback strict_check_context(state()) :: [atom()]
```

# `apply_field_level_auth`

```elixir
@spec apply_field_level_auth(
  Ash.Resource.t(),
  Ash.Resource.Record.t() | [Ash.Resource.Record.t()],
  Keyword.t()
) ::
  {:ok, Ash.Resource.Record.t() | [Ash.Resource.Record.t()]}
  | {:error, Ash.Error.t()}
```

Apply field-level authorization to records that are already in memory,
scrubbing any fields the actor isn't allowed to see.

Walks each authorizer configured on the resource and invokes its
`apply_field_level_auth/3` callback if defined. Returns the records with
forbidden fields replaced by `%Ash.ForbiddenField{}`.

Use this when you have records in hand (for example, returned from a
generic action or constructed in memory) and want field policies applied
without driving the records through a full read.

Supported options:

- `:actor` - the actor whose visibility is being checked.
- `:tenant` - the tenant the records belong to.
- `:domain` - the domain context.

---

*Consult [api-reference.md](api-reference.md) for complete listing*
