In case anyone travels this path in the future this is what I did …
This tutorial was my jumping off point: http://codeloveandboards.com/blog/2018/06/20/elixir-and-phoenix-basic-passwordless-and-databaseless-authentication-pt-2/ I did find part 3 but that’s not so helpful since it covers building an Elm SPA.
My use case was restricting access to particular domains. So instead of a hard encoded list of users I have a manageable number of domains in config.exs
. Even so, the number of domains might grow to be unmanageable here, and I’ll need to explore an alternative - Mnesia perhaps.
GenServer is used for state. In my case it’s an advantage that a GenServer is transient and to require users to re-register when the GenServer restarts. Maybe not so good for a public facing app, but I’m working on an in-house tool and it’s a feature 
The state is a nested map %{domain: %{user_name: “token”}}. The user name is randomly generated using :crypto. I cannot cancel a known users registration because I don’t have any knowledge of a particular user on the server.
Authentication is done using an emailed token. I’m using SendGrid, which was relatively painless to set-up, although a couple of module names have changed which needed fixing.
When a user submits their email address the first thing that is checked is the domain. If it’s not supported then they fall at the first fence. The successful submission and verification of the emailed link (one that didn’t display localhost!) results in 3 cookies being saved to the users browser - their random name, their org and the encrypted token. All are set to expire at 2-weeks.
Handily (I didn’t know this beforehand) the browser automatically submits the cookies for each subsequent request. They have to be fetched to populate conn. I’ve built a small plug that requests are routed through. The plug checks the org (first check), then finds their user name against the org (second check), and then checks the now unencrypted token against the user name (third check). All by calling the GenServer.
I have another layer completing authorisation by comparing the org against metadata in the data that the user requests. Rather than trying to authorise against resources ahead of time. The owners of the data can decide who gets to see it.
Users have to go through registration frequently. I’ve set-up a monthly cleanse of the GenServer. Their cookies expire after 2-weeks. And it’ll reset each time I redeploy or the GenServer falls over. Given the registration is so lightweight I regard this as a feature for my use case.
That’s it! My first GenServer, my first plug, and the first time using Bamboo and SendGrid.