Ash dropping FilterCheck if there's `authorize_if always()`
Hi, I've got a resource that in it's action has:
Previously there were other checks instead of
always()
but we've loosened our constraints.
When we've changed it to always()
the FilterByActorID stopped applying
My question is, is this the intended behaviour or is it a bug?10 Replies
That’s intended. Nothing in that policy will forbid the request anymore. I.e if the actors if matches the filter then the policy passes, and then it always passes
Policies logically apply from top to bottom
Thanks!
Just to make sure, if the filter is something like
expr(owner_id == ^actor(:id))
that filter would not be applied to reads anymore in this case?Yep. You can rewrite the policies to make it apply still
It’s just the way that the policy logically works when it just contains two
authorize_if
statements and the last one supersedes the first one.Maybe something should be added to the checks section https://ash-hq.org/docs/guides/ash/latest/topics/policies#checks, because there it looks like the first
authorize_if
wins, but the filter is handled differently, because it needs to be run later with the data,i guess? Essentially filter_checks only make sense in their own policy block?well, thats not the issue
When reading policies, you want to imagine you're reading instructions from top to bottom, and constructing a statement
And you want to imagine its from the perspective of an individual record, not a group of records.
authorize_if
cannot produce a forbidden result (but if nothing at the end has produced an :authorized
result, then it is forbidden. So the statement in procedural logic for each record might look something like this:
So when we build a filter statement, there is no need to add a filter. Because you can see everything
Without authorize_if always()
at the end, ActorIdMatches
would return :unknown
, and :unknown
at the end is :forbidden
. So for an individual record that would be like:
So the only branch that this should return true
for is the one that filters by id.yeah, ok I'm getting it now I think. either the filter check is ok and it is authorized or if it is not it is still authorized because of the always case
yep!
Thanks again for clearing things up for me
any time 😄