Why this policy worked in Ash 2 but not in Ash 3?

In my user action I have these policies:

policies do
  bypass AshAuthentication.Checks.AshAuthenticationInteraction do
    authorize_if always()
  end

  policy always() do
    forbid_unless actor_attribute_equals(:active?, true)
    authorize_if always()
  end
  ...
end

In Ash 2, when I run sign_in_with_password it will login successfully.

Now, in Ash 3 it fails on that second policy. Basically it fail when, as far as I can tell, when ash authentication tries to fetch the user by its token using the token user belongs_to relationship which will call the read action in my user resource which will not contain the ash_authentication?: true so it will not enter the bypass and then it will fail in the second policy since the actor doesn’t exists yet.

I had to add this bypass to make it work:

    bypass accessing_from(Token, :user) do
      authorize_if always()
    end

which is fine, but I still would like to understand if there is some logic change between Ash 2 to Ash 3 in the policies that made this stop working after the upgrade.

Seems to me that in Ash 2, if you don’t send the actor, it will just ignore the policies and in Ash 3, it will be set as nil and run the policies anyway, is that correct?

Maybe this is related to the change that now Domain.authorization.authorize defaults to :by_default?

As you already mentioned, it is due to the changing of the default of Domain.authorization.authorize.

Before, it was set to :when_requested, which would only check policies if an actor was supplied.

The new setting now always checks policies unless you explicitly set authorize?: false

2 Likes