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]
Summary
Callbacks
Apply field-level authorization to a list of records that already have values populated in memory, without re-fetching them through a read.
Functions
Apply field-level authorization to records that are already in memory, scrubbing any fields the actor isn't allowed to see.
Types
Callbacks
@callback add_calculations(Ash.Query.t() | Ash.Changeset.t(), state(), context()) :: {:ok, Ash.Query.t() | Ash.Changeset.t(), state()} | {:error, Ash.Error.t()}
@callback alter_filter(filter :: Ash.Filter.t(), state(), context()) :: {:ok, Ash.Filter.t()} | {:error, Ash.Error.t()}
@callback alter_results(state(), [Ash.Resource.Record.t()], context()) :: {:ok, [Ash.Resource.Record.t()]} | {:error, Ash.Error.t()}
@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.
@callback check(state(), context()) :: :authorized | {:data, [Ash.Resource.Record.t()]} | {:error, :forbidden, state()} | {:error, Ash.Error.t()}
@callback exception(atom(), state()) :: Exception.t()
@callback initial_state( Ash.Resource.t(), Ash.Resource.Record.t(), Ash.Resource.Actions.action(), Ash.Domain.t() ) :: state()
Functions
@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.