<commit_before>.. _authentication_modes:

Authentication Modes
====================

privacyIDEA supports a variety of tokens that implement different
authentication flows. We call these flows *authentication modes*. Currently,
tokens may implement three authentication modes, namely ``authenticate``,
``challenge`` and ``outofband``.

Application plugins need to implement the three authentication modes
separately, as the modes differ in their user experience. For example:

* The HOTP token type implements the ``authenticate`` mode, which is a
  single-shot authentication flow. For each authentication request, the user
  uses their token to generate a new HOTP value and enters it along with their
  OTP PIN. The plugin sends both values to privacyIDEA, which decides whether
  the authentication is valid or not.
* The E-Mail and SMS token types implement the ``challenge`` mode. With such a
  token, the authentication flow consists of two steps: In a
  first step, the plugin triggers a challenge. privacyIDEA sends the challenge
  response --- a fresh OTP value --- to the user via E-Mail or SMS.
  In a second step, the user responds to the challenge by entering the
  respective OTP value in the plugin's login form. The plugin sends the
  challenge response to privacyIDEA, which decides whether the authentication
  is valid or not.
* The PUSH and TiQR token types implement the ``outofband`` mode.
  With a PUSH token, the authentication step also consists of two steps:
  In a first step, the user triggers a challenge. privacyIDEA pushes the
  challenge to the user's smartphone app. In a second step, the user approves
  the challenge on their phone, and the app responds to the challenge by
  communicating with the privacyIDEA server on behalf of the user.
  The plugin periodically queries privacyIDEA to check if
  the challenge has been answered correctly and the authentication is valid.

The following describes the authentication flows of the three authentication
modes in more detail.

.. _authentication_mode_authenticate:

``authenticate`` mode
---------------------

.. uml::
  :width: 500

  Service -> PrivacyIDEA: POST /validate/check
  Service <-- PrivacyIDEA

* The user enters a OTP PIN along with an OTP value.
* The plugin sends a request to the ``/validate/check`` endpoint:

  .. code-block:: text

    POST /validate/check

    user=<user>&pass=<PIN+OTP>

 and privacyIDEA returns whether the authentication request has succeeded
 or not.

.. _authentication_mode_challenge:

``challenge`` mode
------------------

.. uml::
  :width: 500

  alt with pin

    Service -> PrivacyIDEA: POST /validate/check
    Service <-- PrivacyIDEA: transaction_id

  else without pin

    Service -> PrivacyIDEA: POST /validate/triggerchallenge
    Service <-- PrivacyIDEA: transaction_id

  end

  PrivacyIDEA -> "SMS Gateway": OTP

  ...User enters OTP from SMS...

  Service -> PrivacyIDEA: POST /validate/check
  Service <-- PrivacyIDEA

* The plugin triggers a challenge, for example via the
  ``/validate/triggerchallenge`` endpoint:

  .. code-block:: text

    POST /validate/triggerchallenge

    user=<user>

  Alternatively, a challenge can be triggered via the ``/validate/check``
  endpoint with the PIN of a challenge-response token:

  .. code-block:: text

    POST /validate/check

    user=<user>&pass=<PIN>

  In both variants, the plugin receives a transaction ID which we call
  ``transaction_id`` and asks the user for the challenge response.
* The user enters the challenge response, which we call ``OTP``.
  The plugin forwards the response to privacyIDEA along with the
  transaction ID:

  .. code-block:: text

    POST /validate/check

    user=<user>&transaction_id=<transaction_id>&pass=<OTP>

 and privacyIDEA returns whether the authentication request succeeded or not.

.. _authentication_mode_outofband:

``outofband`` mode
------------------

.. uml::
  :width: 500

  alt with pin

    Service -> PrivacyIDEA: POST /validate/check
    Service <-- PrivacyIDEA: transaction_id

  else without pin

    Service -> PrivacyIDEA: POST /validate/triggerchallenge
    Service <-- PrivacyIDEA: transaction_id

  end

  PrivacyIDEA -> Firebase: PUSH Notification
  Firebase -> Phone: PUSH Notification

  loop until confirmed

    Service -> PrivacyIDEA: GET /validate/polltransaction
    Service <-- PrivacyIDEA: false

  end

  ...User confirms sign in on phone...

  Phone -> PrivacyIDEA: POST /ttype/push

  Service -> PrivacyIDEA: GET /validate/polltransaction
  Service <-- PrivacyIDEA: true

  |||

  Service -> PrivacyIDEA: POST /validate/check
  Service <-- PrivacyIDEA

* The plugin triggers a challenge, for example via the
  ``/validate/triggerchallenge`` endpoint:

  .. code-block:: text

    POST /validate/triggerchallenge

    user=<user>

  or via the ``/validate/check`` endpoint with the PIN of a out-of-band token:
<commit_msg>Add a short note what the service is.<commit_after>.. _authentication_modes:

Authentication Modes
====================

