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