taler-docs

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

taler-kyc-manual.rst (53372B)


      1 ..
      2   This file is part of GNU TALER.
      3 
      4   Copyright (C) 2014-2025 Taler Systems SA
      5 
      6   TALER is free software; you can redistribute it and/or modify it under the
      7   terms of the GNU Affero General Public License as published by the Free Software
      8   Foundation; either version 2.1, or (at your option) any later version.
      9 
     10   TALER is distributed in the hope that it will be useful, but WITHOUT ANY
     11   WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
     12   A PARTICULAR PURPOSE.  See the GNU Affero General Public License for more details.
     13 
     14   You should have received a copy of the GNU Affero General Public License along with
     15   TALER; see the file COPYING.  If not, see <http://www.gnu.org/licenses/>
     16 
     17   @author Christian Grothoff
     18   @author Florian Dold
     19 
     20 .. _KycOperatorManual:
     21 
     22 Exchange KYC/AML Operator Manual
     23 ################################
     24 
     25 Introduction
     26 ============
     27 
     28 About GNU Taler
     29 ---------------
     30 
     31 .. include:: frags/about-taler.rst
     32 
     33 
     34 About this manual
     35 -----------------
     36 
     37 This chapter describes how to setup certain compliance aspects of a GNU Taler
     38 exchange. Users that just want to set up an exchange as an experiment without
     39 legal or regulatory requirements can safely skip this chapter.
     40 
     41 This manual targets compliance experts working with system administrators and
     42 developers to configure legitimization (KYC/KYB) and anti-money laundering
     43 (AML) processes for a GNU Taler exchange.  Expertise in all three domains is
     44 required, as Taler's KYC and AML processes are highly configurable and
     45 programmable.
     46 
     47 
     48 
     49 Legal conditions for using the service
     50 --------------------------------------
     51 
     52 .. include:: frags/legal.rst
     53 
     54 
     55 Know-Your-Customer Setup
     56 ========================
     57 
     58 To legally operate, Taler exchange operators may have to comply with KYC
     59 regulation that requires financial institutions to identify parties involved
     60 in transactions at certain points.
     61 
     62 Taler permits an exchange to require know-your-customer (KYC) or
     63 know-your-business (KYB) data under the following circumstances:
     64 
     65   * Customer withdraws money over a threshold
     66   * Wallet receives (via refunds) money resulting in a balance over a threshold
     67   * Wallet receives money via P2P payments over a threshold
     68   * Merchant receives money over a threshold
     69   * Merchant deposits digital cash over a threshold (**planned feature, bug 9040**)
     70   * Reserve is "opened" for invoicing (**planned feature**)
     71 
     72 Any of the above requests can trigger the KYC process,
     73 which can be illustrated as follows:
     74 
     75 .. image:: images/kyc-process.png
     76 
     77 At the end of the KYC process, the wallet re-tries the
     78 original request, and assuming KYC was successful, the
     79 request should then succeed.
     80 
     81 
     82 KYC Terminology
     83 ---------------
     84 
     85 * **Attributes**: Attributes are used to represent KYC data obtained about
     86   an account holder. Attributes include passport images, address data,
     87   business registration documents, and indeed arbitrary forms filed by
     88   AML staff or the customer themselves.  Attribute data is considered
     89   sensitive private information and is thus stored encrypted within the
     90   exchange database.
     91 
     92 * **Check**: A check establishes a particular attribute of a user, such as
     93   their name based on an ID document and lifeness, mailing address, phone
     94   number, taxpayer identity, etc.  Checks may be given *context* (such as
     95   whether a customer is an individual or a business) to run correctly. Checks
     96   can also be AML staff inserting information for plausibilization.  Checks
     97   result in *attributes* about the account's owner which are given to an
     98   external AML *program* together with the *context* to determine an *outcome*.
     99   KYC checks are always specified with a fallback *measure* to be taken if
    100   the check fails.
    101 
    102 * **Condition**: A condition specifies when KYC is required. Conditions
    103   include the *type of operation*, a threshold amount (e.g. above EUR:1000)
    104   and possibly a time period (e.g. over the last month).
    105 
    106 * **Configuration**: The configuration determines the *legitimization rules*,
    107   and specifies which providers offer which *checks*.
    108 
    109 * **Context**: Context is information provided as input into a *check* and
    110   *program* to customize their execution. The context is initially set by the
    111   *measure* (possibly including data from the *trigger*).  Naturally, the
    112   *program* may use its `AmlProgramInput` which includes *context* and
    113   *attribute* data to compute an update *context* for the next set of
    114   *measures* that it specifies in the `LegitimizationRuleSet` as part
    115   of the `AmlOutcome`.  Thus, *context* is something that typically
    116   evolves as the *account* undergoes *measures*.  Context is lost if
    117   an account transitions to default *legitimization rules* due to
    118   *expiration*.
    119 
    120 * **Decision**: AML decisions are these as taken by AML officers (humans). AML
    121   outcomes are the results of AML programs (code). Legitimization outcomes (DB
    122   table) can arise from either.
    123 
    124 * **Display priority**: Every rule has a *display priority*. If a second
    125   *rule* is *triggered* before the *outcome* of a *rule* could be determined,
    126   the *rule* with the larger *display priority* becomes the requirement that
    127   the account owner has to satisfy (and that thus will be displayed by the
    128   KYC SPA).
    129 
    130 * **Expiration**: Except for the default rules, any set of KYC rules is
    131   subject to *expiration*. This can be because *attributes* become outdated or
    132   because sanctions have a time limit. The expiration time thus determines
    133   when a new *measure* is triggered in the absence of a transaction crossing
    134   thresholds in the current set of *legtimization rules*.
    135 
    136 * **Legitimization rules**: The *legitimization rules* determine under which
    137   *conditions* which *measures* will be taken. A `LegitimizationRuleSet`
    138   always also includes an *expiration* time period for (custom, non-default)
    139   *legitimization rules* after which a fallback measure* will automatically
    140   apply.  Legitimization rules may be *exposed* to the client (for example,
    141   to allow a wallet to stay below hard withdraw thresholds) or could be secret.
    142 
    143 * **Logic**: Logic refers to a specific bit of code (realized as an exchange
    144   plugin) that enables the interaction with a specific *provider*.  Logic
    145   typically requires *configuration* for access control (such as an
    146   authorization token) and possibly the endpoint of the specific *provider*
    147   implementing the respective API.
    148 
    149 * **Measure**: Describes the possible outgoing edges from one state in the
    150   state machine (including how to show the current state). Each edge is given
    151   some *context* and a *check* to be performed as well as an AML *program*
    152   which determines the *outcome*.  We generally distinguish between
    153   "original" measures (defined globally in the exchange configuration) and
    154   "custom" measures (defined specifically for an account by AML staff).
    155   Additionally, only *origional* measures that have a *check* of type
    156   "SKIP" and that require no inputs can be used as *FALLBACK* measures.
    157 
    158 * **Outcome**: An `AmlOutcome` describes the account state that an account
    159   ends up in due to either an AML staff action or an AML *program* doing some
    160   computation over the attributes resulting from a *check*.  Outcomes can be
    161   that certain types of transactions are "verboten", that the account is (or
    162   remains) under investigation by AML staff, that the account is given certain
    163   properties, and/or that certain events are to be logged. Outcomes also
    164   include a new set of *legitimization rules* to apply (and an *expiration*
    165   time at which point a successor *measure* will be automatically taken).
    166 
    167 * **Provider**: A provider performs a specific set of *checks* at a certain
    168   *cost*. Interaction with a provider is performed by provider-specific
    169   *logic*.
    170 
    171 * **Program**: An AML helper *program* is given *context* about the current
    172   state of an account and the attribute data from a *check* to compute the
    173   *outcome*.  For example, a *program* may look at the "PEP" field of a KYC
    174   check and decide if the outcome is to put the account into ``normal`` or
    175   ``held-for-manual-review`` state.  AML programs are always specified
    176   with a fallback *measure* to be taken if the program fails.
    177 
    178 * **Trigger**: A specific transaction that satisfies a **Condition**.
    179 
    180 * **Type of operation**: The operation type determines which Taler-specific
    181   operation has triggered the KYC requirement. We support four types of
    182   operation: withdraw (by customer), deposit (by merchant),
    183   aggregate transfer (to merchant), P2P receive (by wallet) and
    184   (high) wallet balance.
    185 
    186 
    187 Configuration of possible KYC/AML providers
    188 -------------------------------------------
    189 
    190 The KYC configuration determines the *legitimization rules*, and specifies
    191 which providers offer which *checks*.
    192 
    193 The configuration specifies a set of providers, one per configuration
    194 section. The names of the configuration sections must being with
    195 ``kyc-proider-`` followed by an arbitrary ``$PROVIDER_ID``:
    196 
    197 .. code-block:: ini
    198   :caption: /etc/taler-exchange/conf.d/exchange-kyc-providers.conf
    199 
    200   [kyc-provider-$PROVIDER_ID]
    201 
    202   # Which plugin is responsible for this provider?
    203   # Choices include "oauth2", "kycaid" and "persona".
    204   LOGIC = oauth2
    205 
    206   # Plus additional logic-specific options, e.g.:
    207   AUTHORIZATION_TOKEN = superdupersecret
    208 
    209   # Other logic-specific internal options (example):
    210   FORM_ID = business_legi_form
    211 
    212 
    213 OAuth 2.0 specifics
    214 ^^^^^^^^^^^^^^^^^^^
    215 
    216 In terms of configuration, the OAuth 2.0 logic requires the respective client
    217 credentials to be configured apriori to enable access to the legitimization
    218 service.  The OAuth 2.0 configuration options are:
    219 
    220 .. code-block:: ini
    221   :caption: /etc/taler-exchange/conf.d/exchange-oauth2.conf
    222 
    223   [kyc-provider-example-oauth2]
    224   LOGIC = oauth2
    225   # (generic options omitted)
    226   # How long is the KYC check valid?
    227   KYC_OAUTH2_VALIDITY = forever
    228 
    229   # URL to which we redirect the user for the login process
    230   KYC_OAUTH2_AUTHORIZE_URL = "http://kyc.example.com/authorize"
    231   # URL where we POST the user's authentication information
    232   KYC_OAUTH2_TOKEN_URL = "http://kyc.example.com/token"
    233   # URL of the user info access point.
    234   KYC_OAUTH2_INFO_URL = "http://kyc.example.com/info"
    235 
    236   # Where does the client get redirected upon completion?
    237   KYC_OAUTH2_POST_URL = "http://example.com/thank-you"
    238 
    239   # For authentication to the OAuth2.0 service
    240   KYC_OAUTH2_CLIENT_ID = testcase
    241   KYC_OAUTH2_CLIENT_SECRET = password
    242 
    243   # Mustach template that converts OAuth2.0 data about the user
    244   # into GNU Taler standardized attribute data.
    245   KYC_OAUTH2_CONVERTER_HELPER = taler-exchange-kyc-oauth2-challenger.sh
    246 
    247 The converter helper is expected to be customized to the selected OAuth2.0
    248 service: different services may return different details about the user or
    249 business, hence there cannot be a universal converter for all purposes. The
    250 default shell script uses the ``jq`` tool to convert the JSON returned by the
    251 service into the KYC attributes (also in JSON) expected by the exchange.  The
    252 script will need to be adjusted based on the attributes collected by the
    253 specific backend.
    254 
    255 The Challenger service for address validation supports OAuth2.0, but does not
    256 have a static AUTHORIZE_URL. Instead, the AUTHORIZE_URL must be enabled by the client
    257 using a special authenticated request to the Challenger's ``/setup`` endpoint.
    258 The exchange supports this by appending ``#setup`` to the AUTHORIZE_URL (note
    259 that fragments are illegal in OAuth2.0 URLs).  Be careful to quote the URL,
    260 as ``#`` is otherwise interpreted as the beginning of a comment by the
    261 configuration file syntax.
    262 
    263 .. code-block:: ini
    264   :caption: /etc/taler-exchange/conf.d/exchange-challenger-oauth2.conf
    265 
    266   [kyc-provider-challenger-oauth2]
    267   LOGIC = oauth2
    268   KYC_OAUTH2_AUTHORIZE_URL = "http://challenger.example.com/authorize/#setup"
    269   KYC_OAUTH2_TOKEN_URL = "http://challenger.example.com/token"
    270   KYC_OAUTH2_INFO_URL = "http://challenger.example.com/info"
    271 
    272 When using OAuth 2.0, the *CLIENT REDIRECT URI* must be set to the
    273 ``/kyc-proof/$PROVIDER_SECTION`` endpoint. For example, given the
    274 configuration above and an exchange running on the host
    275 ``exchange.example.com``, the redirect URI would be
    276 ``https://exchange.example.com/kyc-proof/kyc-provider-challenger-oauth2/``.
    277 
    278 Using the OAuth 2.0 logic with the ``/setup`` endpoint it is possible to
    279 pass Challenger the address to validate via the **context** of the KYC check.
    280 To do so, the *address type* specific address data must be provided in a
    281 field ``initial_address`` of the **context** object.
    282 
    283 
    284 Persona specifics
    285 ^^^^^^^^^^^^^^^^^
    286 
    287 We use the hosted flow. The Persona endpoints return a ``request-id``, which
    288 we log for diagnosis.
    289 
    290 Persona should be configured to use the ``/kyc-webhook/`` endpoint of the
    291 exchange to notify the exchange about the completion of KYC processes.  The
    292 webhook is authenticated using a shared secret, which should be in the
    293 configuration.  To use the Persona webhook, you must set the webhook URL in
    294 the Persona service to ``$EXCHANGE_BASE_URL/kyc-webhook/$SECTION_NAME/`` where
    295 ``$SECTION_NAME`` is the name of the configuration section.  You should also
    296 extract the authentication token for the webhook and put it into the
    297 configuration as shown above.
    298 
    299 
    300 .. code-block:: ini
    301   :caption: /etc/taler-exchange/conf.d/exchange-persona.conf
    302 
    303   [kyclogic-persona]
    304   # Webhook authorization token. Global for all uses
    305   # of the persona provider!
    306   WEBHOOK_AUTH_TOKEN = wbhsec_698b5a19-c790-47f6-b396-deb572ec82f9
    307 
    308   [kyc-provider-example-persona]
    309   LOGIC = persona
    310   # (generic options omitted)
    311 
    312   # How long is the KYC check valid?
    313   KYC_PERSONA_VALIDITY = 365d
    314 
    315   # Which subdomain is used for our API?
    316   KYC_PERSONA_SUBDOMAIN = taler
    317 
    318   # Authentication token to use.
    319   KYC_PERSONA_AUTH_TOKEN = persona_sandbox_42XXXX
    320 
    321   # Form to use.
    322   KYC_PERSONA_TEMPLATE_ID = itempl_Uj6Xxxxx
    323 
    324   # Where do we redirect to after KYC finished successfully.
    325   KYC_PERSONA_POST_URL = "https://taler.net/kyc-done"
    326 
    327   # Salt to give to requests for idempotency.
    328   # Optional.
    329   # KYC_PERSONA_SALT = salt
    330 
    331   # Helper to convert JSON with KYC data returned by Persona into GNU Taler
    332   # internal format. Should probably always be set to some variant of
    333   # "taler-exchange-kyc-persona-converter.sh".
    334   KYC_PERSONA_CONVERTER_HELPER = "taler-exchange-kyc-persona-converter.sh"
    335 
    336 The converter helper is expected to be customized to the
    337 selected template: different templates may return different details
    338 about the user or business, hence there cannot be a universal converter
    339 for all purposes. The default shell script uses the ``jq`` tool to
    340 convert the JSON returned by Persona into the KYC attributes (also
    341 in JSON) expected by the exchange.  The script will need to be adjusted
    342 based on the attributes collected by the specific template.
    343 
    344 
    345 KYC AID specifics
    346 ^^^^^^^^^^^^^^^^^
    347 
    348 We use the hosted flow.
    349 
    350 KYCAID must be configured to use the ``/kyc-webhook/$SECTION_NAME/`` endpoint
    351 of the exchange to notify the exchange about the completion of KYC processes.
    352 
    353 .. code-block:: ini
    354   :caption: /etc/taler-exchange/conf.d/exchange-kycaid.conf
    355 
    356   [kyc-provider-example-kycaid]
    357   LOGIC = kycaid
    358   # (generic options omitted)
    359 
    360   # How long is the KYC check valid?
    361   KYC_KYCAID_VALIDITY = 365d
    362 
    363   # Authentication token to use.
    364   KYC_KYCAID_AUTH_TOKEN = XXX
    365 
    366   # Form to use.
    367   KYC_KYCAID_FORM_ID = XXX
    368 
    369   # URL to go to after the process is complete.
    370   KYC_KYCAID_POST_URL = "https://taler.net/kyc-done"
    371 
    372   # Script to convert the KYCAID data into the Taler format.
    373   KYC_KYCAID_CONVERTER_HELPER = taler-exchange-kyc-kycaid-converter.sh
    374 
    375 
    376 The converter helper is expected to be customized to the selected template:
    377 different templates may return different details about the user or business,
    378 hence there cannot be a universal converter for all purposes. The default
    379 shell script uses the ``jq`` tool to convert the JSON returned by Persona into
    380 the KYC attributes (also in JSON) expected by the exchange.  The script will
    381 need to be adjusted based on the attributes collected by the specific
    382 template.
    383 
    384 
    385 Configuration of possible KYC/AML checks
    386 ----------------------------------------
    387 
    388 The configuration specifies a set of possible KYC checks offered by external
    389 providers, one per configuration section.  The names of the configuration
    390 sections must being with ``kyc-check-`` followed by an arbitrary
    391 ``$CHECK_NAME``.
    392 
    393 .. code-block:: ini
    394 
    395   [kyc-check-$CHECK_NAME]
    396 
    397   # Which type of check is this? Also determines
    398   # the SPA form to show to the user for this check.
    399   #
    400   # INFO: wait for staff or contact staff out-of band
    401   #          (only information shown, no SPA action)
    402   # FORM: SPA should show an inline (HTML) form
    403   # LINK: SPA may start external KYC process or upload
    404   #
    405   TYPE = INFO|LINK|FORM
    406 
    407   # Optional. Set to YES to allow this check be
    408   # done voluntarily by a client (they may then
    409   # still have to pay for it). Used to offer the
    410   # SPA to display checks even if they are
    411   # not required. Default is NO.
    412   # Since **vATTEST**.
    413   VOLUNTARY = YES/NO
    414 
    415   # Provider id, present only if type is LINK.
    416   # Refers to a ``kyc-provider-$PROVIDER_ID`` section.
    417   PROVIDER_ID = id
    418 
    419   # Name of the SPA form, if type is FORM
    420   # "INFO" and "LINK" are reserved and must not be used.
    421   # The exchange server and the SPA must agree on a list
    422   # of supported forms and the resulting attributes.
    423   #
    424   # The SPA should include a JSON resource file
    425   # "forms.json" mapping form names to arrays of
    426   # attribute names each form provides.
    427   FORM_NAME = name
    428 
    429   # Descriptions to use in the SPA to display the check.
    430   DESCRIPTION = "Upload your passport picture"
    431   DESCRIPTION_I18N = "{"en":"Upload scan of your passport"}"
    432 
    433   # ';'-separated list of fields that the CONTEXT must
    434   # provide as inputs to this check. For example,
    435   # for a FORM of type CHOICE, this might state
    436   # ``choices: string[];``. The type after the ":"
    437   # is for now purely for documentation and is
    438   # not checked. However, it may be shown to AML staff
    439   # when they configure measures.
    440   REQUIRES = requirement;
    441 
    442   # Description of the outputs provided by the check.
    443   # Basically, the check's output is expected to
    444   # provide the following fields as attribute inputs into
    445   # a subsequent AML program.
    446   # INFO never has any outputs.
    447   OUTPUTS = "business_name street city country registration"
    448 
    449   # **original** measure to take if the check fails
    450   # (for any reason, e.g. provider or form fail to
    451   # satisfy constraints or provider signals user error)
    452   # Usually should point to a measure that requests
    453   # AML staff to investigate.  The fallback measure
    454   # context always includes the reasons for the
    455   # failure.  Fallback measures MUST be *origional*
    456   # measures and MUST use a check of
    457   # type "SKIP" and MUST NOT require any inputs.
    458   FALLBACK = MEASURE_NAME
    459 
    460 The list of possible FORM names is fixed in the SPA
    461 for a particular exchange release.
    462 
    463 The "check_name" value "skip" is reserved and must not be defined. It can be
    464 used in measures where the AML program must be run immediately without any
    465 input.
    466 
    467 The outcome of *any* check is stored encrypted in the ``kyc_attributes``
    468 table.  It MUST include an ``expiration_time``.
    469 
    470 The INFO Type
    471 ^^^^^^^^^^^^^
    472 
    473 When using KYC checks of type "INFO", the KYC-SPA
    474 will simply show the given DESCRIPTION (or translations
    475 from DESCRIPTION_I18N) to the user.
    476 
    477 
    478 The FORM Type
    479 ^^^^^^^^^^^^^
    480 
    481 When using KYC checks of type "FORM", the KYC-SPA
    482 will show different forms based on "FORM_NAME" while
    483 also showing the user the text from DESCRIPTION
    484 as instructions.
    485 
    486 Some of the forms may be further parameterized via
    487 the context in which the form is executed.
    488 
    489 .. note::
    490 
    491   For build-in forms, it should in the future not be
    492   necessary to specify the context requirements via
    493   REQUIRES as the KYC SPA should inform the exchange
    494   about the requirements of each form automatically.
    495   However, this is not yet implemented, see #9187.
    496 
    497 When forms are submitted, the exchange converts the form data into key-value
    498 pairs where the key is the form field name and the value depends on
    499 the key.  The different keys are defined in the
    500 ``gnu-taler-form-attributes`` GANA registry.
    501 The respective AML program can then evaluate the data from the form
    502 submission from ``attributes``.
    503 
    504 
    505 The LINK Type
    506 ^^^^^^^^^^^^^
    507 
    508 When using KYC checks of type "FORM", the KYC-SPA will show a link that allows
    509 the user to begin the KYC process at an external provider under the given
    510 DESCRIPTION.
    511 
    512 The external providers are expected to yield KYC attributes in the form of
    513 key-value pairs where the list of key is defined in the GANA
    514 ``gnu-taler-kyc-attributes`` registry, which also defines the format of each
    515 attribute.  External providers may not directly yield attributes using the
    516 correct encodings, thus converter helper programs are typically used to convert
    517 external attribute data into the standardized format.
    518 
    519 
    520 Configuration of legitimization rules
    521 -------------------------------------
    522 
    523 The configuration also must specify a set of legitimization rules, one per
    524 configuration section. Each rule specifies the condition and the measure the
    525 condition triggers:
    526 
    527 .. code-block:: ini
    528 
    529   [kyc-rule-$RULE_NAME]
    530 
    531   # Operation that triggers this rule.
    532   # Must be one of AGGREGATE, BALANCE, CLOSE, DEPOSIT, MERGE,
    533   # REFUND, TRANSACTION or WITHDRAW
    534   OPERATION_TYPE = WITHDRAW
    535 
    536   # Space-separated list of next measures to be performed.
    537   # The SPA should display *all* of these measures to the user.
    538   # (They have a choice of either which ones, or in
    539   # which order they are to be performed.)
    540   # A special measure name "verboten" is used if the
    541   # specified threshold may never be crossed
    542   # (under this set of rules).
    543   NEXT_MEASURES = SWISSNESS KYB
    544 
    545   # "YES" if all NEXT_MEASURES will eventually need
    546   # to be satisfied, "NO" if the user has a choice between
    547   # them. Not actually enforced by the exchange, but
    548   # primarily used to inform the user whether this is
    549   # an "and" or "or". YES for "and".
    550   IS_AND_COMBINATOR = YES
    551 
    552   # YES if the rule (specifically, operation type,
    553   # threshold, timeframe) and the general nature of
    554   # the next measure (verboten or approval required)
    555   # should be exposed to the client.
    556   # Defaults to NO if not set.
    557   EXPOSED = YES
    558 
    559   # Threshold amount above which the rule is
    560   # triggered.  The total must be exceeded in the given
    561   # timeframe.
    562   THRESHOLD = KUDOS:100
    563 
    564   # Timeframe over which the amount to be compared to
    565   # the THRESHOLD is calculated.
    566   # Ignored for WALLET-BALANCE.  Can be 'forever'.
    567   TIMEFRAME = 30 days
    568 
    569   # Set to YES to enable the rule (default is NO)
    570   ENABLED = NO
    571 
    572 The operation types of KYC rules refer to the following scenarios:
    573 
    574   * **AGGREGATION**: Triggered when an exchange is about to do an
    575     wire transfer to a merchant. Such wire transfers typically have
    576     aggregated multiple smaller deposits, and thus enforcing KYC rules
    577     at aggregation time is more efficient than checking individual
    578     deposits. Plus, checking at the aggregation level is likely to
    579     render structuring inherently ineffective.
    580     Enforced by the exchange.
    581 
    582   * **BALANCE**: Triggered whenever the balance of a wallet is increased.
    583     Can only be used with a timeframe of zero, as this is about the absolute
    584     amount that can be stored at any time in a compliant wallet.
    585     Enforced by the wallet.
    586 
    587   * **CLOSE**: Triggered when a reserve is closed (explicitly by a wallet
    588     or implicitly by timeout). Use with caution, as this may prevent
    589     an exchange from returning funds that were not withdrawn to users.
    590     Enforced by the exchange.
    591     (Note: This rule is so far not used in production
    592     anywhere, thus likely not tested well yet.)
    593 
    594   * **DEPOSIT**: Sets a limit on the amount that can be deposited by
    595     a merchant into their bank account.  Can be used with a timeframe
    596     of zero to effectively set another transaction limit that additionally
    597     only applies to deposits (and not P2P payments), or with a non-zero
    598     timeframe to limit the amount a merchant can deposit over time.
    599     Usually used with a limit of zero to enforce merchant onboarding
    600     prior to first payment processing.  Inefficient to enforce limits
    601     later, usually for merchants that have been onboarded **AGGREGATION**
    602     limits should be set instead.
    603     Enforced by the exchange.
    604 
    605   * **MERGE**: Triggered when a user received digital cash from another
    606     wallet.
    607     Enforced by the exchange.
    608 
    609   * **REFUND**: Limit on the amount that can be refunded per
    610     transaction by a compliant merchant to a compliant wallet.
    611     Can only be used with a timeframe of zero, as this is about
    612     the amount that can be funded on an individual purchase.
    613     Enforced both wallet-side and merchant-side (enforcement by
    614     the exchange could be implemented in the future, but is
    615     tricky as the exchange sees refunds per coin and not per
    616     purchase).
    617 
    618   * **TRANSACTION**: Refers to all transactions of a wallet where digital
    619     cash is spent. Can be used with a timeframe of zero to set a transaction
    620     limit, or with a non-zero timeframe to limit the spending rate over time.
    621     Applies to spending money both in P2P and merchant transactions.
    622     Enforced by wallets and merchants.
    623 
    624   * **WITHDRAW**: Triggered when a user withdraws digital cash from their
    625     bank account.  Enforced by the exchange.
    626 
    627 
    628 Configuration of AML programs
    629 -----------------------------
    630 
    631 AML decision processes are automatically executed under certain configurable
    632 conditions.  Basically, any AML program that is run can flag an account for
    633 investigation by setting the respective flag in the `AmlOutcome`. Once this
    634 happens, the respective account will be highlighted to AML staff. The AML
    635 program can also limit the operations of the account by setting arbitrary
    636 thresholds for the various operations (including freezing the account by
    637 setting the thresholds to zero). AML staff investigating the account can then
    638 request further documentation or set new rules, including new thresholds.
    639 
    640 AML programs can base their decisions on arbitrary attributes created by the
    641 KYC check (such as the user being a politically exposed person).
    642 
    643 AML programs will be given the KYC attributes in JSON format on standard
    644 input, and must output the `AmlOutcome`. If AML programs fail (return non-zero
    645 status codes), a FALLBACK measure is automatically triggered.  FALLBACK
    646 measures MUST be *original* measures and MUST have a check of type "SKIP"
    647 and MUST NOT require any inputs.
    648 
    649 AML programs are listed in the configuration file, one program per section:
    650 
    651 .. code-block:: ini
    652 
    653   [aml-program-$PROG_NAME]
    654 
    655   # Program to run.
    656   COMMAND = taler-helper-aml-pep
    657 
    658   # Human-readable description of what this
    659   # AML helper program will do. Used to show
    660   # to the AML staff.
    661   DESCRIPTION = "check if the customer is a PEP"
    662 
    663   # True if this AML program is enabled (and thus can be
    664   # used in measures and exposed to AML staff).
    665   # Optional, default is NO.
    666   ENABLED = YES
    667 
    668   # **original** measure to take if COMMAND fails
    669   # Usually points to a measure that asks AML staff
    670   # to contact the systems administrator. The fallback measure
    671   # context always includes the reasons for the
    672   # failure.  FALLBACK measures MUST be *original*
    673   # measures with a check type of "SKIP" without any required
    674   # inputs.
    675   FALLBACK = MEASURE_NAME
    676 
    677 Implementing your own AML programs
    678 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    679 
    680 When implementing an AML program, developers must
    681 ensure to provide four main execution paths:
    682 
    683 * Generate a list of *required* context field names
    684   for the helper (introspection!) when given the "-r"
    685   command-line switch. The output should use the same
    686   syntax as the REQUIRES clause of ``[kyc-check-]``
    687   configuration sections, except that new lines
    688   MUST be used to separate fields instead of ";".
    689 * Generate a list of *required* inputs fields
    690   for the helper (introspection!) when given the "-i"
    691   command-line switch.  The input fields are named
    692   after the respective fields of the `AmlProgramInput`,
    693   thus "attributes", "aml_history", "context", "kyc_history",
    694   "default_rules" and "current_rules" are valid strings
    695   to return. Additionally, for the histories, it is
    696   possible to specify "\*_history[$NUMBER]" where
    697   "$NUMBER" is the number of entries to return, with
    698   positive numbers counting from the start of the
    699   history and negative numbers from the end of the
    700   history. Thus, "aml_history[-1]" will cause only
    701   the last AML history entry to be included.
    702 * Generate a list of *required* attribute names
    703   for the helper (introspection!) when given the "-a"
    704   command-line switch. The output should use the same
    705   list of names as the ATTRIBUTES in the
    706   ``[kyc-provider-]`` configuration section
    707   (but may also include FORM field names).
    708 * Process an input JSON object of type
    709   `AmlProgramInput` into a JSON object of
    710   type `AmlOutcome`.
    711   This is the default behavior if no command-line switches
    712   are provided.
    713 
    714 AML programs will be given the exchange's configuration filename with the "-c
    715 FILENAME" command-line option.  They may or may not use the configuration file
    716 as they see fit. AML programs should support the canonical "-h" (help) and
    717 "-v" (version) command-line options to display a help text and their version
    718 number respectively.  AML programs may be given the "-V" option to put them
    719 into verbose mode, suggesting that they should log additional information to
    720 standard error.
    721 
    722 If the AML program fails (exits with a failure code or does not provide
    723 well-formed JSON output) the AML/KYC process continues with the FALLBACK
    724 measure. This should usually be one that asks AML staff to contact the systems
    725 administrator.
    726 
    727 .. ts:def:: AmlProgramInput
    728 
    729   interface AmlProgramInput {
    730 
    731     // JSON object that was provided as
    732     // part of the *measure*.  This JSON object is
    733     // provided under "context" in the main JSON object
    734     // input to the AML program.  This "context" should
    735     // satify both the REQUIRES clause of the respective
    736     // check and the output of "-r" from the
    737     // AML program's command-line option.
    738     context?: Object;
    739 
    740     // JSON object that captures the
    741     // output of a ``[kyc-provider-]`` or (HTML) FORM.
    742     // In the case of KYC data provided by providers,
    743     // the keys in the JSON object will be the attribute
    744     // names and the values must be strings representing
    745     // the data. In the case of file uploads, the data
    746     // MUST be base64-encoded.
    747     // Attributes are only provided if the AML program
    748     // specifies "attributes" for its input requirements.
    749     attributes?: Object;
    750 
    751     // JSON array with the results of historic
    752     // AML desisions about the account.
    753     //
    754     // AML history is only provided if the AML program
    755     // specifies "aml_history" for its input requirements.
    756     aml_history?: AmlHistoryEntry[];
    757 
    758     // JSON array with the results of historic
    759     // KYC data about the account.
    760     //
    761     // KYC history is only provided if the AML program
    762     // specifies "kyc_history" for its input requirements.
    763     kyc_history?: KycHistoryEntry[];
    764 
    765     // Default KYC rules of the exchange (exposed and not exposed).
    766     //
    767     // Default KYC rules are only provided if the AML program
    768     // specifies "default_rules" for its input requirements.
    769     default_rules?: LegitimizationRuleSet;
    770 
    771     // Current KYC rules the exchange applies for this user.
    772     // (exposed and not exposed).
    773     //
    774     // Current KYC rules are only provided if the AML program
    775     // specifies "current_rules" for its input requirements.
    776     current_rules?: LegitimizationRuleSet;
    777 
    778   }
    779 
    780 .. ts:def:: AmlHistoryEntry
    781 
    782   interface AmlHistoryEntry {
    783     // When was the AML decision taken.
    784     decision_time : Timestamp;
    785 
    786     // What was the justification given for the decision.
    787     justification : string;
    788 
    789     // Public key of the AML officer taking the decision.
    790     decider_pub : AmlOfficerPublicKeyP;
    791 
    792     // Properties associated with the account by the decision.
    793     properties : Object;
    794 
    795     // New set of legitimization rules that was put in place.
    796     new_rules : LegitimizationRuleSet;
    797 
    798     // True if the account was flagged for (further)
    799     // investigation.
    800     to_investigate : boolean;
    801 
    802     // True if this is the currently active decision.
    803     is_active : boolean;
    804   }
    805 
    806 .. ts:def:: KycHistoryEntry
    807 
    808   interface KycHistoryEntry {
    809     // Name of the provider
    810     // which was used to collect the attributes. NULL if they were
    811     // just uploaded via a form by the account owner.
    812     provider_name?: string;
    813 
    814     // True if the KYC process completed.
    815     finished: boolean;
    816 
    817     // Numeric `error code <error-codes>`, if the
    818     // KYC process did not succeed; 0 on success.
    819     code: number;
    820 
    821     // Human-readable description of ``code``. Optional.
    822     hint?: string;
    823 
    824     // Optional detail given when the KYC process failed.
    825     error_message?: string;
    826 
    827     // Identifier of the user at the KYC provider. Optional.
    828     provider_user_id?: string;
    829 
    830     // Identifier of the KYC process at the KYC provider. Optional.
    831     provider_legitimization_id? :string;
    832 
    833     // The collected KYC data.
    834     // NULL if the attribute data could not
    835     // be decrypted or was not yet collected.
    836     attributes?: Object;
    837 
    838     // Time when the KYC data was collected
    839     collection_time: Timestamp;
    840 
    841     // Time when the KYC data will expire.
    842     expiration_time: Timestamp;
    843   }
    844 
    845 .. ts:def:: AmlOutcome
    846 
    847   interface AmlOutcome {
    848 
    849     // Should the client's account be investigated
    850     // by AML staff?
    851     // Defaults to false.
    852     to_investigate?: boolean;
    853 
    854     // Free-form properties about the account.
    855     // Can be used to store properties such as PEP,
    856     // risk category, type of business, hits on
    857     // sanctions lists, etc.
    858     properties?: AccountProperties;
    859 
    860     // Types of events to add to the KYC events table.
    861     // (for statistics).
    862     events?: string[];
    863 
    864     // Space-separated list of measures to trigger
    865     // immediately on the account.
    866     // Prefixed with a "+" to indicate that the
    867     // measures should be ANDed.
    868     // Should typically be used to give the user some
    869     // information or request additional information.
    870     //
    871     // MUST NOT contain an instant measure.
    872     // AML programs may be chained directly via
    873     // exec / fork+exec, but the exchange does not
    874     // support chaining.
    875     new_measures?: string;
    876 
    877     // KYC rules to apply.  Note that this
    878     // overrides *all* of the default rules
    879     // until the ``expiration_time`` and specifies
    880     // the successor measure to apply after the
    881     // expiration time.
    882     new_rules: LegitimizationRuleSet;
    883 
    884   }
    885 
    886 If the AML program fails (exits with a failure code or
    887 does not provide well-formed JSON output) the AML/KYC
    888 process continues with the FALLBACK measure. This should
    889 usually be one that asks AML staff to contact the
    890 systems administrator.
    891 
    892 
    893 
    894 Configuration of measures
    895 -------------------------
    896 
    897 Finally, the configuration specifies a set of
    898 **original** *measures* one per configuration section:
    899 
    900 .. code-block:: ini
    901 
    902   [kyc-measure-$MEASURE_NAME]
    903 
    904   # Possible check for this measure.  Optional.
    905   # If not given (or set to "SKIP"), PROGRAM should
    906   # be run immediately (on an empty set of attributes).
    907   CHECK_NAME = IB_FORM
    908 
    909   # Context for the check. The context can be
    910   # just an empty JSON object if there is none.
    911   CONTEXT = {"choices":["individual","business"]}
    912 
    913   # Program name to run on the context and check data to
    914   # determine the outcome and next measure.
    915   # Refers to a ``[aml-program-$PROG_NAME]`` section name.
    916   PROGRAM = taler-aml-program
    917 
    918 If ``CHECK_NAME`` is set to "SKIP" (or is not provided at all), the AML
    919 ``PROGRAM`` is to be run immediately.  This is useful if no client-interaction
    920 is required to arrive at a decision.
    921 
    922 .. note::
    923 
    924   The list of *measures* in the configuration is not complete: AML staff may
    925   freely define new measures dynamically, usually by selecting checks, an AML
    926   program, and providing context.  The measures specified in the configuration
    927   are called the *original measures* and only those can be used as FALLBACK
    928   measures.
    929 
    930 
    931 
    932 AML Configuration
    933 =================
    934 
    935 The AML configuration steps are used to add or remove keys of exchange
    936 operator staff that are responsible for anti-money laundering (AML)
    937 compliance.  These AML officers are shown suspicious transactions and are
    938 granted access to the KYC data of an exchange. They can then investigate the
    939 transaction and decide on new rules for the respective user. They may request
    940 additional KYC data from the consumer, can change the thresholds up to which
    941 amounts transactions are allowed, and associate properties with the account
    942 that AML programs (and AML officers) may interpret for arbitrary future
    943 actions.
    944 
    945 
    946 AML Officer Setup
    947 -----------------
    948 
    949 To begin the AML setup, AML staff should launch the GNU Taler exchange AML SPA
    950 Web interface by going to the ``/aml-spa/`` endpoint of the exchange. This is
    951 generally a public endpoint, but of course an operator may restrict access via
    952 the reverse proxy. The SPA will generate a public-private key pair and store
    953 it in the local storage of the browser.  The public key will be displayed and
    954 **must** be securely transmitted to the offline system for approval.  Using the
    955 offline system, one can then configure which staff has access to the AML
    956 operations:
    957 
    958 .. code-block:: shell-session
    959 
    960   [root@exchange-offline]# taler-exchange-offline \
    961      aml-enable "$PUBLIC_KEY" "Legal Name" rw > aml.json
    962   [root@exchange-online]# taler-exchange-offline \
    963      upload < aml.json
    964 
    965 The above commands would add an AML officer with the given "Legal Name" with
    966 read-write (rw) access to the AML officer database.  Using "ro" instead of
    967 "rw" would grant read-only access to the data, leaving out the ability to
    968 actually make AML decisions.  Once AML access has been granted, the AML
    969 officer can use the SPA to review cases and (with "rw" access) take AML
    970 decisions.
    971 
    972 Access rights can be revoked at any time using:
    973 
    974 .. code-block:: shell-session
    975 
    976   [root@exchange-offline]# taler-exchange-offline \
    977      aml-disable $PUBLIC_KEY "Legal Name" > aml-off.json
    978   [root@exchange-online]# taler-exchange-offline \
    979      upload < aml-off.json
    980 
    981 
    982 AML Forms
    983 ---------
    984 
    985 AML forms are defined by the :ref:`dynamic forms design document <dd54dynamicforms>`.
    986 The shipped implementation with of the exchange is installed in
    987 
    988 .. code-block:: shell-session
    989 
    990   ${INSTALL_PREFIX}/share/taler-exchange/spa/forms.js
    991 
    992 
    993 The variable ``form`` contains the list of all form available. For
    994 every entry in the list the next properties are expected to be present:
    995 
    996 ``label``: used in the UI as the name of the form
    997 
    998 ``id``: identification name, this will be saved in the exchange database
    999 along with the values to correctly render the form again.
   1000 It should simple, short and without any character outside numbers,
   1001 letters and underscore.
   1002 
   1003 ``version``: when editing a form, instead of just replacing fields
   1004 it will be better to create a new form with the same id and new version.
   1005 That way old forms in the database will used old definition of the form.
   1006 It should be a number.
   1007 
   1008 ``impl`` : a function that returns the design and behavior of form.
   1009 See DD 54 dynamic forms.
   1010 
   1011 .. attention::
   1012 
   1013   do not remove a form the list if it has been used. Otherwise you
   1014   won't be able to see the information save in the exchange database.
   1015 
   1016 To add a new one you can simply copy and paste one element, and edit it.
   1017 
   1018 It is much easier to download ``@gnu-taler/aml-backoffice-ui`` source
   1019 from ``https://git.taler.net/wallet-core.git/``, compile and copy the file
   1020 from the ``dist/prod``.
   1021 
   1022 
   1023 .. _sanctions:
   1024 
   1025 Sanction list checking
   1026 ======================
   1027 
   1028 The **taler-exchange-sanctionlist** service can be used to automatically check
   1029 KYC records against sanction lists.  The service is not run by default but
   1030 must be explicitly enabled. It can run in incremental mode, processing
   1031 incoming KYC records immediately when new data is submitted. When a new
   1032 sanction list is released, use the "--reset" option to re-process all existing
   1033 records, checking them again against the latest list.  To only reset the
   1034 position but keep checking in the background, add "--norun". Finally, to run
   1035 the tool manually and exit immediately once all existing KYC records have been
   1036 processed (and not wait for new records to eventually be submitted from new
   1037 customers), use "--test".
   1038 
   1039 The tool operates by decrypting all of the KYC attributes from the exchange
   1040 database and passes them to a helper program which must then determine
   1041 
   1042   * which sanction list record matches best,
   1043   * how well that sanction list record matches, and
   1044   * how certain the tool is that the match is accurate.
   1045 
   1046 Based on this assessment by the helper program, **taler-exchange-sanctionlist**
   1047 will then either
   1048 
   1049   * freeze the account and flag it for investigation (likely match),
   1050   * only flag the account for investigation (possible match), or
   1051   * allow the account to continue as normal (no match)
   1052 
   1053 To avoid the same account being flagged repeatedly for investigation
   1054 due to a false-positive match with the sanction list, AML staff can
   1055 mark an account with the "SANCTION_LIST_SUPPRESS: true"
   1056 property, in which case hits on the sanction list are ignored.
   1057 
   1058 Robocop
   1059 -------
   1060 
   1061 Robocop is an implementation of a sanction list helper that can be used to
   1062 match KYC records against sanction lists. It consists of a generic matching
   1063 tool that computes the editing distance between a provided KYC record and each
   1064 sanction list entry. The sanction list entries must be provided in a file that
   1065 contains a JSON array with all sanction list entries where each entry is a
   1066 JSON object with fields matching the KYC attributes from the GANA registry,
   1067 plus a special field "ssid" that identifies the sanction list entry. Each
   1068 regular attribute field must be mapped to an array of strings where each
   1069 string is a possible spelling for values of this field, for example to allow
   1070 aliases to be given for names.
   1071 
   1072 Given such a sanction list, Robocop finds the best match for
   1073 each KYC record read from standard input (one record per line)
   1074 and outputs the match quality, confidence and the "ssid" of the
   1075 best match in the format expected by **taler-exchange-sanctionlist**.
   1076 
   1077 Robocop additionally includes Python script to convert the Swiss
   1078 sanction list (provided in XML) to its internal JSON format, and
   1079 a shell script to optimize the resulting JSON data by removing
   1080 empty fields.
   1081 
   1082 
   1083 .. _ExchangeTemplateCustomization:
   1084 
   1085 KYC Process Template Customization
   1086 ==================================
   1087 
   1088 The Exchange comes with various HTML templates that are shown to guide users
   1089 through the KYC process. The Exchange uses `C implementation of mustache
   1090 <https://gitlab.com/jobol/mustach>`__ as the templating engine.  This section
   1091 describes the various templates.  In general, the templates must be installed
   1092 to the ``share/taler-exchange/templates/`` directory. The file names must be
   1093 of the form ``$NAME.$LANG.must`` where ``$NAME`` is the name of the template
   1094 and ``$LANG`` is the 2-letter language code of the template. English templates
   1095 must exist and will be used as a fallback.  If the browser (user-agent) has
   1096 provided language preferences in the HTTP header and the respective language
   1097 exists, the correct language will be automatically served.
   1098 
   1099 The following subsections give details about each of the templates. Most
   1100 subsection titles are the ``$NAME`` of the respective template.
   1101 
   1102 
   1103 Generic Errors Templates
   1104 ------------------------
   1105 
   1106 A number of templates are used for generic errors. These are:
   1107 
   1108   * kyc-proof-already-done (KYC process already completed)
   1109   * kyc-bad-request (400 Bad Request)
   1110   * kyc-proof-endpoint-unknown (404 Not Found for KYC logic)
   1111   * kyc-proof-internal-error (500 Internal Server Error)
   1112   * kyc-proof-target-unknown (404 Not Found for KYC operation)
   1113 
   1114 All of these templates are instantiated using the following information:
   1115 
   1116   * ec: Integer; numeric Taler error code, should be shown to indicate the
   1117     error compactly for reporting to developers
   1118 
   1119   * hint: String; human-readable Taler error code, should be shown for the
   1120     user to understand the error
   1121 
   1122   * message: String; optional, extended human-readable text provided to elaborate
   1123     on the error, should be shown to provide additional context
   1124 
   1125 
   1126 kycaid-invalid-request
   1127 ----------------------
   1128 
   1129 The KYCaid plugin does not support requests to the
   1130 ``/kyc-proof/`` endpoint (HTTP 400 bad request).
   1131 
   1132 This template is instantiated using the following information:
   1133 
   1134   * ec: Integer; numeric Taler error code, should be shown to indicate the
   1135     error compactly for reporting to developers
   1136 
   1137   * hint: String; human-readable Taler error code, should be shown for the
   1138     user to understand the error
   1139 
   1140   * error: String; error code from the server
   1141 
   1142   * error_details: String; optional error description from the server
   1143 
   1144   * error_uri: optional URI with further details about the error from the server
   1145 
   1146 
   1147 
   1148 oauth2-authentication-failure
   1149 -----------------------------
   1150 
   1151 The OAuth2 server said that the request was not
   1152 properly authenticated (HTTP 403 Forbidden).
   1153 
   1154 
   1155 This template is instantiated using the following information:
   1156 
   1157   * ec: Integer; numeric Taler error code, should be shown to indicate the
   1158     error compactly for reporting to developers
   1159 
   1160   * hint: String; human-readable Taler error code, should be shown for the
   1161     user to understand the error
   1162 
   1163 
   1164 oauth2-authorization-failure
   1165 ----------------------------
   1166 
   1167 The OAuth2 server refused to return the KYC data because the authorization
   1168 code provided was invalid (HTTP 403 Forbidden).
   1169 
   1170 This template is instantiated using the following information:
   1171 
   1172   * ec: Integer; numeric Taler error code, should be shown to indicate the
   1173     error compactly for reporting to developers
   1174 
   1175   * hint: String; human-readable Taler error code, should be shown for the
   1176     user to understand the error
   1177 
   1178   * error: String; error code from the server
   1179 
   1180   * error_message: String; error message from the server
   1181 
   1182 
   1183 oauth2-authorization-failure-malformed
   1184 --------------------------------------
   1185 
   1186 The server refused the authorization, but then provided
   1187 a malformed response (HTTP 502 Bad Gateway).
   1188 
   1189 This template is instantiated using the following information:
   1190 
   1191   * ec: Integer; numeric Taler error code, should be shown to indicate the
   1192     error compactly for reporting to developers
   1193 
   1194   * hint: string; human-readable Taler error code, should be shown for the
   1195     user to understand the error
   1196 
   1197   * debug: boolean; true if we are running in debug mode and are allowed to return HTML with potentially sensitive information
   1198 
   1199   * server_response: Object; could be NULL; this includes the (malformed) OAuth2 server response, it should be shown to the use if "debug" is true
   1200 
   1201 
   1202 oauth2-bad-request
   1203 ------------------
   1204 
   1205 The client made an invalid request (HTTP 400 Bad Request).
   1206 
   1207 This template is instantiated using the following information:
   1208 
   1209   * ec: Integer; numeric Taler error code, should be shown to indicate the
   1210     error compactly for reporting to developers
   1211 
   1212   * hint: String; human-readable Taler error code, should be shown for the
   1213     user to understand the error
   1214 
   1215   * message: String; additional error message elaborating on what was bad about the request
   1216 
   1217 
   1218 oauth2-conversion-failure
   1219 -------------------------
   1220 
   1221 Converting the KYC data into the exchange's internal
   1222 format failed (HTTP 502 Bad Gateway).
   1223 
   1224 This template is instantiated using the following information:
   1225 
   1226   * ec: Integer; numeric Taler error code, should be shown to indicate the
   1227     error compactly for reporting to developers
   1228 
   1229   * hint: string; human-readable Taler error code, should be shown for the
   1230     user to understand the error
   1231 
   1232   * debug: boolean; true if we are running in debug mode and are allowed to return HTML with potentially sensitive information
   1233 
   1234   * converter: String; name of the conversion command that failed which was used by the Exchange
   1235 
   1236   * attributes: Object; attributes returned by the conversion command, often NULL (after all, conversion failed)
   1237 
   1238   * message: error message elaborating on the conversion failure
   1239 
   1240 
   1241 oauth2-provider-failure
   1242 -----------------------
   1243 
   1244 We did not get an acceptable response from the OAuth2
   1245 provider (HTTP 502 Bad Gateway).
   1246 
   1247 This template is instantiated using the following information:
   1248 
   1249   * ec: Integer; numeric Taler error code, should be shown to indicate the
   1250     error compactly for reporting to developers
   1251 
   1252   * hint: String; human-readable Taler error code, should be shown for the
   1253     user to understand the error
   1254 
   1255   * message: String; could be NULL; text elaborating on the details of the failure
   1256 
   1257 
   1258 persona-exchange-unauthorized
   1259 -----------------------------
   1260 
   1261 The Persona server refused our request (HTTP 403 Forbidden from Persona, returned as a HTTP 502 Bad Gateway).
   1262 
   1263 This template is instantiated using the following information:
   1264 
   1265   * ec: Integer; numeric Taler error code, should be shown to indicate the
   1266     error compactly for reporting to developers
   1267 
   1268   * hint: String; human-readable Taler error code, should be shown for the
   1269     user to understand the error
   1270 
   1271   * data: Object; data returned from Persona service, optional
   1272 
   1273   * persona_http_status: Integer; HTTP status code returned by Persona
   1274 
   1275 
   1276 persona-load-failure
   1277 --------------------
   1278 
   1279 The Persona server refused our request (HTTP 429 Too Many Requests from Persona, returned as a HTTP 503 Service Unavailable).
   1280 
   1281 This template is instantiated using the following information:
   1282 
   1283   * ec: Integer; numeric Taler error code, should be shown to indicate the
   1284     error compactly for reporting to developers
   1285 
   1286   * hint: String; human-readable Taler error code, should be shown for the
   1287     user to understand the error
   1288 
   1289   * data: Object; data returned from Persona service, optional
   1290 
   1291   * persona_http_status: Integer; HTTP status code returned by Persona
   1292 
   1293 
   1294 persona-exchange-unpaid
   1295 -----------------------
   1296 
   1297 The Persona server refused our request (HTTP 402 Payment REquired from Persona, returned as a HTTP 503 Service Unavailable).
   1298 
   1299 This template is instantiated using the following information:
   1300 
   1301   * ec: Integer; numeric Taler error code, should be shown to indicate the
   1302     error compactly for reporting to developers
   1303 
   1304   * hint: String; human-readable Taler error code, should be shown for the
   1305     user to understand the error
   1306 
   1307   * data: Object; data returned from Persona service, optional
   1308 
   1309   * persona_http_status: Integer; HTTP status code returned by Persona
   1310 
   1311 
   1312 
   1313 persona-logic-failure
   1314 ---------------------
   1315 
   1316 The Persona server refused our request (HTTP 400, 403, 409, 422 from Persona, returned as a HTTP 502 Bad Gateway).
   1317 
   1318 This template is instantiated using the following information:
   1319 
   1320   * ec: Integer; numeric Taler error code, should be shown to indicate the
   1321     error compactly for reporting to developers
   1322 
   1323   * hint: String; human-readable Taler error code, should be shown for the
   1324     user to understand the error
   1325 
   1326   * data: Object; data returned from Persona service, optional
   1327 
   1328   * persona_http_status: Integer; HTTP status code returned by Persona
   1329 
   1330 
   1331 persona-invalid-response
   1332 ------------------------
   1333 
   1334 The Persona server refused our request in an
   1335 unexpected way; returned as a HTTP 502 Bad Gateway.
   1336 
   1337 This template is instantiated using the following information:
   1338 
   1339   * ec: Integer; numeric Taler error code, should be shown to indicate the
   1340     error compactly for reporting to developers
   1341 
   1342   * hint: string; human-readable Taler error code, should be shown for the
   1343     user to understand the error
   1344 
   1345   * debug: boolean; true if we are running in debug mode and are allowed to return HTML with potentially sensitive information
   1346 
   1347   * server_response: Object; could be NULL; this includes the (malformed) OAuth2 server response, it should be shown to the use if "debug" is true
   1348 
   1349 
   1350 persona-network-timeout
   1351 -----------------------
   1352 
   1353 The Persona server refused our request (HTTP 408 from Persona, returned as a HTTP 504 Gateway Timeout).
   1354 
   1355 This template is instantiated using the following information:
   1356 
   1357   * ec: Integer; numeric Taler error code, should be shown to indicate the
   1358     error compactly for reporting to developers
   1359 
   1360   * hint: String; human-readable Taler error code, should be shown for the
   1361     user to understand the error
   1362 
   1363   * data: Object; data returned from Persona service, optional
   1364 
   1365   * persona_http_status: Integer; HTTP status code returned by Persona
   1366 
   1367 
   1368 persona-kyc-failed
   1369 ------------------
   1370 
   1371 The Persona server indicated a problem with the KYC process, saying it was not completed.
   1372 
   1373 This template is instantiated using the following information:
   1374 
   1375   * persona_inquiry_id: String; internal ID of the inquiry within Persona, useful for further diagnostics by staff
   1376 
   1377   * data: Object; could be NULL; this includes the server response, it contains extensive diagnostics, see Persona documentation on their ``/api/v1/inquiries/$ID``.
   1378 
   1379   * persona_http_status: Integer; HTTP status code returned by Persona
   1380 
   1381 persona-provider-failure
   1382 ------------------------
   1383 
   1384 The Persona server refused our request (HTTP 500 from Persona, returned as a HTTP 502 Bad Gateway).
   1385 
   1386 This template is instantiated using the following information:
   1387 
   1388   * ec: Integer; numeric Taler error code, should be shown to indicate the
   1389     error compactly for reporting to developers
   1390 
   1391   * hint: String; human-readable Taler error code, should be shown for the
   1392     user to understand the error
   1393 
   1394   * data: Object; data returned from Persona service, optional
   1395 
   1396   * persona_http_status: Integer; HTTP status code returned by Persona