privacyIDEA supports a variety of tokens that implement different
authentication flows. We call these flows *authentication modes*. Currently,
tokens may implement three authentication modes, namely ``authenticate``,
``challenge`` and ``outofband``.

Application plugins need to implement the three authentication modes
separately, as the modes differ in their user experience. For example:

* The HOTP token type implements the ``authenticate`` mode, which is a
  single-shot authentication flow. For each authentication request, the user
  uses their token to generate a new HOTP value and enters it along with their
  OTP PIN. The plugin sends both values to privacyIDEA, which decides whether
  the authentication is valid or not.
* The E-Mail and SMS token types implement the ``challenge`` mode. With such a
  token, the authentication flow consists of two steps: In a
  first step, the plugin triggers a challenge. privacyIDEA sends the challenge
  response --- a fresh OTP value --- to the user via E-Mail or SMS.
  In a second step, the user responds to the challenge by entering the
  respective OTP value in the plugin's login form. The plugin sends the
  challenge response to privacyIDEA, which decides whether the authentication
  is valid or not.
* The PUSH and TiQR token types implement the ``outofband`` mode.
  With a PUSH token, the authentication step also consists of two steps:
  In a first step, the user triggers a challenge. privacyIDEA pushes the
  challenge to the user's smartphone app. In a second step, the user approves
  the challenge on their phone, and the app responds to the challenge by
  communicating with the privacyIDEA server on behalf of the user.
  The plugin periodically queries privacyIDEA to check if
  the challenge has been answered correctly and the authentication is valid.

The following describes the authentication flows of the three authentication
modes in more detail.

.. _authentication_mode_authenticate:

``authenticate`` mode
---------------------

.. uml::
  :width: 500

  Service -> privacyIDEA: POST /validate/check
  Service <-- privacyIDEA

The *Service* is an application that is protected with a second factor by privacyIDEA.

* The user enters a OTP PIN along with an OTP value at the *Service*.
* The plugin sends a request to the ``/validate/check`` endpoint of privacyIDEA:

  .. code-block:: text

    POST /validate/check

    user=<user>&pass=<PIN+OTP>

 and privacyIDEA returns whether the authentication request has succeeded
 or not.

.. _authentication_mode_challenge:

``challenge`` mode
------------------

.. uml::
  :width: 500

  alt with pin

    Service -> privacyIDEA: POST /validate/check
    Service <-- privacyIDEA: transaction_id

  else without pin

    Service -> privacyIDEA: POST /validate/triggerchallenge
    Service <-- privacyIDEA: transaction_id

  end

  privacyIDEA -> "SMS Gateway": OTP

  ...User enters OTP from SMS...

  Service -> privacyIDEA: POST /validate/check
  Service <-- privacyIDEA

* The plugin triggers a challenge, for example via the
  ``/validate/triggerchallenge`` endpoint:

  .. code-block:: text

    POST /validate/triggerchallenge

    user=<user>

  Alternatively, a challenge can be triggered via the ``/validate/check``
  endpoint with the PIN of a challenge-response token:

  .. code-block:: text

    POST /validate/check

    user=<user>&pass=<PIN>

  In both variants, the plugin receives a transaction ID which we call
  ``transaction_id`` and asks the user for the challenge response.
* The user enters the challenge response, which we call ``OTP``.
  The plugin forwards the response to privacyIDEA along with the
  transaction ID:

  .. code-block:: text

    POST /validate/check

    user=<user>&transaction_id=<transaction_id>&pass=<<PASSWORD>>

 and privacyIDEA returns whether the authentication request succeeded or not.

.. _authentication_mode_outofband:

``outofband`` mode
------------------

.. uml::
  :width: 500

  alt with pin

    Service -> privacyIDEA: POST /validate/check
    Service <-- privacyIDEA: transaction_id

  else without pin

    Service -> privacyIDEA: POST /validate/triggerchallenge
    Service <-- privacyIDEA: transaction_id

  end

  privacyIDEA -> Firebase: PUSH Notification
  Firebase -> Phone: PUSH Notification

  loop until confirmed

    Service -> privacyIDEA: GET /validate/polltransaction
    Service <-- privacyIDEA: false

  end

  ...User confirms sign in on phone...

  Phone -> privacyIDEA: POST /ttype/push

  Service -> privacyIDEA: GET /validate/polltransaction
  Service <-- privacyIDEA: true

  |||

  Service -> privacyIDEA: POST /validate/check
  Service <-- privacyIDEA

* The plugin triggers a challenge, for example via the
  ``/validate/triggerchallenge`` endpoint:

  .. code-block:: text

    POST /validate/triggerchallenge

    user=<user>

  or via the ``/validate/check`` endpoint with the PIN of a out-of-band token:

{'fraction_non_alphanumeric': 0.08845110061312694, 'fraction_numerical': 0.0018092270579957784, 'mean_word_length': 3.514519056261343, 'pattern_counts': {'":': 2, '<': 40, '<?xml version=': 0, '>': 48, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '6333626', 'n_tokens_mistral': 2781, 'n_tokens_neox': 2548, 'n_words': 1178}