Skip to main content
Version: 2.3.x.x RR



A user is trying to access an HTTP application, for example an e-banking application, which requires authentication. The user must provide the required authentication with a FIDO2 capable authenticator. Furthermore, the HTTP application is protected by Nevis (notably nevisProxy and nevisAuth).


  • The user's device and browser must support FIDO2.
  • The user already has existing FIDO2 credentials which can be used to authenticate.


  1. The user opens the web application in the browser.
  2. The browser tries to access the web application to display information to the user.
  3. Nevis detects that the browser is not authenticated. It asks the user to provide his login identifier to authenticate.
  4. The user provides his login information.
  5. The login information is sent to the Nevis backend.
  6. After identifying the user, Nevis asks the user to provide FIDO2 authentication.
  7. The user authenticates using the FIDO2 Authenticator available on the client device.
  8. The signed FIDO2 assertion is sent to the Nevis backend for validation.
  9. The user is now authenticated and able to access the web server.
  10. The user is now logged in and able to access the web application.
FIDO2 Authentication Example

Technical flow

The technical flow in the following figure explains the component interaction in detail. The step numbers in the next figure do not correlate with the simplified example above.


The following flow is a simple compact example. Depending on requirements, changes or different approaches might be required. The key fix points are:

  • WebAuthn API in the browser.
  • FIDO2 HTTP API in nevisFIDO.
  • nevisAuth must be aware of the status of the FIDO2 authentication.
  1. The user initiates the FIDO2 authentication.

  2. nevisProxy forwards the userId input to nevisAuth

  3. The IdmUserVerifyState verifies if the provided userId matches any user.

  4. The provided userId from the browser should be mapped to an extId so later there is no need to think about what kind of identifier it is. Best approach is to use the extId from this point forward. You can use the IdmGetPropertiesState for this purpose.

  5. Depending on the flow you would like to implement, at this point you might want to check if the user has a FIDO2 credential or not. The IdmCredStatusCheckState doesn't support FIDO2 credentials, so to do this you will need a ScriptState to query nevisIdm via the REST API. see example here

  6. The transition is made to the ScriptState implementing the FIDO2 authentication. In this state it will render the self executing JS.

  7. The browser uses the JavaScript client to initiate the FIDO2 authentication. As the client JavaScript likely contains customer-specific code adapted for specific needs, how the authentication is triggered is up to the custom implementation.

  8. The JS client submits an empty form POST to get the ServerPublicKeyCredentialGetOptionsResponse. In this example implementation the ServerPublicKeyCredentialGetOptionsRequest is generated by the Groovy ScriptSate.

  9. nevisProxy continues the authentication process by calling nevisAuth.

  10. The ServerPublicKeyCredentialGetOptionsRequest is created by ScriptState and calls the nevisFIDO Options endpoint.

    Endpoint: https://<nevisFIDO-host>:<nevisFIDO-port>/nevisfido/fido2/attestation/options


  11. nevisFIDO queries the FIDO2 credentials from nevisIdm.

  12. Challenge is generated and the ServerPublicKeyCredentialGetOptionsResponse is built.

  13. A direct response is prepared using the ServerPublicKeyCredentialGetOptionsResponse.

  14. JS client receives the ServerPublicKeyCredentialGetOptionsResponse.

  15. JS client initiates an authentication using the received Options response via the WebAuthn API.

  16. Dialog presented to the user by the browser to unlock the private key.

  17. The user authenticates.

  18. The WebAuthn API generates an assertion and returns it to the JS client.

  19. JS client submits assertion to the backend.

  20. The ScriptState in nevisAuth assembles a ServerPublicKeyCredentialForAuthentication JSON payload from the form submit and calls the nevisFIDO REST API.

    Endpoint: https://<nevisFIDO-host>:<nevisFIDO-port>/nevisfido/fido2/assertion/result


  1. nevisFIDO session lookup. (This session is independent of the nevisAuth session)
  2. nevisFIDO queries the FIDO2 credentials from nevisIdm.
  3. The FIDO2 credential is updated with a new SignCounter, to prevent replay attacks. (the counter is not increased by a predefined number)
  4. FIDO2 session is updated to reflect the current status.
  5. ServerResponse is returned stating the status of the FIDO2 authentication.
  6. ScriptState decides next step / does error handling based on implementation.
  7. nevisAuth returns to nevisProxy with a SecToken.
  8. nevisProxy grants access to originally requested resource.