diff options
Diffstat (limited to 'taler-exchange-manual.rst')
-rw-r--r-- | taler-exchange-manual.rst | 890 |
1 files changed, 474 insertions, 416 deletions
diff --git a/taler-exchange-manual.rst b/taler-exchange-manual.rst index df05fbfc..57db7095 100644 --- a/taler-exchange-manual.rst +++ b/taler-exchange-manual.rst @@ -1,7 +1,7 @@ .. This file is part of GNU TALER. - Copyright (C) 2014-2023 Taler Systems SA + Copyright (C) 2014-2024 Taler Systems SA TALER is free software; you can redistribute it and/or modify it under the terms of the GNU Affero General Public License as published by the Free Software @@ -17,8 +17,13 @@ @author Christian Grothoff @author Florian Dold -GNU Taler Exchange Operator Manual -################################## +Exchange Operator Manual +######################## + +.. contents:: Table of Contents + :depth: 1 + :local: + Introduction ============ @@ -35,6 +40,7 @@ About this manual This manual targets system administrators who want to install and operate a GNU Taler exchange. + Organizational prerequisites ---------------------------- @@ -449,7 +455,7 @@ to compartmentalize different parts of the system: The exchange setup uses the following system groups: -* ``taler-exchange-db``: group for all Taler users with direct database access, specifically taler-exchange-httpd, taler-exchange-wire, taler-exchange-closer and taler-exchange-aggregator. +* ``taler-exchange-db``: group for all Taler users with direct database access, specifically taler-exchange-httpd, taler-exchange-wirewatch, taler-exchange-closer and taler-exchange-aggregator. * ``taler-exchange-secmod``: group for processes with access to online signing keys; this group must have four users: taler-exchange-secmod-rsa, taler-exchange-secmod-cs, taler-exchange-secmod-eddsa and taler-exchange-httpd. * ``taler-exchange-offline``: group for the access to the offline private key (only used on the offline host and not used on the online system). @@ -521,11 +527,6 @@ can use the ``taler-config`` helper: .. include:: frags/configuration-format.rst -.. _Using-taler_002dconfig-exchange: - -.. include:: frags/using-taler-config.rst - - Exchange Database Setup ======================= @@ -827,375 +828,32 @@ configuration of the online machine: Wire Gateway Setup ================== -The Taler Wire Gateway is an API that connects the Taler exchange to -the underlying core banking system. - -LibEuFin is an implementation of the Wire Gateway API for the EBICS protocol. -This section will walk through (1) installing and configuring LibEuFin and -(2) connecting the Taler Exchange to LibEuFin. - -.. note:: - - If you do not have a bank account with EBICS but want to test these instructions, - you can use the EBICS sandbox as described in the - :doc:`LibEuFin Tutorial <libeufin/nexus-tutorial>`. - - -Installation and Basic Configuration ------------------------------------- - -First, install the ``libeufin`` package. This can be done on the ``exchange-online`` -machine or a different one. - -.. code-block:: shell-session - - [root@exchange-online]# apt-get install -y libeufin - -The main component of LibEuFin is called the Nexus. It implements a Web -service that provides a JSON abstraction layer to access bank accounts. - -The HTTP port and database connection string can be edited in the configuration: - -.. code-block:: ini - :caption: /etc/libeufin/nexus.env - - LIBEUFIN_NEXUS_PORT=5017 - LIBEUFIN_NEXUS_DB_CONNECTION=jdbc:sqlite:/var/lib/libeufin/nexus/nexus-db.sqlite3 - -After configuring the database, you can start the service. -The database is initialized automatically. - - -.. code-block:: shell-session - - [root@exchange-online]# systemctl enable libeufin-nexus - [root@exchange-online]# systemctl start libeufin-nexus - -You can now create a superuser account. The command to -create the superuser needs direct database access, thus -the configuration file is sourced first, and the relevant -environment variable is exported. - -.. code-block:: console - - [root@exchange-online]# source /etc/libeufin/nexus.env - [root@exchange-online]# export LIBEUFIN_NEXUS_DB_CONNECTION - [root@exchange-online]# NEXUS_ADMIN_PW=$(tr -dc A-Za-z0-9 </dev/urandom | head -c 13) - [root@exchange-online]# libeufin-nexus superuser admin --password $NEXUS_ADMIN_PW - -If you omit ``--password $NEXUS_ADMIN_PW``, you will interactively be asked for a password. -For simplicity, a superuser can as well act as a normal user, but an API -to create less privileged users is offered. - -.. note:: - - User and permissions management in LibEuFin is still under development. - In particular, permissions for non-superusers are very limited at the moment. - - -Connecting Nexus with an EBICS account --------------------------------------- - -The command line interface of the LibEuFin Nexus needs the following three -values to be defined in the environment: ``LIBEUFIN_NEXUS_URL``, -``LIBEUFIN_NEXUS_USERNAME``, and ``LIBEUFIN_NEXUS_PASSWORD``. In this example, -``LIBEUFIN_NEXUS_USERNAME`` should be set to ``admin``, and -``LIBEUFIN_NEXUS_PASSWORD`` to the value hold in ``NEXUS_ADMIN_PW`` from the -previous step (the ``libeufin-nexus superuser`` command). The -``LIBEUFIN_NEXUS_URL`` could be given as ``http://localhost:5017/``. - -Next, we create a EBICS *bank connection* that Nexus can use to communicate with the bank. - -.. code-block:: console - - [root@exchange-online]# libeufin-cli \ - connections \ - new-ebics-connection \ - --ebics-url $EBICS_BASE_URL \ - --host-id $EBICS_HOST_ID \ - --partner-id $EBICS_PARTNER_ID \ - --ebics-user-id $EBICS_USER_ID \ - $CONNECTION_NAME - -If this step executes correctly, Nexus will have created all the cryptographic -material that is needed on the client side; in this EBICS example, it created -the signature and identification keys. It is therefore advisable to *make -a backup copy* of such keys. - -.. code-block:: console - - [root@exchange-online]# libeufin-cli \ - connections \ - export-backup \ - --passphrase $SECRET \ - --output-file $BACKUP_FILE \ - $CONNECTION_NAME - -At this point, Nexus needs to both communicate its keys to the bank, and -download the bank's keys. This synchronization happens through the INI, HIA, and -finally, HPB message types. - -After the electronic synchronization, the subscriber must confirm their keys -by sending a physical mail to the bank. The following command helps generating -such letter: - -.. code-block:: console - - [root@exchange-online]# libeufin-cli connections get-key-letter $CONNECTION_NAME out.pdf - -.. code-block:: console - - [root@exchange-online]# libeufin-cli \ - connections \ - connect \ - $CONNECTION_NAME - -.. - FIXME: Maybe is not 100% clear that 'connecting' means exchanging keys - with the bank? - -Once the connection is synchronized, Nexus needs to import locally the data -corresponding to the bank accounts offered by the bank connection just made. -The command below downloads the list of the bank accounts offered by ``$CONNECTION_NAME``. - -.. code-block:: console - - [root@exchange-online]# libeufin-cli \ - connections \ - download-bank-accounts \ - $CONNECTION_NAME - -It is now possible to list the accounts offered by the connection. +The :ref:`Taler Wire Gateway <taler-wire-gateway-http-api>` is an API that +connects the Taler exchange to the underlying core banking system. There are +several implementations of wire gateways: -.. code-block:: console - - [root@exchange-online]# libeufin-cli \ - connections \ - list-offered-bank-accounts \ - $CONNECTION_NAME - -.. note:: - - The ``nexusBankAccountId`` field should at this step be ``null``, - as we have not yet imported the bank account and thus the account - does not yet have a local name. - -Nexus now needs an explicit import of the accounts it should manage. This -step is needed to let the user pick a custom name for such accounts. - -.. code-block:: console - - [root@exchange-online]# libeufin-cli \ - connections \ - import-bank-account \ - --offered-account-id testacct01 \ - --nexus-bank-account-id $LOCAL_ACCOUNT_NAME \ - $CONNECTION_NAME - -Once a Nexus user imported a bank account (``$LOCAL_ACCOUNT_NAME``) -under a certain connection (``$CONNECTION_NAME``), it is possible -to accomplish the usual operations for any bank account: asking for the -list of transactions, and making a payment. - -Testing: Requesting the transaction history -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + * `Project deploymerization <https://git.taler.net/depolymerization.git>`_ implements a wire gateway on top of Bitcoin or Ethereum + * The :ref:`libeufin-bank <libeufin-bank>` provides a wire gateway interface on top of a regional currency bank + * The **taler-fakebank-run** command is an in-memory bank simulator with a wire gateway interface for testing -The LibEuFin Nexus keeps a local copy of the bank account's transaction -history. Before querying transactions locally, it is necessary -to request transactions for the bank account via the bank connection. +.. FIXME :ref:`libeufin-nexus <libeufin-nexus>` is an implementation of the Wire Gateway API for the EBICS protocol. Add to list above once nexus implements the TWG directly! -This command asks Nexus to download the latest transaction reports/statements -through the bank connection: +Before continuing, you need to decide which wire gateway you want to use, +and install and configure it on your system. Afterwards, you need to +have two key pieces of information from that setup: -.. code-block:: console - - [root@exchange-online]# libeufin-cli accounts fetch-transactions $LOCAL_ACCOUNT_NAME - -.. note:: - - By default, the latest available transactions are fetched. It is also - possible to specify a custom date range (or even all available transactions) - and the type of transactions to fetch (inter-day statements or intra-day - reports). - -.. - FIXME: Possibly the date range filter is still missing, see #6243. - -Once Nexus has stored all the information in the database, the -client can ask to actually see the transactions: - -.. code-block:: console + * The username and password to access the exchange's account in the system. + * The ``payto://`` URI of that account (see `RFC 8905 <https://www.rfc-editor.org/rfc/rfc8905>`_). - [root@exchange-online]# libeufin-cli accounts transactions $LOCAL_ACCOUNT_NAME - -Testing: Making payments -^^^^^^^^^^^^^^^^^^^^^^^^ - -Payments pass through two phases: preparation and submission. The preparation -phase assigns the payment initiation a unique ID, which prevents accidental -double submissions of payments in case of network failures or other -disruptions. - - -The following command prepares a payment: - -.. code-block:: console - - [root@exchange-online]# libeufin-cli accounts prepare-payment \ - --creditor-iban=$IBAN_TO_SEND_MONEY_TO \ - --creditor-bic=$BIC_TO_SEND_MONEY_TO \ - --creditor-name=$CREDITOR_NAME \ - --payment-amount=$AMOUNT \ - --payment-subject=$SUBJECT \ - $LOCAL_ACCOUNT_NAME - -Note: the ``$AMOUNT`` value needs the format ``X.Y:CURRENCY``; for example -``EUR:10``, or ``EUR:1.01``. - -The previous command should return a value (``$UUID``) that uniquely -identifies the prepared payment in the Nexus system. That is needed -in the next step, to **send the payment instructions to the bank**: - -.. code-block:: console - - [root@exchange-online]# libeufin-cli accounts submit-payments \ - --payment-uuid $UUID \ - $LOCAL_ACCOUNT_NAME - -Automatic scheduling -^^^^^^^^^^^^^^^^^^^^ - -With an EBICS bank connection, the LibEuFin Nexus needs to regularly query for -new transactions and (re-)submit prepared payments. - -It is possible to schedule these tasks via an external task scheduler such as -cron(8). However, the nexus also has an internal task scheduling mechanism for -accounts. - - -The following three commands create a schedule for submitting payments hourly, -fetching transactions (intra-day reports) every 5 minutes, and (inter-day statements) -once at 11pm every day: - -.. code-block:: console - - [root@exchange-online]# libeufin-cli accounts task-schedule $LOCAL_ACCOUNT_NAME \ - --task-type="submit" \ - --task-name='submit-payments-hourly' \ - --task-cronspec='0 0 *' - - [root@exchange-online]# libeufin-cli accounts task-schedule $LOCAL_ACCOUNT_NAME \ - --task-type="fetch" \ - --task-name='fetch-5min' \ - --task-cronspec='0 */5 *' \ - --task-param-level=report \ - --task-param-range-type=latest - - [root@exchange-online]# libeufin-cli accounts task-schedule $LOCAL_ACCOUNT_NAME \ - --task-type="fetch" \ - --task-name='fetch-daily' \ - --task-cronspec='0 0 23' \ - --task-param-level=statement \ - --task-param-range-type=latest - -The cronspec has the following format, which is slightly non-standard due to -the ``SECONDS`` field - -.. code-block:: none - - SECONDS MINUTES HOURS DAY-OF-MONTH[optional] MONTH[optional] DAY-OF-WEEK[optional] - - -Creating a Taler facade -^^^^^^^^^^^^^^^^^^^^^^^ - -Facades are additional abstraction layers that can serve -specific purposes. For example, one application might need -a filtered version of the transaction history, or it might -want to refuse payments that do not conform to certain rules. - -At this moment, only the *Taler facade type* is implemented -in the Nexus, and the command below instantiates one under a -existing bank account / connection pair. You can freely -assign an identifier for the ``$FACADE_NAME`` below: - -.. code-block:: console - - [root@exchange-online]# libeufin-cli facades new-taler-wire-gateway-facade \ - --currency EUR \ - --facade-name $FACADE_NAME \ - $CONNECTION_NAME \ - $LOCAL_ACCOUNT_NAME - -At this point, the additional :doc:`taler-wire-gateway API <core/api-bank-wire>` -becomes offered by the Nexus. The purpose is to let a Taler exchange rely on -Nexus to manage its bank account. - -The base URL of the facade that can be used by the Taler exchange -as the Taler Wire Gateway base URL can be seen by listing the facades: - -.. code-block:: console - - [root@exchange-online]# libeufin-cli facades list - -Managing Permissions and Users -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -This guide has so far assumed that a superuser is accessing the LibEuFin Nexus. -However, it is advisable that the Nexus is accessed with users that only have a -minimal set of permissions. - -The Nexus currently only has support for giving non-superusers access to Taler -wire gateway facades. - -To create a new user, use the ``users`` subcommand of the CLI: - -.. code-block:: console - - [root@exchange-online]# libeufin-cli users list - # [ ... shows available users ... ] - - [root@exchange-online]# libeufin-cli users create $USERNAME - # [ ... will prompt for password ... ] - -Permissions are managed with the ``permissions`` subcommand. -The following commands grant permissions to view the transaction history -and create payment initiations with a Taler wire gateway facade: - - -.. code-block:: console - - [root@exchange-online]# libeufin-cli permissions grant \ - user $USERNAME \ - facade $FACADENAME \ - facade.talerwiregateway.history - - [root@exchange-online]# libeufin-cli permissions grant \ - user $USERNAME \ - facade $FACADENAME \ - facade.talerwiregateway.transfer - -.. - FIXME: The two commands above output an empty JSON object - when successful. Possibly, we should suppress that (just like - the other commands do). - -The list of all granted permissions can be reviewed: - -.. code-block:: console - - [root@exchange-online]# libeufin-cli permissions list - - -.. _Bank-account: +.. _exchange-bank-account-configuration: Exchange Bank Account Configuration ----------------------------------- An exchange must be configured with the right settings to access its bank -account via a Taler Wire Gateway. An exchange can be configured to use -multiple bank accounts by using multiple Wire Gateways. Typically only one -Wire Gateway is used. +account via a :ref:`Taler wire gateway <taler-wire-gateway-http-api>`. An +exchange can be configured to use multiple bank accounts by using multiple +wire gateways. Typically only one wire gateway is used. To configure a bank account in Taler, we need to furnish two pieces of information: @@ -1206,8 +864,8 @@ information: an IBAN or ``payto://x-taler-bank/localhost:8080/2`` for the 2nd bank account a the Taler bank demonstrator running at ``localhost`` on port 8080. - The first part of the URI following ``payto://`` (“iban” or - “x-taler-bank”) is called the wire method. + The first part of the URI following ``payto://`` (``iban`` or + ``x-taler-bank``) is called the wire method. - The ``taler-exchange-wirewatch`` and ``taler-exchange-transfer`` tools needs to be provided resources for authentication @@ -1216,20 +874,22 @@ information: for HTTP basic authentication. -A Taler Wire Gateway is configured in a configuration section that follows the -pattern ``exchange-account-$id``, where ``$id`` is an internal identifier for -the bank account accessed by the exchange. The basic information for an +Each Taler wire gateway is configured in a configuration section that follows +the pattern ``exchange-account-$id``, where ``$id`` is an internal identifier +for the bank account accessed by the exchange. The basic information for an account should be put in ``/etc/taler/conf.d/exchange-business.conf``. The secret credentials to access the Taler Wire Gateway API should be put into a corresponding ``exchange-accountcredentials-$id`` section in ``/etc/taler/secrets/exchange-accountcredentials.conf``. The latter file -should already be only readable for the ``taler-exchange-wire`` user. Other -exchange processes should not have access to this information. +should be only readable for the ``taler-exchange-wire`` user. Only the +``taler-exchange-wirewatch`` and ``taler-exchange-transfer`` services should +run as the ``taler-exchange-wire`` user. Other exchange processes do not need +to have access to the account credentials. You can configure multiple accounts for an exchange by creating sections -starting with “exchange-account-” for the section name. You can ENABLE for -each account whether it should be used, and for what (incoming or outgoing -wire transfers): +starting with ``exchange-account-`` for the section name. You must specify +``ENABLE_``-settings for each account whether it should be used, and for what +(incoming or outgoing wire transfers): .. code-block:: ini :caption: /etc/taler/conf.d/exchange-business.conf @@ -1264,15 +924,15 @@ wire transfers): # LibEuFin expects basic auth. WIRE_GATEWAY_AUTH_METHOD = basic - # Username and password set in LibEuFin. + # Username and password to access the Taler wire gateway. USERNAME = ... PASSWORD = ... - # Base URL of the wire gateway set up with LibEuFin. + # Base URL of the Taler wire gateway. WIRE_GATEWAY_URL = ... -Such a Wire Gateway configuration can be tested with the following commands: +Such a wire gateway configuration can be tested with the following commands: .. code-block:: shell-session @@ -1281,7 +941,8 @@ Such a Wire Gateway configuration can be tested with the following commands: [root@exchange-online]# taler-exchange-wire-gateway-client \ --section exchange-accountcredentials-1 --credit-history - +On success, you will see some of your account's transaction history (or an +empty history), while on failure you should see an error message. .. _LegalSetup: @@ -1300,7 +961,7 @@ Legal conditions for using the service KYC Configuration ------------------ +================= To legally operate, Taler exchange operators may have to comply with KYC regulation that requires financial institutions to identify parties involved @@ -1312,11 +973,20 @@ Taler permits an exchange to require KYC data under the following circumstances: * Wallet receives (via refunds) money resulting in a balance over a threshold * Wallet receives money via P2P payments over a threshold * Merchant receives money over a threshold - * Reserve is "opened" for invoicing or rewards (**planned feature**) + * Reserve is "opened" for invoicing (**planned feature**) + +Any of the above requests can trigger the KYC process, +which can be illustrated as follows: + +.. image:: kyc-process.png + +At the end of the KYC process, the wallet re-tries the +original request, and assuming KYC was successful, the +request should then succeed. Taler KYC Terminology -^^^^^^^^^^^^^^^^^^^^^ +--------------------- * **Check**: A check establishes a particular attribute of a user, such as their name based on an ID document and lifeness, mailing address, phone @@ -1355,7 +1025,7 @@ Taler KYC Terminology KYC Configuration Options -^^^^^^^^^^^^^^^^^^^^^^^^^ +------------------------- The KYC configuration determines the *legitimization rules*, and specifies which providers offer which *checks* at what *cost*. @@ -1412,7 +1082,7 @@ per configuration section: OAuth 2.0 specifics -^^^^^^^^^^^^^^^^^^^ +------------------- In terms of configuration, the OAuth 2.0 logic requires the respective client credentials to be configured apriori to enable access to the legitimization @@ -1443,11 +1113,15 @@ service. The OAuth 2.0 configuration options are: # Mustach template that converts OAuth2.0 data about the user # into GNU Taler standardized attribute data. - # - KYC_OAUTH2_ATTRIBUTE_TEMPLATE = "{"fullname":"{{last_name}}, {{first_name}}","phone":"{{phone}}"}" + KYC_OAUTH2_CONVERTER_HELPER = taler-exchange-kyc-oauth2-challenger.sh -The ``KYC_OAUTH2_ATTRIBUTE_TEMPLATE`` provides a generic way to convert data -returned by an OAuth-provider into the internal format used by the exchange. +The converter helper is expected to be customized to the selected OAuth2.0 +service: different services may return different details about the user or +business, hence there cannot be a universal converter for all purposes. The +default shell script uses the ``jq`` tool to convert the JSON returned by the +service into the KYC attributes (also in JSON) expected by the exchange. The +script will need to be adjusted based on the attributes collected by the +specific backend. The Challenger service for address validation supports OAuth2.0, but does not have a static AUTHORIZE_URL. Instead, the AUTHORIZE_URL must be enabled by the client @@ -1475,15 +1149,20 @@ configuration above and an exchange running on the host Persona specifics -^^^^^^^^^^^^^^^^^ +----------------- We use the hosted flow. The Persona endpoints return a ``request-id``, which we log for diagnosis. Persona should be configured to use the ``/kyc-webhook/`` endpoint of the -exchange to notify the exchange about the completion of KYC processes. -The webhook is authenticated using a shared secret, which should -be in the configuration. +exchange to notify the exchange about the completion of KYC processes. The +webhook is authenticated using a shared secret, which should be in the +configuration. To use the Persona webhook, you must set the webhook URL in +the Persona service to ``$EXCHANGE_BASE_URL/kyc-webhook/$SECTION_NAME/`` where +``$SECTION_NAME`` is the name of the configuration section. You should also +extract the authentication token for the webhook and put it into the +configuration as shown above. + .. code-block:: ini :caption: /etc/taler/conf.d/exchange-persona.conf @@ -1503,29 +1182,31 @@ be in the configuration. # Which subdomain is used for our API? KYC_PERSONA_SUBDOMAIN = taler - # Helper to convert JSON with KYC data returned by Persona into GNU Taler - # internal format. Should probably always be set to - # "taler-exchange-kyc-persona-converter.sh". - KYC_PERSONA_CONVERTER_HELPER = "taler-exchange-kyc-persona-converter.sh" - # Authentication token to use. - KYC_PERSONA_AUTH_TOKEN = persona_sandbox_42 + KYC_PERSONA_AUTH_TOKEN = persona_sandbox_42XXXX # Form to use. KYC_PERSONA_TEMPLATE_ID = itempl_Uj6Xxxxx # Where do we redirect to after KYC finished successfully. - KYC_PERSONA_POST_URL = "https://taler.net/" + KYC_PERSONA_POST_URL = "https://taler.net/kyc-done" # Salt to give to requests for idempotency. # Optional. # KYC_PERSONA_SALT = salt -To use the Persona webhook, you must set the webhook URL in the -Persona service to ``$EXCHANGE_BASE_URL/kyc-webhook/$SECTION_NAME/`` -where ``$SECTION_NAME`` is the name of the configuration section. -You should also extract the authentication token for the webhook -and put it into the configuration as shown above. + # Helper to convert JSON with KYC data returned by Persona into GNU Taler + # internal format. Should probably always be set to some variant of + # "taler-exchange-kyc-persona-converter.sh". + KYC_PERSONA_CONVERTER_HELPER = "taler-exchange-kyc-persona-converter.sh" + +The converter helper is expected to be customized to the +selected template: different templates may return different details +about the user or business, hence there cannot be a universal converter +for all purposes. The default shell script uses the ``jq`` tool to +convert the JSON returned by Persona into the KYC attributes (also +in JSON) expected by the exchange. The script will need to be adjusted +based on the attributes collected by the specific template. KYC AID specifics @@ -1533,8 +1214,8 @@ KYC AID specifics We use the hosted flow. -KYCAID should be configured to use the ``/kyc-webhook/`` endpoint of the -exchange to notify the exchange about the completion of KYC processes. +KYCAID must be configured to use the ``/kyc-webhook/$SECTION_NAME/`` endpoint +of the exchange to notify the exchange about the completion of KYC processes. .. code-block:: ini :caption: /etc/taler/conf.d/exchange-kycaid.conf @@ -1553,7 +1234,19 @@ exchange to notify the exchange about the completion of KYC processes. KYC_KYCAID_FORM_ID = XXX # URL to go to after the process is complete. - KYC_KYCAID_POST_URL = "https://taler.net/" + KYC_KYCAID_POST_URL = "https://taler.net/kyc-done" + + # Script to convert the KYCAID data into the Taler format. + KYC_KYCAID_CONVERTER_HELPER = taler-exchange-kyc-kycaid-converter.sh + + +The converter helper is expected to be customized to the selected template: +different templates may return different details about the user or business, +hence there cannot be a universal converter for all purposes. The default +shell script uses the ``jq`` tool to convert the JSON returned by Persona into +the KYC attributes (also in JSON) expected by the exchange. The script will +need to be adjusted based on the attributes collected by the specific +template. .. _Deployment: @@ -1695,7 +1388,7 @@ started using a simple command: At this point, the exchange service is not yet fully operational. -To check whether the exchange is running correctly under the advertized +To check whether the exchange is running correctly under the advertised base URL, run: .. code-block:: shell-session @@ -1790,6 +1483,8 @@ periodically, as it signs the various online signing keys of the exchange which periodically expire. +.. _exchange-account-signing: + Account signing --------------- @@ -1798,7 +1493,7 @@ The ``enable-account`` step is important to must be used to sign the correct address to wire funds to. Note that for each bank account, additional options **must** be set in the configuration file to tell the exchange how to access the bank account. The offline tool *only* configures the externally -visible portions of the setup. The chapter on `Bank account <_Bank-account>`_ configuration has further details. +visible portions of the setup. The chapter on `bank account configuration <_exchange-bank-account-configuration>`_ has further details. taler-exchange-offline accepts additional options to configure the use of the account. For example, additional options can be used to add currency @@ -1907,7 +1602,7 @@ of ``taler-exchange-offline``. operation. AML Configuration ------------------ +================= The AML configuration steps are used to add or remove keys of exchange operator staff that are responsible for anti-money laundering (AML) @@ -1918,7 +1613,7 @@ request additional KYC data from the consumer and can change the threshold amount above which a further AML review is triggered. AML Officer Setup -^^^^^^^^^^^^^^^^^ +----------------- To begin the AML setup, AML staff should launch the GNU Taler exchange AML SPA Web interface. (FIXME-Sebastian: how?). The @@ -1953,7 +1648,7 @@ Access rights can be revoked at any time using: AML Triggers -^^^^^^^^^^^^ +------------ AML decision processes are automatically triggered under certain configurable conditions. The primary condition that *must* be configured is the @@ -1984,10 +1679,49 @@ makes the decision given the KYC attributes: The given program will be given the KYC attributes in JSON format on standard input, and must return 0 to continue without AML and non-zero to flag the -account for manual review. To disable this triger, simply leave the option to +account for manual review. To disable this trigger, simply leave the option to its default value of '[/usr/bin/]true'. To flag all new users for manual review, simply set the program to '[/usr/bin/]false'. +AML Forms +--------- + +AML forms are defined by the DD 54 dynamic forms. +The shipped implementation with of the exchange is installed in + +.. code-block:: shell-session + + ${INSTALL_PREFIX}/share/taler/exchange/spa/forms.js + + +The variable ``form`` contains the list of all form available. For +every entry in the list the next properties are expected to be present: + +``label``: used in the UI as the name of the form + +``id``: identification name, this will be saved in the exchange database +along with the values to correctly render the form again. +It should simple, short and without any character outside numbers, +letters and underscore. + +``version``: when editing a form, instead of just replacing fields +it will be better to create a new form with the same id and new version. +That way old forms in the database will used old definition of the form. +It should be a number. + +``impl`` : a function that returns the design and behavior of form. +See DD 54 dynamic forms. + +.. attention:: + + do not remove a form the list if it has been used. Otherwise you + won't be able to see the information save in the exchange database. + +To add a new one you can simply copy and paste one element, and edit it. + +It is much easier to download ``@gnu-taler/aml-backoffice-ui`` source +from ``https://git.taler.net/wallet-core.git/``, compile and copy the file +from the ``dist/prod``. Setup Linting @@ -2104,6 +1838,13 @@ After enough time has passed, the money should arrive at the specified IBAN. For more information on the taler-wallet-cli tool, see :doc:`taler-wallet`. +taler-config +------------ + +.. _Using-taler_002dconfig-exchange: + +.. include:: frags/using-taler-config.rst + Private key storage ------------------- @@ -2201,6 +1942,323 @@ grant the permissions to the other exchange processes again. +.. _ExchangeTemplateCustomization: + +Template Customization +====================== + +The Exchange comes with various HTML templates that are shown to +guide users through the KYC process. The Exchange uses `Mustach +<https://gitlab.com/jbol/mustach>`__ as the templating engine. This section +describes the various templates. In general, the templates must be installed +to the ``share/taler/exchange/templates/`` directory. The file names must be of +the form ``$NAME.$LANG.must`` where ``$NAME`` is the name of the template and +``$LANG`` is the 2-letter language code of the template. English templates +must exist and will be used as a fallback. If the browser (user-agent) has +provided language preferences in the HTTP header and the respective language +exists, the correct language will be automatically served. + +The following subsections give details about each of the templates. Most +subsection titles are the ``$NAME`` of the respective template. + + +Generic Errors Templates +------------------------ + +A number of templates are used for generic errors. These are: + + * kyc-proof-already-done (KYC process already completed) + * kyc-bad-request (400 Bad Request) + * kyc-proof-endpoint-unknown (404 Not Found for KYC logic) + * kyc-proof-internal-error (500 Internal Server Error) + * kyc-proof-target-unknown (404 Not Found for KYC operation) + +All of these templates are instantiated using the following information: + + * ec: Integer; numeric Taler error code, should be shown to indicate the + error compactly for reporting to developers + + * hint: String; human-readable Taler error code, should be shown for the + user to understand the error + + * message: String; optional, extended human-readable text provided to elaborate + on the error, should be shown to provide additional context + + +kycaid-invalid-request +---------------------- + +The KYCaid plugin does not support requests to the +``/kyc-proof/`` endpoint (HTTP 400 bad request). + +This template is instantiated using the following information: + + * ec: Integer; numeric Taler error code, should be shown to indicate the + error compactly for reporting to developers + + * hint: String; human-readable Taler error code, should be shown for the + user to understand the error + + * error: String; error code from the server + + * error_details: String; optional error description from the server + + * error_uri: optional URI with further details about the error from the server + + + +oauth2-authentication-failure +----------------------------- + +The OAuth2 server said that the request was not +properly authenticated (HTTP 403 Forbidden). + + +This template is instantiated using the following information: + + * ec: Integer; numeric Taler error code, should be shown to indicate the + error compactly for reporting to developers + + * hint: String; human-readable Taler error code, should be shown for the + user to understand the error + + +oauth2-authorization-failure +---------------------------- + +The OAuth2 server refused to return the KYC data +because the authorization code provided was +invalid (HTTP 403 Forbidden). + +This template is instantiated using the following information: + + * ec: Integer; numeric Taler error code, should be shown to indicate the + error compactly for reporting to developers + + * hint: String; human-readable Taler error code, should be shown for the + user to understand the error + + * error: String; error code from the server + + * error_message: String; error message from the server + + +oauth2-authorization-failure-malformed +-------------------------------------- + +The server refused the authorization, but then provided +a malformed response (HTTP 502 Bad Gateway). + +This template is instantiated using the following information: + + * ec: Integer; numeric Taler error code, should be shown to indicate the + error compactly for reporting to developers + + * hint: String; human-readable Taler error code, should be shown for the + user to understand the error + + * debug: Bool; true if we are running in debug mode and are allowed to return HTML with potentially sensitive information + + * server_response: Object; could be NULL; this includes the (malformed) OAuth2 server response, it should be shown to the use if "debug" is true + + +oauth2-bad-request +------------------ + +The client made an invalid request (HTTP 400 Bad Request). + +This template is instantiated using the following information: + + * ec: Integer; numeric Taler error code, should be shown to indicate the + error compactly for reporting to developers + + * hint: String; human-readable Taler error code, should be shown for the + user to understand the error + + * message: String; additional error message elaborating on what was bad about the request + + +oauth2-conversion-failure +------------------------- + +Converting the KYC data into the exchange's internal +format failed (HTTP 502 Bad Gateway). + +This template is instantiated using the following information: + + * ec: Integer; numeric Taler error code, should be shown to indicate the + error compactly for reporting to developers + + * hint: String; human-readable Taler error code, should be shown for the + user to understand the error + + * debug: Bool; true if we are running in debug mode and are allowed to return HTML with potentially sensitive information + + * converter: String; name of the conversion command that failed which was used by the Exchange + + * attributes: Object; attributes returned by the conversion command, often NULL (after all, conversion failed) + + * message: error message elaborating on the conversion failure + + +oauth2-provider-failure +----------------------- + +We did not get an acceptable response from the OAuth2 +provider (HTTP 502 Bad Gateway). + +This template is instantiated using the following information: + + * ec: Integer; numeric Taler error code, should be shown to indicate the + error compactly for reporting to developers + + * hint: String; human-readable Taler error code, should be shown for the + user to understand the error + + * message: String; could be NULL; text elaborating on the details of the failure + + +persona-exchange-unauthorized +----------------------------- + +The Persona server refused our request (HTTP 403 Forbidden from Persona, returned as a HTTP 502 Bad Gateway). + +This template is instantiated using the following information: + + * ec: Integer; numeric Taler error code, should be shown to indicate the + error compactly for reporting to developers + + * hint: String; human-readable Taler error code, should be shown for the + user to understand the error + + * data: Object; data returned from Persona service, optional + + * persona_http_status: Integer; HTTP status code returned by Persona + + +persona-load-failure +-------------------- + +The Persona server refused our request (HTTP 429 Too Many Requests from Persona, returned as a HTTP 503 Service Unavailable). + +This template is instantiated using the following information: + + * ec: Integer; numeric Taler error code, should be shown to indicate the + error compactly for reporting to developers + + * hint: String; human-readable Taler error code, should be shown for the + user to understand the error + + * data: Object; data returned from Persona service, optional + + * persona_http_status: Integer; HTTP status code returned by Persona + + +persona-exchange-unpaid +----------------------- + +The Persona server refused our request (HTTP 402 Payment REquired from Persona, returned as a HTTP 503 Service Unavailable). + +This template is instantiated using the following information: + + * ec: Integer; numeric Taler error code, should be shown to indicate the + error compactly for reporting to developers + + * hint: String; human-readable Taler error code, should be shown for the + user to understand the error + + * data: Object; data returned from Persona service, optional + + * persona_http_status: Integer; HTTP status code returned by Persona + + + +persona-logic-failure +--------------------- + +The Persona server refused our request (HTTP 400, 403, 409, 422 from Persona, returned as a HTTP 502 Bad Gateway). + +This template is instantiated using the following information: + + * ec: Integer; numeric Taler error code, should be shown to indicate the + error compactly for reporting to developers + + * hint: String; human-readable Taler error code, should be shown for the + user to understand the error + + * data: Object; data returned from Persona service, optional + + * persona_http_status: Integer; HTTP status code returned by Persona + + +persona-invalid-response +------------------------ + +The Persona server refused our request in an +unexpected way; returned as a HTTP 502 Bad Gateway. + +This template is instantiated using the following information: + + * ec: Integer; numeric Taler error code, should be shown to indicate the + error compactly for reporting to developers + + * hint: String; human-readable Taler error code, should be shown for the + user to understand the error + + * debug: Bool; true if we are running in debug mode and are allowed to return HTML with potentially sensitive information + + * server_response: Object; could be NULL; this includes the (malformed) OAuth2 server response, it should be shown to the use if "debug" is true + + +persona-network-timeout +----------------------- + +The Persona server refused our request (HTTP 408 from Persona, returned as a HTTP 504 Gateway Timeout). + +This template is instantiated using the following information: + + * ec: Integer; numeric Taler error code, should be shown to indicate the + error compactly for reporting to developers + + * hint: String; human-readable Taler error code, should be shown for the + user to understand the error + + * data: Object; data returned from Persona service, optional + + * persona_http_status: Integer; HTTP status code returned by Persona + + +persona-kyc-failed +------------------ + +The Persona server indicated a problem with the KYC process, saying it was not completed. + +This template is instantiated using the following information: + + * persona_inquiry_id: String; internal ID of the inquiry within Persona, useful for further diagnostics by staff + + * data: Object; could be NULL; this includes the server response, it contains extensive diagnostics, see Persona documentation on their ``/api/v1/inquiries/$ID``. + + * persona_http_status: Integer; HTTP status code returned by Persona + +persona-provider-failure +------------------------ + +The Persona server refused our request (HTTP 500 from Persona, returned as a HTTP 502 Bad Gateway). + +This template is instantiated using the following information: + + * ec: Integer; numeric Taler error code, should be shown to indicate the + error compactly for reporting to developers + + * hint: String; human-readable Taler error code, should be shown for the + user to understand the error + + * data: Object; data returned from Persona service, optional + + * persona_http_status: Integer; HTTP status code returned by Persona + + .. _ExchangeBenchmarking: Benchmarking |