How to make your Phoenix app more secure —use Argon2 with Phoenix’s phx_gen_auth generator

Image for post
Image for post
Elixir and Phoenix logos.

Why Argon2?

Argon2 is a key derivation function that won the 2015 Password Hashing Competition (Wikipedia). “argon2_elixir” is an Elixir wrapper for the Argon2 function — kind of like a Ruby gem only for your Elixir/Phoenix application (if you’re coming from the world of Ruby and Ruby on Rails).

The Elixir argon2_elixir wrapper defaults to Argon2id which is a hybrid of Argon2’s other variants (Argon2d and Argon2i). For the sake of simplicity, it is typically a “more secure” method for hashing passwords with Argon2.

So, the fact that the Argon2id variant is the default with argon2_elixir is a big thumbs up because it means less configuration on your end (unless you want or need to use the other implementations).

But, really, why Argon2?

Increased security and, thanks to phx_gen_auth and the Comeonin library, it’s virtually the same level of sophistication to implement.

Okay, great.

Argon2 it is (Argon2id in this case).

Why phx_gen_auth?

This is a generator-type authentication solution for Phoenix 1.5+ applications from the gentleman who created Elixir, José Valim.

Enough said, skip to “Let’s get started”.

José spent time with existing authentication solutions for Phoenix (side note: he was also behind Devise — the hugely popular authentication solution for Ruby on Rails) and determined that the best solution is no authentication framework at all.

Enter phx_gen_auth.

phx_gen_auth inserts the authentication code directly into your application, enabling you full control over its growth and development, whilst providing you with the ideal foundation and structure with which to begin.

It’s a tool and masterclass all-in-one, a light and deft touch.

Let’s begin.

Let’s get started

You can call your app whatever you like and also leave out (or include) the “live” flag (it’s for the Phoenix Live View generator — prefix with two dashes).

Note: the “no-ecto” and “no-html” flags are not supported currently. Also, if you’re in an umbrella app, then change (“cd”) into your project’s web_app directory.

  1. Generate a new Phoenix app.
# command line$ mix phx.new auth_app --live$ cd auth_app$ mix ecto.create

2. Add phx_gen_auth to your app’s dependencies.

# mix.exsdefp deps do  [    {:phx_gen_auth, "~> 0.6.0", only: [:dev], runtime: false},    ...  ]end

3. Install and compile your dependencies.

# command line$ mix do deps.get, deps.compile

4. Install your authentication system, using the “hashing-lib” flag with “argon2”. This is called from the root of your Phoenix app (or apps/auth_app_web if this example were an umbrella app).

# command line$ mix phx.gen.auth Accounts Person people --hashing-lib argon2

Note: we substitute out the default “User users”. This is inspired thanks to the recent Netflix documentary, in turn inspired by Shoshana Zuboff’s book, but I digress…

5. Lastly, Phoenix may remind you to re-fetch dependencies and update your repository (mix deps.get and mix ecto.migrate, respectively).

# command line$ mix deps.get # adds argon2_elixir, comeonin, and elixir_make$ mix ecto.migrate$ mix test # test everything works$ mix phx.server # try it out!

Congratulations! You’ve now used the brilliant phx_gen_auth to create your authentication system and hash your application’s passwords with Argon2.

You can quickly verify by going to your person.ex file (or your equivalent), and you’ll see (note — it is in your auth_app, not your auth_app_web, directory):

# lib/auth_app/person.exdefp hash_password(changeset) do  password = get_change(changeset, :password)
changeset |> put_change(:hashed_password, Argon2.hash_pwd_salt(password)) |> delete_change(:password)end

Further reading

When you read through the code generated by phx_gen_auth, you will be delighted to see comments on how to build out your authentication system into a more robust and production ready solution (e.g. implementing stronger password validations to ensure stronger passwords).

I highly recommend digging deeper into the code and documentation by visiting the official GitHub repository for phx_gen_auth and reading the overview guide.

Also, I encourage you to dig into the argon2_elixir documentation for configuration options and to see what’s possible.

Conclusion

After bouncing around from Python/Django and Ruby/Rails, I’m pretty excited to discover this new paradigm (Functional Programming), language (Elixir), and connectivity framework (Phoenix).

I imagine if you are reading this, then you are also excited — or becoming more and more intrigued.

So much thanks to José Valim, Griffin Byatt, Aaron Renner, Dashbit and Chris McCord (creator of Phoenix) for making all of this possible.

Co-founder @ Core Theory

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store