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