Wax: WebAuthn for Elixir

Hi all,

The last weeks I’ve been working on a library implementing the server side of WebAuthn: Wax.

Link: https://github.com/tanguilp/wax

What is WebAuthn?

WebAuthn (and FIDO2) are a set of protocols that enable phishing-resistant authentication based on authenticators. It works by generating key-pairs (private-public keys) for a user for a specific site (~= URI) in a registration phase and reusing it for further authentication. If you want to use WebAuthn for authentication of your users, you’ll therefore have 2 steps:

  1. Register user key
  2. Authenticate using key generated

How does it look like?

Here is a video demo of WebAuthn / FIDO2 authentication using security keys:

(If you have an authenticator, you can try it out yourself: https://github.com/tanguilp/wax_demo)

What are authenticators?

As of today, most authenticators are USB keys. However, this is changing fast as it will soon include:

  • Smartphone sensors (fingerprint, face recognition, etc.)
  • Sensors on laptops
  • NFC / bluetooth keys

One can also imagine using the fingerprint sensor on his/her smartphone to authenticate to a website on a computer, the smartphone using bluetooth or NFC to enable FIDO2/WebAuthn communication to the computer.

Authenticators can be certified by the FIDO Alliance. When registering a new WebAuthn/FIDO2 key, you can actually receive strong guarantees about the authenticator used, for instance the use of special hardware protection to protect the private keys (TEE / TPM).

What does it solve?

The missing part on today’s unlocking mechanisms on smartphone is that the process is local to the smartphone, which helps with keeping the biometrics on the phone and only on it, but prevents the server from receiving an actual proof of the user authentication (in general, it only receives a token that might come from the user’s smartphone - or not). With WebAuthn & FIDO2, the server receives a signed security proof of user authentication (and, with some extensions, of authorization). And in case of the use of a biometric authentication scheme, the biometric data (e.g.: fingerprint) will not leave the authenticator (the server will not receive it).

Besides, unless other authentication mechanisms such as password, push notifications, SMS, etc. it is not phishable.

How to use it in authentication flows?

I see several ways it can be used. Keep in mind that you can detect support of WebAuthn through javascript, and then not propose it for incompatible browsers or devices. My ideas:

  • As a second factor for high-risk users such as admins, in addition to the password
  • As an optional second factor for knowledgeable people
  • As a convenience first factor, as an alternative to the password (like in the demo video)
  • As the first and unique factor on website you don’t need to know your users, but need to authenticate them ?

Will it solve all authentication problems?

Many people in the Identity and Access Management community go into ecstasies when talking about WebAuthn/FIDO2 - like 2016, no 2017, no 2018, no 2019 is the year of the death of passwords. However:
People will lose, forget or change their authenticators, be it smartphones, security keys or smartphones. This means they’ll have to register again which is not so good on a UX standpoint. Regarding security, the weakest link become the reinitialization process. If that’s a code sent by email then, well, the security level will be the one to access a user’s inbox (password? :wink: )
Some people will probably be reluctant to use it for privacy reasons, especially when biometrics is involved (and even if there’s no actual privacy risk since biometry will not be sent to the server). Like “Login with [social network]” today (I personally seldom use it).

So I guess it will be one authentication scheme among others, and password will still be used, for better or for worse :slight_smile:

What the status of the lib?

Most of the standard is implemented and I’ll keep maintaining the lib. If you have an authenticator, feel free to test the demo app and fill an issue if it doesn’t work.

There are also a lot of things to rework and complete on it, such as implementing new crypto algorithms which are not supported by the core Erlang libraries (RSA PSS, Edwards curves…). Extensions are not supported neither. Pull requests are welcome!

Besides, the FIDO Alliance (that makes the FIDO standard) has released a test suite but it’s not working on Linux as of today.

Last but not least, its security has not been reviewed by anyone other than me, so as long as it has not been thoroughly checked by other experts, use it at your own risks. It also raises the question of open-source security libs that are actually never reread…

Fun facts

  • Implementing the “Android Key attestation statement format” (one of the 6 attestation formats), I had to parse an ASN1 record (whose schema in the Google doc is malformed) from an X509 certificate custom extension, itself stored in a CBOR map. That was the hell of a ride, but not as much as the delicious Trusted Platform Module part 2 PDF doc
  • I noticed my computer had an SD slot while watching the demo video


It’s my first lib in Elixir, and I really enjoy the language. Binary pattern matching was particularly useful for this lib, it’s dead simple and so readable.

Here are a few resources that might be helpful:
Introduction to WebAuthn API
W3C spec


Ooo I was thinking of starting such a WebAuthn layer into ueberauth soon, this will be a huge help!

Hmm, nothing loads? And I am on a GUI system for once…
Apparently that domain is blocked at work, joy…
And on my phone it plays some kind of greeting card video? Lot of buffering, ended up canceling it about half-way through the video… o.O

I’ll take a look at it soon though, thanks for this much! :slight_smile:


Would the main value of an uberauth integration be that you could use webauthn next to other authentication methods. Or would using uberauth provide value even if you were only supporting webauthn?

Hi all!

I’m glad to release version v0.2.0 of Wax, which brings:

  • almost complete support of the protocol, for instance support for new signature schemes including non-NIST ones (edDSA and ES256K (secp256k1 curve)) (see Support of FIDO2 section)
  • 100% conformance with the official FIDO Alliance test suite (passes the 165 server tests), which guarantees better interoperability
  • some code cleaning & refactoring

For those using it: pay attention to the CHANGELOG, some interfaces changed. I’ve updated the Wax demo accordingly.

One can test the library against the official test suite using WaxFidoTestSuiteServer. For this I needed to create the WaxAPIREST library, a REST API on top of Wax. This could be useful if you plan to implement Wax in a higher-level authentication library using Javascript.

Next step will be to have the library officially certified by the FIDO Alliance.



If you only use a single authentication type and will never support another then ueberauth ‘might’ only provide succinctness of API, but even then it’s not really useful. Ueberauth is primarily useful for unifying multiple authentication types.

I have eventually published the library on hex.pm (couldn’t before because of a git dependency).

Because of a name conflict, the application name is :wax_ and not :wax. Beware of not confusing it with another package!

Some other updates have been made as well, including using Tesla (and therefore the HTTP adapter of your choice) for outbound HTTP requests. Refer to the README for more information.

Thanks to all having tested this library and provided feedback. Cheers!