Hi everyone,
I’m currently practicing with Elixir, Phoenix, LiveView, and Ash—so I’m not an expert yet, but eager to learn.
I’m building a Phoenix app with Ash + AshAuthentication and want users to log in with whichever unique attribute they prefer—today that’s username or email, but soon it will include mobile phone numbers and other optional fields.
# sign_in_with_password (snippet)
read :sign_in_with_password do
# thinking of replacing :username with :login for flexibility
argument :login, :string
argument :password, :string, sensitive?: true
prepare fn changeset, _ ->
login_val = Ash.Changeset.get_argument(changeset, :login)
user =
Helpdesk.Accounts.User
|> Ash.Query.filter(
expr(username == ^login_val or email == ^login_val /* add mobile later */)
)
|> Helpdesk.Accounts.read_one!()
if user && Helpdesk.Accounts.check_password(user, Ash.Changeset.get_argument(changeset, :password)) do
Ash.Changeset.put_context(changeset, :user, user)
else
Ash.Changeset.add_error(changeset, "Invalid credentials")
end
end
prepare AshAuthentication.Strategy.Password.SignInPreparation
metadata :token, :string
end
Relevant pieces:
- Strategies
strategies do
password :password do
register_action_accept [:username] # open to :mobile next
hash_provider AshAuthentication.BcryptProvider
end
end
- register_with_password
create :register_with_password do
argument :username, :ci_string
argument :email, :ci_string
argument :password, :string, sensitive?: true
argument :password_confirmation, :string, sensitive?: true
end
- attributes & identities
attributes do
attribute :username, :string
attribute :email, :ci_string
# planning: attribute :mobile, :string
end
identities do
identity :unique_username, [:username]
identity :unique_email, [:email]
# will add :unique_mobile, [:mobile]
end
Question
Is there an idiomatic Ash/AshAuthentication way to centralize authentication over any present unique field (username, email, mobile, etc.) without manually extending expr(...) each time?
I’m considering:
- Accepting a generic
:loginargument and dynamically building a filter across all identity fields. - Creating separate sign-in actions per identifier.
- Using a custom data layer or policy trick I’ve missed.
Are there other recommended patterns or best practices for this in Ash/AshAuthentication?
I’m open to any solution that’s clean and maintainable, even examples or links to docs that tackle this pattern.
Thanks for your time!




















