View Source Ash.Policy.Check behaviour (ash v3.4.45)

A behaviour for declaring checks, which can be used to easily construct authorization rules.

If a check can be expressed simply, i.e as a function of the actor, or the context of the request, see Ash.Policy.SimpleCheck for an easy way to write that check. If a check can be expressed with a filter statement, see Ash.Policy.FilterCheck for an easy way to write that check.

Summary

Callbacks

An optional callback, that allows the check to work with policies set to access_type :filter

An optional callback, hat allows the check to work with policies set to access_type :runtime

Describe the check in human readable format, given the options

Expands the description of the check, given the actor and subject

Whether or not the expanded description should replace the basic description in breakdowns

Whether or not your check requires the original data of a changeset (if applicable)

Strict checks should be cheap, and should never result in external calls (like database or domain)

The type of the check

Types

actor()

@type actor() :: any()

authorizer()

@type authorizer() :: Ash.Policy.Authorizer.t()

check_type()

@type check_type() :: :simple | :filter | :manual

options()

@type options() :: Keyword.t()

ref()

@type ref() :: {module(), Keyword.t()} | module()

t()

@type t() :: %Ash.Policy.Check{
  check: term(),
  check_module: term(),
  check_opts: term(),
  type: term()
}

Callbacks

auto_filter(actor, authorizer, options)

(optional)
@callback auto_filter(actor(), authorizer(), options()) :: Keyword.t() | Ash.Expr.t()

An optional callback, that allows the check to work with policies set to access_type :filter

Return a keyword list filter that will be applied to the query being made, and will scope the results to match the rule

check(actor, list, map, options)

(optional)
@callback check(actor(), [Ash.Resource.record()], map(), options()) :: [
  Ash.Resource.record()
]

An optional callback, hat allows the check to work with policies set to access_type :runtime

Takes a list of records, and returns the subset of authorized records.

describe(options)

@callback describe(options()) :: String.t()

Describe the check in human readable format, given the options

eager_evaluate?()

@callback eager_evaluate?() :: boolean()

expand_description(actor, authorizer, options)

(optional)
@callback expand_description(
  actor(),
  authorizer(),
  options()
) :: {:ok, String.t()} | :none

Expands the description of the check, given the actor and subject

prefer_expanded_description?()

@callback prefer_expanded_description?() :: boolean()

Whether or not the expanded description should replace the basic description in breakdowns

requires_original_data?(actor, options)

@callback requires_original_data?(actor(), options()) :: boolean()

Whether or not your check requires the original data of a changeset (if applicable)

strict_check(actor, authorizer, options)

@callback strict_check(actor(), authorizer(), options()) ::
  {:ok, boolean() | :unknown} | {:error, term()}

Strict checks should be cheap, and should never result in external calls (like database or domain)

It should return {:ok, true} if it can tell that the request is authorized, and {:ok, false} if it can tell that it is not. If unsure, it should return {:ok, :unknown}

type()

@callback type() :: check_type()

The type of the check

:manual checks must be written by hand as standard check modules :filter checks can use Ash.Policy.FilterCheck for simplicity :simple checks can use Ash.Policy.SimpleCheck for simplicity

Functions

defines_auto_filter?(module)

defines_check?(module)