```elixir defmodule Account do use Ash.Resource, data_layer: AshPostgres.DataLayer, extensions: [Ash.Policy.Authorizer, AshAuthentication], authorizers: [Ash.Policy.Authorizer] actions do action :permissions, {:array, :permission} do argument :id, :uuid, allow_nil?: false run fn input, context -> id = Ash.ActionInput.get_argument(input, :id) opts = Ash.Context.to_opts(context) cached = case Ash.get(CachedAccount, id, Keyword.merge(opts, error?: false)) do {:ok, nil} -> Logger.debug("account cache miss: #{id}") nil {:ok, %CachedAccount{permissions: permissions}} -> # Logger.debug("account cache hit: #{id}") permissions {:error, err} -> Logger.warning("error fetching cache: #{Ash.Error.error_descriptions(err)}") nil end if is_nil(cached) do case Ash.get(__MODULE__, id, Keyword.merge(opts, load: [:roles], error?: false)) do {:ok, nil} -> Ash.Error.Query.NotFound.exception(primary_key: id, resource: __MODULE__) {:ok, %{roles: roles} = account} -> Cache.upsert(account) {:ok, Enum.flat_map(roles, & &1.permissions)} {:error, err} -> {:error, err} end else {:ok, cached} end end end end policies do policy action_type(:read) do authorize_if {Auth.Checks.HasPermissions, permissions: [:read_accounts]} end end end defmodule Auth.Checks.HasPermissions do use Ash.Policy.SimpleCheck require Logger @impl Ash.Policy.Check def describe(opts) do pset = Keyword.get(opts, :permissions, []) "Account has permissions: #{inspect(pset)}" end @impl Ash.Policy.SimpleCheck def match?(%Account{} = actor, _context, opts) do actual = Account |> Ash.ActionInput.for_action(:permissions, %{id: actor.id}, authorize?: false) |> Ash.run_action!() |> MapSet.new() required = Keyword.get(opts, :permissions, []) |> MapSet.new() MapSet.subset?(required, actual) end def match?(_, _, _), do: false end ```