Protecting Phoenix endpoints with HTTP Basic Auth (on Heroku)

1st May, 2020

Phoenix LiveDashboard was recently officially announced by José Valim, and I was keen try it out so I installed it on a toy app I’ve been developing, which is deployed to Heroku.

I didn’t want my LiveDashboard to be available to the whole world, so the quickest and easiest method of protecting it was to use HTTP Basic Authentication, something that is recommended in the LiveDashboard docs.

To that end, I installed and configured the basic_auth plug, and read the username and password to configure it from environment variables.

These are the steps I took.

Install and configure

  1. Add the basic_auth plug

    Add basic_auth to your mix.exs file

    {:basic_auth, "~> 2.2.4"}
    

    Install dependencies

    mix deps.get
    
  2. Configure basic_auth from environment variables

    Edit your prod.secret.exs file and add this.

    http_basic_auth_username =
      System.get_env("HTTP_BASIC_AUTH_USERNAME") ||
        raise """
        environment variable HTTP_BASIC_AUTH_USERNAME is missing.
        """
    
    http_basic_auth_password =
      System.get_env("HTTP_BASIC_AUTH_PASSWORD") ||
        raise """
        environment variable HTTP_BASIC_AUTH_PASSWORD is missing.
        """
    
    # Set basic auth from environment variables
    config :example_web, basic_auth: [
      username: http_basic_auth_username,
      password: http_basic_auth_password,
    ]
    
  3. Update the router to protect the LiveDashboard routes

    Create a new pipeline that conditionally adds the basic_auth plug if the HTTP_BASIC_AUTH_USERNAME or HTTP_BASIC_AUTH_PASSWORD are present.

    pipeline :protected do
      if System.get_env("HTTP_BASIC_AUTH_USERNAME") || System.get_env("HTTP_BASIC_AUTH_PASSWORD") do
        plug BasicAuth, use_config: {:example_web, :basic_auth}
      end
    end
    

    Then add :protected to the pipeline.

    scope "/", ExampleWeb do
      pipe_through [:browser, :protected]
      live_dashboard "/dashboard"
    end
    
  4. Set your environment variables on Heroku

    heroku config:set HTTP_BASIC_AUTH_USERNAME=admin \
                      HTTP_BASIC_AUTH_PASSWORD=P@ssword
    

Now when you visit /dashboard you should be prompted to enter your username and password.