taler-docs

Documentation for GNU Taler components, APIs and protocols
Log | Files | Refs | README | LICENSE

commit ac681f0e44fd68a7977c72bf033c237d510acb45
parent f98568776d9e6d0f1515ff865ef8653096df3bec
Author: Florian Dold <dold@taler.net>
Date:   Sat, 29 Aug 2026 18:49:01 +0200

merchant authentication: document password reauthentication

Diffstat:
Mcore/merchant/post-instances-INSTANCE-forgot-password.rst | 18+++++++++++-------
Mcore/merchant/post-management-instances-INSTANCE-auth.rst | 21+++++++++++++++++++--
Mdesign-documents/049-auth.rst | 20++++++++++++++++++--
Mmanpages/taler-merchant.conf.5.rst | 6++++--
4 files changed, 52 insertions(+), 13 deletions(-)

diff --git a/core/merchant/post-instances-INSTANCE-forgot-password.rst b/core/merchant/post-instances-INSTANCE-forgot-password.rst @@ -1,10 +1,14 @@ .. http:post:: /instances/$INSTANCE/forgot-password - Same as ``/management/instances/$INSTANCE/private/auth`` it will update the password of the instance but - without requiring the current password. On the first call it will validate the request - and return the multi-factor authentication challenge IDs with - a ``202 Accepted`` response. Once the challenges are solved the - request needs to be repeated with the ``Taler-Challenge-Ids`` header. + Like ``[/instances/$INSTANCE]/private/auth``, this endpoint updates the + password of the instance, but it does not require the current password. + Instead, every TAN channel listed in ``MANDATORY_TAN_CHANNELS`` must be + solved. Thus, configurations listing both ``sms`` and ``email`` require + both challenges, while configurations listing only one of them require only + that channel. On the first call the backend validates the request and + returns the challenge IDs with a ``202 Accepted`` response. Once all + required challenges are solved, the exact request must be repeated with the + ``Taler-Challenge-Ids`` header. This endpoint is **not** available for the ``admin`` instance. The administrator must use the command-line tool if they forgot @@ -21,8 +25,8 @@ refreshable ``spa`` access token in a `LoginTokenSuccessResponse`, as requested with ``token_duration``. @since **v39** :http:statuscode:`202 Accepted`: - 2FA is required for this operation. This returns - the `ChallengeResponse`. @since **v21** + TAN authentication is required for this operation. This returns the + `ChallengeResponse` with ``combi_and`` set to true. @since **v21** :http:statuscode:`204 No content`: The backend has successfully changed the credentials for the instance. No login token was requested. diff --git a/core/merchant/post-management-instances-INSTANCE-auth.rst b/core/merchant/post-management-instances-INSTANCE-auth.rst @@ -9,7 +9,11 @@ **Required permission:** ``auth-write`` on the ``/private`` path, ``instances-auth-write`` on the ``/management/`` path (see :ref:`Scopes <merchant-api-scopes>`) - **Request** the request must be an `InstanceAuthConfigurationMessage`. + **Request:** Requests to ``/management/instances/$INSTANCE/auth`` use an + `InstanceAuthConfigurationMessage`. Requests to the instance's own + ``/private/auth`` endpoint use an `InstanceAuthChangeRequest` and must + reauthenticate with the current password whenever the existing + authentication method is ``token``. **Response:** @@ -18,7 +22,9 @@ :http:statuscode:`204 No content`: The backend has successfully changed the credentials for the instance. :http:statuscode:`401 Unauthorized`: - The request is unauthorized. + The request is unauthorized. A missing or incorrect ``old_password`` on + the ``/private`` path is returned with + ``TALER_EC_MERCHANT_PRIVATE_POST_INSTANCE_AUTH_BAD_OLD_PASSWORD``. :http:statuscode:`403 Forbidden`: MFA channels are not available for this instance. Returned with ``TALER_EC_MERCHANT_GENERIC_MFA_MISSING``. @@ -41,6 +47,17 @@ type InstanceAuthConfigurationMessage = InstanceAuthConfigToken | InstanceAuthConfigTokenOLD | InstanceAuthConfigExternal + .. ts:def:: InstanceAuthChangeRequest + + // @since **v40** + type InstanceAuthChangeRequest = InstanceAuthConfigurationMessage & { + // Required on the instance's own /private/auth endpoint when the + // current authentication method is "token". It is checked by the + // backend against the stored password before the update is committed. + // Administrative changes through /management do not use this field. + old_password: string; + }; + .. ts:def:: InstanceAuthConfigToken // @since **v19** diff --git a/design-documents/049-auth.rst b/design-documents/049-auth.rst @@ -6,8 +6,8 @@ DD 49: Authentication :DD shepherd: TBD :Historical contributors: Florian Dold, Sebastian, Antoine A, Martin Schanzenbach, Christian Grothoff :First published: 2023-09-06 -:Last substantive change: 2025-06-19 -:Implementation evidence: merchant (2023-09-06), libeufin (2024-11-15) +:Last substantive change: 2026-08-29 +:Implementation evidence: merchant (2023-09-06, 2026-08-29), libeufin (2024-11-15) :Normative references: ``core/api-merchant.rst``, ``core/api-corebank.rst`` .. note:: @@ -216,6 +216,22 @@ suffixing the requested scope with ``:refreshable``, for example ``refreshable`` field in its ``TokenRequest``. Clients must follow the normative API of the component they use. +Password changes and recovery +============================= + +A bearer token authorizes access to the account, but it is not sufficient by +itself to replace password authentication. A merchant changing its own +password must reauthenticate with the current password, which the backend +checks against its stored password hash. An administrator resetting another +instance's authentication is exempt because the administrative credential is +the authority for that operation. + +Forgotten-password recovery cannot provide the current password. The public +merchant recovery endpoint therefore requires all channels configured in +``MANDATORY_TAN_CHANNELS``. If both SMS and e-mail are configured, both must +be solved; if exactly one is configured, that one challenge is sufficient. A +merchant backend with no mandatory TAN channel refuses public recovery. + Definition of Done ================== diff --git a/manpages/taler-merchant.conf.5.rst b/manpages/taler-merchant.conf.5.rst @@ -166,8 +166,10 @@ ENABLE_SELF_PROVISIONING Set to YES to allow unauthenticated clients to create new instances. MANDATORY_TAN_CHANNELS - Space-separted list of TAN channels required for password reset. - Can be "sms" or "email" or both. + Space-separated list of TAN channels required for password reset. + Supported channels are ``sms`` and ``email``. Every channel in the list is + mandatory: listing both requires both challenges, while listing only one + requires only that challenge. PHONE_REGEX Posix regular expression specifying which phone numbers are acceptable for