WebAuthn

WebAuthn/FIDO2 is a W3C standard that defines a cryptographic protocol between a relying party (your Flask application) and an authenticator. In simple terms this allows connecting your Flask application to a variety of authenticators including dedicated hardware (e.g. YubiKey) and devices that have cryptographic capabilities (e.g. a mobile phone with fingerprint or face id).

This protocol is supported by all major browsers, and gradually (2025) many major web applications actually support it. Note that those that do normally just support using a WebAuthn credential/passkey as an additional, optional, second factor.

Note that a WebAuthn credential/passkey can possibly satisfy a complete 2-factor authentication requirement - something you have and something you are (think a mobile device with face-Id). Flask-Security supports this use case.

Flask-Security uses the term WebAuthn and WebAuthn credential internally and in its JSON API. For the non-developer community, the term ‘passkey’ has become standard, so all templates and messages refer to WebAuthn credentials as passkeys.

Getting Started

To add WebAuthn support to your application you will need:

  • Install the webauthn package (the Flask-Security pip ‘extra’ [mfa] will do this).

  • Add/modify your DB models as described here.

Key Concepts

While the spec is quite complex - there are 2 important concepts to know. WebAuthn keys can be classified as ‘platform’/’cross-platform’ and ‘resident’/or not. If a key is a platform key that means it is tied to a particular device. If you set up a second factor WebAuthn key that is a platform key you will ONLY BE ABLE TO AUTHENTICATE using that device. For that reason it is a best practice to make sure there is at least one second-factor authentication method setup that is NOT platform specific (such as SMS, an authenticator app, etc.).

Flask-Security requires that when registering a WebAuthn key, the user must specify whether the key will be used for first/primary authentication or for multi-factor/second authentication.

It should be noted the the current spec REQUIRES javascript to communicate from your front-end to the browser. Flask-Security ships with the basic required JS (static/{webauthn.js,base64.js}). An application should be able to simply wire those into their templates or javascript.

Configuration

As with many features in Flask-Security, configuration is a combination of config variables, constructor parameters, and a sub-classable utility class. The WebAuthn spec offers a lot of flexibility in supporting a wide range of authenticators. The default configuration is:

The bundled WebauthnUtil class implements the following defaults:

  • The AuthenticatorSelectionCriteria is set to CROSS_PLATFORM for webauthn credentials/passkeys being registered for first/primary authentication.

  • The UserVerificationRequirement is set to DISCOURAGED for credentials/passkeys used for secondary authentication, and PREFERRED for credentials/passkeys used for first/primary or multi-factor.