gnunet-svn
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[taler-docs] branch master updated: kyc spec work


From: gnunet
Subject: [taler-docs] branch master updated: kyc spec work
Date: Sun, 14 Apr 2024 20:47:56 +0200

This is an automated email from the git hooks/post-receive script.

grothoff pushed a commit to branch master
in repository docs.

The following commit(s) were added to refs/heads/master by this push:
     new 2fd678a6 kyc spec work
2fd678a6 is described below

commit 2fd678a6bf5841e6461d2819c0bac4d46d8a856a
Author: Christian Grothoff <christian@grothoff.org>
AuthorDate: Sun Apr 14 20:47:53 2024 +0200

    kyc spec work
---
 core/api-exchange.rst              |   2 +
 design-documents/023-taler-kyc.rst | 694 +++++++++++++++++++++++++++++--------
 2 files changed, 561 insertions(+), 135 deletions(-)

diff --git a/core/api-exchange.rst b/core/api-exchange.rst
index d41372d8..4c5be000 100644
--- a/core/api-exchange.rst
+++ b/core/api-exchange.rst
@@ -1418,6 +1418,7 @@ and freeze or unfreeze accounts suspected of money 
laundering.
       // What was the justification given?
       justification: string;
 
+      // FIXME: review!
       // What is the new AML state.
       new_state: Integer;
 
@@ -1438,6 +1439,7 @@ and freeze or unfreeze accounts suspected of money 
laundering.
 
       // Name of the configuration section that specifies the provider
       // which was used to collect the KYC details
+      // FIXME: review!
       provider_section: string;
 
       // The collected KYC data.  NULL if the attribute data could not
diff --git a/design-documents/023-taler-kyc.rst 
b/design-documents/023-taler-kyc.rst
index 85478d8e..1eb0669e 100644
--- a/design-documents/023-taler-kyc.rst
+++ b/design-documents/023-taler-kyc.rst
@@ -84,9 +84,14 @@ There are also various *outcomes*:
 * held, AML staff reviewing evidence for plausibilization (new measure)
 * automatically frozen until certain day (due to sanctions)
 * institutionally frozen until certain day (due to order by state authority)
+* operation is categorically not allowed (at least above certain limits)
 
-The outcome of a *check* can trigger further *measures* (including
-expiration of the outcome state).
+Outcomes may also be (partially) public, that is exposed to the client. For
+example, we may want to tell a wallet that it has hit a hard withdraw limit,
+but might succeed at withdrawing a smaller amount.
+
+The outcome of a *check* can set new rules or trigger another *measure* (the
+latter is conditional on reaching the expiration time of the outcome).
 
 As a result, we largely end up in a large state machine where the AML staff has
 serious flexibiltiy while the user needs guidance as to the possible next moves
@@ -219,11 +224,11 @@ Terminology
 
 * **Measure**: Describes the possible outgoing edges from one state in the 
state machine (including how to show the current state). Each edge is given 
some *context* and a *check* to be performed as well as a *program* to decide 
the *outcome* and the next *measure*.
 
-* **Outcome**: Describes the account state that an account ends up in due to 
the result of a *check*. Outcomes can be that an account is frozen (no 
transactions possible until freeze expires), held (no transactions possible 
until another *measure* has been taken), or operating normally.
+* **Outcome**: Describes the account state that an account ends up in due to 
the result of a *check*. Outcomes can be that an account is frozen (no 
transactions possible until freeze expires), held (no transactions possible 
until another *measure* has been taken), or operating normally.  Outcomes also 
include a new set of *legitimization rules* to apply and an expiration time at 
which point a new *measure* will be automatically taken. Finally, parts of the 
outcome may be explained to the [...]
 
 * **Provider**: A provider performs a specific set of *checks* at a certain 
*cost*. Interaction with a provider is performed by provider-specific *logic*.
 
-* **Program**: An AML helper *program* is given *context* about the current 
state of an account and the data from a *check* to compute the *outcome*.  For 
example, a *program* may look at the "PEP" field of a KYC check and decide if 
the outcome is to put the account into ``normal`` or ``held-for-manual-review`` 
state.  A *program* operating on an AML form filed by AML staff will likely be 
trivial and directly apply the explicit decision taken by the staff member.
+* **Program**: An AML helper *program* is given *context* about the current 
state of an account and the attribute data from a *check* to compute the 
*outcome*.  For example, a *program* may look at the "PEP" field of a KYC check 
and decide if the outcome is to put the account into ``normal`` or 
``held-for-manual-review`` state.
 
 * **Type of operation**: The operation type determines which Taler-specific 
operation has triggered the KYC requirement. We support four types of 
operation: withdraw (by customer), deposit (by merchant), P2P receive (by 
wallet) and (high) wallet balance.
 
@@ -231,7 +236,7 @@ Terminology
 New Endpoints
 ^^^^^^^^^^^^^
 
-The new ``/kyc-check/`` endpoint is based on the legitimization requirements
+The ``/kyc-check/`` endpoint is based on the legitimization requirements
 serial number and receives the business vs. individual status from the client.
 Access is ``authenticated`` by also passing the hash of the payto://-URI.
 (Weak authentication is acceptable, as the KYC status or the ability to
@@ -243,73 +248,332 @@ GET.  It must always be the same endpoint for the same 
client, as the
 wallet/merchant backend are not required to check for changes to this
 endpoint.
 
-A new set of ``/kyc-spa/$HASH`` GET endpoints is created per client ``$HASH`` 
that
-serves the KYC SPA.  This is where the ``/kyc-check/`` endpoint will redirect
-clients unless all KYC/AML requirements are satisfied.  The KYC SPA will
-use the ``$HASH`` of its URL to initialize itself via the ``/kyc-info/$HASH``
-endpoint family.
-
-A new set of ``/kyc-info/$HASH`` GET endpoints is created per client ``$HASH``
-to return information about the state of the KYC or AML process to the client.
-The SPA uses this information to show the user an appropriate dialog. The SPA
-should also long-poll this endpoint for changes to the AML/KYC state. Note
-that this is a client-facing endpoint, so it will only provide a restricted
-amount of information to the customer (as some laws may forbid us to inform
-particular customers about their true status).  The endpoint will typically
-inform the SPA about possible choices to proceed, such as directly uploading
-files, contacting AML staff, or proceeding with a particular KYC process at
-an external provider (such as Challenger).  If the user chooses to initate a
-KYC process at an external provider, the SPA must request the respective
-process to be set-up by the exchange via the ``/kyc-start/`` endpoint.
-
-The new ``/kyc-upload/$ID`` POST endpoint allows the SPA to upload
-client-provided evidence.  The ``$ID`` will be provided as part of the
-``/kyc-info`` body.  This is for checks of type ``FORM``.
-
-The new ``/kyc-start/$ID`` POST endpoint allows the SPA to set up a new
-external KYC process. It will return the (GET) URL that the client must open
-to begin the KYC process. The SPA should probably open this URL in a new
-window or tab.  The ``$ID`` will be provided as part of the ``/kyc-info``
-body.  As this endpoint is involved in every KYC check at the beginning, this
-is also the place where we could integrate the payment process for the KYC fee
-in the future.
-
-Upon completion of the process at the external KYC provider, the provider must
-trigger a GET request to a new ``/kyc-proof/$H_PAYTO/$PROVIDER_SECTION``
-endpoint.  This may be done either by redirecting the browser of the user to
-that endpoint.  Once this endpoint is triggered, the exchange will pass the
-received arguments to the respective logic plugin.  The logic plugin will then
-(asynchronously) update the KYC status of the user.  The logic plugin should
-return a human-readable HTML page with the KYC result to the user.
-
-Alternatively, the KYC confirmation may be triggered by a ``/kyc-webhook``
-request. As KYC providers do not necessarily support passing detailed
-information in the URL arguments, the ``/kyc-webhook`` only needs to specify
-either the ``PROVIDER_SECTION`` *or* the ``LOGIC`` (the name of the plugin
-implementing the KYC API).  The API-specific webhook logic must then figure
-out what exactly the webhook is about on its own.  The ``/kyc-webhook/``
-endpoint works for GET or POST, again as details depend on the KYC provider.
-In contrast to ``kyc-proof``, the response does NOT go to the end-users'
-browser and should thus only indicate success or failure.
-
-The new ``/wallet-kyc`` POST endpoint allows a wallet to notify an exchange
-if it will cross a balance threshold.  Here, the ``balance`` specified should
-be the threshold (from the ``wallet_balance_limit_without_kyc`` array) that
-the wallet would cross, and *not* the *exact* balance of the wallet.  The
-exchange will respond with a wire target UUID. The wallet can then use this
-UUID to being the KYC process at ``/kyc-check/``. The wallet must only proceed
-to obtain funds exceeding the threshold after the KYC process has
-concluded. While wallets could be "hacked" to bypass this measure (we cannot
-cryptographically enforce this), such modifications are a terms of service
-violation which may have legal consequences for the user.
-
-
-To enable the AML staff SPA to give AML staff a choice of possible measures, a
-new endpoint ``/aml/$OFFICER_PUB/measures`` is added that allows the AML SPA
-to dynamically GET the list of available measures.
-It returns a list of known KYC checks (by name)
-with their descriptions and a list of AML programs
-with information about the required context.
+FIXME: update /kyc-check/ endpoint to expose *public* outcomes of previous
+checks (such as hard withdrawal limits)!
+
+.. http:get:: /kyc-spa/{$HASH,$FILENAME}
+
+  A set of ``/kyc-spa/$HASH`` GET endpoints is created per client ``$HASH``
+  that serves the KYC SPA.  This is where the ``/kyc-check/`` endpoint will
+  redirect clients unless all KYC/AML requirements are satisfied.  The KYC SPA
+  will use the ``$HASH`` of its URL to initialize itself via the
+  ``/kyc-info/$HASH`` endpoint family.  The KYC SPA may download additional
+  resources via ``/kyc-spa/$FILENAME``. The filenames must not match
+  base32-encoded SHA-512 hashes.
+
+.. http:get:: /kyc-info/$HASH
+
+  A new set of ``/kyc-info/$HASH`` GET endpoints is created per client
+  ``$HASH`` to return information about the state of the KYC or AML process to
+  the KYC SPA.  The SPA uses this information to show the user an appropriate
+  dialog. The SPA should also long-poll this endpoint for changes to the 
AML/KYC
+  state. Note that this is a client-facing endpoint, so it will only provide a
+  restricted amount of information to the customer (as some laws may forbid us
+  to inform particular customers about their true status).  The endpoint will
+  typically inform the SPA about possible choices to proceed, such as directly
+  uploading files, contacting AML staff, or proceeding with a particular KYC
+  process at an external provider (such as Challenger).  If the user chooses to
+  initate a KYC process at an external provider, the SPA must request the
+  respective process to be set-up by the exchange via the ``/kyc-start/``
+  endpoint.
+
+  **Request**:
+
+   *If-None-Match*: The client MAY provide an ``If-None-Match`` header with
+   an ETag.
+
+    :query timeout_ms=MILLISECONDS: *Optional.*  If specified, the exchange 
will wait up to MILLISECONDS for a change to a more recent legitimization 
measure before returning a 304 Not Modified.
+
+  **Response**:
+
+  :http:statuscode:`200 OK`:
+    The body is a `KycProcessClientInformation`.
+
+  *Etag*: Will be set to the serial ID of the measure. Used for long-polling.
+
+  .. ts:def:: KycProcessClientInformation
+
+    interface KycProcessClientInformation {
+
+      // List of requirements.
+      requirements?: { name : KycRequirementInformation};
+
+      // True if the client is expected to eventually satisfy all requirements.
+      // Default (if missing) is false.
+      is_and_combinator?: boolean
+
+      // List of available voluntary checks the client could pay for.
+      // Since **vATTEST**.
+      voluntary_checks?: { name : KycCheckInformation};
+    }
+
+  .. ts:def:: KycRequirementInformation
+
+    interface KycRequirementInformation {
+
+      // Which form should be used? Common values include "INFO"
+      // (to just show the descriptions but allow no action),
+      // "LINK" (to enable the user to obtain a link via
+      // ``/kyc-start/``) or any build-in form name supported
+      // by the SPA.
+      form: string;
+
+      // English description of the requirement.
+      description: string;
+
+      // Map from IETF BCP 47 language tags to localized
+      // description texts.
+      description_i18n ?: { [lang_tag: string]: string };
+
+      // ID of the requirement, useful to construct the
+      // ``/kyc-upload/$ID`` or ``/kyc-start/$ID`` endpoint URLs.
+      // Present if and only if "form" is not "INFO".
+      id?: string;
+
+    }
+
+  .. ts:def:: KycCheckInformation
+
+    // Since **vATTEST**.
+    interface KycCheckInformation {
+
+      // How much would this check cost the client?
+      cost: Amount;
+
+      // English description of the check.
+      description: string;
+
+      // Map from IETF BCP 47 language tags to localized
+      // description texts.
+      description_i18n ?: { [lang_tag: string]: string };
+
+    }
+
+  :http:statuscode:`204 No Content`:
+    There are no open KYC requirements or possible voluntary checks
+    the client might perform.
+
+  :http:statuscode:`304 Not Modified`:
+    The KYC requirements did not change.
+
+.. http:post:: /kyc-upload/$ID
+
+  The ``/kyc-upload/$ID`` POST endpoint allows the SPA to upload
+  client-provided evidence.  The ``$ID`` will be provided as part of the
+  ``/kyc-info`` body.  This is for checks of type ``FORM``.
+
+  **Request**:
+
+  Basically oriented along the possible formats of a HTTP form being
+  POSTed. Details will depend on the form. The server will try to
+  decode the uploaded body from whatever format it is provided in.
+
+  **Response**:
+
+  :http:statuscode:`204 No Content`:
+    The information was successfully uploaded. The SPA should fetch
+    an updated ``/kyc-info/``.
+  :http:statuscode:`404 Not Found`:
+    The ``$ID`` is unknown to the exchange.
+  :http:statuscode:`409 Conflict`:
+    The upload conflicts with a previous upload.
+  :http:statuscode:`413 Content Too Large`:
+    The body is too large.
+
+.. http:post:: /kyc-start/$ID
+
+  The ``/kyc-start/$ID`` POST endpoint allows the SPA to set up a new
+  external KYC process. It will return the URL that the client must GET
+  to begin the KYC process. The SPA should probably open this URL in a new
+  window or tab.  The ``$ID`` will be provided as part of the ``/kyc-info``
+  body.
+
+  **Request**:
+
+  Use empty JSON body for now.
+
+  **Response**:
+
+  :http:statuscode:`200 Ok`:
+    The KYC process was successfully initiated. The URL is in a
+    `KycProcessStartInformation` object.
+
+  .. ts:def:: KycProcessStartInformation
+
+    interface KycProcessStartInformation {
+
+      // URL to open.
+      redirect_url: string;
+    }
+
+  :http:statuscode:`404 Not Found`:
+    The ``$ID`` is unknown to the exchange.
+
+  .. note::
+
+    As this endpoint is involved in every KYC check at the beginning, this
+    is also the place where we could integrate the payment process for the KYC 
fee
+    in the future (since **vATTEST**).
+
+
+.. http:get:: /kyc-proof/$H_PAYTO/$PROVIDER_SECTION
+
+  Upon completion of the process at the external KYC provider, the provider
+  must trigger a GET request to a new ``/kyc-proof/$H_PAYTO/$PROVIDER_SECTION``
+  endpoint.  This may be done either by redirecting the browser of the user to
+  that endpoint.  Once this endpoint is triggered, the exchange will pass the
+  received arguments to the respective logic plugin.  The logic plugin will 
then
+  (asynchronously) update the KYC status of the user.  The logic plugin should
+  return a human-readable HTML page with the KYC result to the user.
+
+.. http:get:: /kyc-webhook/*``
+.. http:post:: /kyc-webhook/*``
+
+  Alternatively, the KYC confirmation may be triggered by a ``/kyc-webhook``
+  request. As KYC providers do not necessarily support passing detailed
+  information in the URL arguments, the ``/kyc-webhook`` only needs to specify
+  either the ``PROVIDER_SECTION`` *or* the ``LOGIC`` (the name of the plugin
+  implementing the KYC API).  The API-specific webhook logic must then figure
+  out what exactly the webhook is about on its own.  The ``/kyc-webhook/``
+  endpoint works for GET or POST, again as details depend on the KYC provider.
+  In contrast to ``kyc-proof``, the response does NOT go to the end-users'
+  browser and should thus only indicate success or failure.
+
+.. http:post:: /wallet-kyc``
+
+  The ``/wallet-kyc`` POST endpoint allows a wallet to notify an exchange if
+  it will cross a balance threshold.  Here, the ``balance`` specified should be
+  the threshold (from the ``wallet_balance_limit_without_kyc`` array) that the
+  wallet would cross, and *not* the *exact* balance of the wallet.  The 
exchange
+  will respond with a wire target UUID. The wallet can then use this UUID to
+  being the KYC process at ``/kyc-check/``. The wallet must only proceed to
+  obtain funds exceeding the threshold after the KYC process has concluded.
+  While wallets could be "hacked" to bypass this measure (we cannot
+  cryptographically enforce this), such modifications are a terms of service
+  violation which may have legal consequences for the user.
+
+.. http:get:: /aml/$OFFICER_PUB/measures
+
+  To enable the AML staff SPA to give AML staff a choice of possible measures, 
a
+  new endpoint ``/aml/$OFFICER_PUB/measures`` is added that allows the AML SPA
+  to dynamically GET the list of available measures.  It returns a list of 
known
+  KYC checks (by name) with their descriptions and a list of AML programs with
+  information about the required context.
+
+  **Request**:
+
+  FIXME: see other AML GET requests?
+
+  **Response**:
+
+  :http:statuscode:`200 Ok`:
+    Information about possible measures is returned in a
+    `AvailableMeasureSummary` object.
+
+  .. ts:def:: AvailableMeasureSummary
+
+    interface AvailableMeasureSummary {
+
+      // Available original measures that can be
+      // triggered directly by default rules.
+      roots: { "$measure_name" : MeasureInformation };
+
+      // Available AML programs.
+      programs: { "$prog_name" : AmlProgramRequirement };
+
+      // Available KYC checks.
+      checks: { "$check_name" : KycCheckInformation };
+
+    }
+
+  .. ts:def:: MeasureInformation
+
+    interface MeasureInformation {
+
+      // Name of a KYC check.
+      check_name: string;
+
+      // Name of an AML program.
+      prog_name: string;
+
+      // Context for the check. Could be empty.
+      context: Object;
+
+    }
+
+  .. ts:def:: AmlProgramRequirement
+
+    interface AmlProgramRequirement {
+
+      // Description of what the AML program does.
+      description: string;
+
+      // List of required field names in the context
+      // to run this AML program.
+      // SPA must check that the AML staff is providing
+      // adequate CONTEXT when defining a measure using
+      // this AML program.
+      context: string[];
+
+      // List of required attribute names in the
+      // input of this AML program.  These attributes
+      // are the minimum that the check must produce
+      // (it may produce more).
+      inputs: string[];
+
+    }
+
+  .. ts:def:: KycCheckInformation
+
+    interface KycCheckInformation {
+
+      // Description of the KYC check.  Should be shown
+      // to the AML staff but will also be shown to the
+      // client when they initiate the check in the KYC SPA.
+      description: string;
+      description_i18n: {};
+
+      // Names of the fields that the CONTEXT must provide
+      // as inputs to this check.
+      // SPA must check that the AML staff is providing
+      // adequate CONTEXT when defining a measure using
+      // this check.
+      requires: string[];
+
+      // Names of the attributes the check will output.
+      // SPA must check that the outputs match the
+      // required inputs when combining a KYC check
+      // with an AML program into a measure.
+      outputs: string[];
+
+      // Name of a root measure taken when this check fails.
+      fallback: string;
+    }
+
+.. http:get:: /aml/kyc-statistics/$NAME
+
+  Returns the number of KYC events matching the given
+  event type ``$NAME`` in the specified time range.
+  Note that this query can be slow as the statistics
+  are computed on-demand. (This is OK as such requests
+  should be rare.)
+
+  **Request**:
+
+  FIXME: add authorization checks, as with other /aml/ requests.
+
+    :query start_date=TIMESTAMP: *Optional*. Specifies the date when to start 
looking (inclusive). If not given, the start time of the exchange operation is 
used.
+    :query end_date=TIMESTAMP: *Optional*. Specifies the date when to stop 
looking (exclusive). If not given, the current date is used.
+
+  **Response**:
+
+  .. ts:def:: EventCounter
+
+    interface EventCounter {
+      // Number of events of the specified type in
+      // the given range.
+      cnt: Integer;
+    }
 
 
 Modifications to existing endpoints
@@ -365,6 +629,7 @@ description of the high-level process for different 
providers.
 
     # Optional cost, useful if clients want to voluntarily
     # trigger authentication procedures for attestation.
+    # Since **vATTEST**.
     COST = EUR:5
 
     # Plus additional logic-specific options, e.g.:
@@ -373,12 +638,17 @@ description of the high-level process for different 
providers.
     # Other logic-specific internal options (example):
     FORM_ID = business_legi_form
 
-    # Description of the outputs provided by the check.
-    # Basically, the check's output is expected to
-    # provide the following fields as inputs into
-    # a subsequent AML program.
-    ATTRIBUTES = business_name street city country registration
-
+    # Name of a program to run on the output of the plugin
+    # to convert the result into the desired set of attributes.
+    # The converter must create a log for the system administrator
+    # if the provided inputs do not match expectations.
+    # Note that the converter will be expected to output the
+    # set of attributes listed under the respective ``[kyc-check-*]``
+    # sections. Calling the converter with ``--list-outputs``
+    # should generate a (newline-separated) list of attributes
+    # the converter promises to generate in its JSON output
+    # (when run regularly).
+    CONVERTER = taler-exchange-helper-$NAME
 
 
 Configuration of possible KYC/AML checks
@@ -406,12 +676,20 @@ providers, one per configuration section:
     # still have to pay for it). Used to offer the
     # SPA to display checks even if they are
     # not required. Default is NO.
+    # Since **vATTEST**.
     VOLUNTARY = YES/NO
 
-    # Provider name, if type is LINK
-    PROVIDER_NAME = name
+    # Provider id, present only if type is LINK.
+    PROVIDER_ID = id
 
-    # Provider name, if type is FORM
+    # Name of the SPA form, if type is FORM
+    # "INFO" and "LINK" are reserved and must not be used.
+    # The exchange server and the SPA must agree on a list
+    # of supported forms and the resulting attributes.
+    #
+    # The SPA should include a JSON resource file
+    # "forms.json" mapping form names to arrays of
+    # attribute names each form provides.
     FORM_NAME = name
 
     # Descriptions to use in the SPA to display the check.
@@ -427,6 +705,12 @@ providers, one per configuration section:
     # when they configure measures.
     REQUIRES = requirement;
 
+    # Description of the outputs provided by the check.
+    # Basically, the check's output is expected to
+    # provide the following fields as inputs into
+    # a subsequent AML program.
+    OUTPUTS = business_name street city country registration
+
     # **original** measure to take if the check fails
     # (for any reason, e.g. provider or form fail to
     # satisfy constraints or provider signals user error)
@@ -463,17 +747,26 @@ configuration section:
     # display *all* of these measures to the user.
     # (they have a choice of either which ones, or in
     # which order they are to be performed).
+    # A special measure "verboten" is used if the
+    # threshold may never be crossed.
     NEXT_MEASURES = SWISSNESS KYB
 
     # Context for each of the above measures, optional.
     MEASURE_CONTEXT_$NAME = CONTEXT
 
-    # AND if all REQUIRED_MEASURES will eventually need
-    # to be satisfied, OR if the user has a choice between
+    # "yes" if all REQUIRED_MEASURES will eventually need
+    # to be satisfied, "no" if the user has a choice between
     # them. Not actually enforced by the exchange, but
     # primarily used to inform the user whether this is
-    # an "and" or "or".
-    COMBINATOR = AND|OR
+    # an "and" or "or". YES for "and".
+    AND_COMBINATOR = YES
+
+    # YES if the rule (specifically, operation type,
+    # threshold, timeframe) and the general nature of
+    # the next measure (verboten or approval required)
+    # should be exposed to the client.
+    # Defaults to NO if not set.
+    EXPOSED = YES
 
     # Threshold amount above which the legitimization is
     # triggered.  The total must be exceeded in the given
@@ -506,13 +799,136 @@ AML programs are helper programs that can:
   list of names as the ATTRIBUTES in the
   ``[kyc-provider-]`` configuration section
   (but may also include FORM field names).
-* Process an input JSON object with context and
-  attributes into an *outcome*.  This is the
-  default behavior if no command-line switches
+* Process an input JSON object of type
+  `AmlProgramInput` into a JSON object of
+  type `AmlProgramOutcome`.
+  This is the default behavior if no command-line switches
   are provided.
 
-AML programs are listed in the configuration file,
-one program per section:
+.. ts:def:: AmlProgramInput
+
+  interface AmlProgramInput {
+
+    // JSON object that was provided as
+    // part of the *measure*.  This JSON object is
+    // provided under "context" in the main JSON object
+    // input to the AML program.  This "context" should
+    // satify both the REQUIRES clause of the respective
+    // check and the output of "--requires" from the
+    // AML program's command-line option.
+    context?: Object;
+
+    // JSON object that captures the
+    // output of a ``[kyc-provider-]`` or (HTML) FORM.
+    // The keys in the JSON object will be the attribute
+    // names and the values must be strings representing
+    // the data. In the case of file uploads, the data
+    // MUST be base64-encoded.
+    attributes: Object;
+
+    // JSON array with the results of historic
+    // AML desisions about the account.
+    // FIXME: review AmlDecisionDetail spec!
+    // (need to enable new outcomes!)
+    aml_history: AmlDecisionDetail[];
+
+    // JSON array with the results of historic
+    // KYC data about the account.
+    // FIXME: review KycDetail spec!
+    // (need to include AmlProgramOutcome!)
+    kyc_history: KycDetail[];
+
+  }
+
+.. ts:def:: AmlProgramOutcome
+
+  interface AmlProgramOutcome {
+
+    // Should the client's account be investigated
+    // by AML staff?
+    // Defaults to false.
+    to_investigate?: boolean;
+
+    // Should the client's account be frozen?
+    // Defaults to false.
+    is_frozen?: boolean;
+
+    // Was the client's account reported to the authorities?
+    // Defaults to false.
+    is_reported?: boolean;
+
+    // Free-form properties about the account.
+    // Can be used to store properties such as PEP,
+    // risk category, type of business, hits on
+    // sanctions lists, etc.
+    properties?: Object;
+
+    // Types of events to add to the KYC events table.
+    // (for statistics).
+    events?: string[];
+
+    // When does the outcome expire?
+    expiration: Timestamp;
+
+    // Name of the measure to apply the outcome expires.
+    // If not set, we revert to the default set
+    // of rules (and the default account state).
+    successor_measure: string;
+
+    // Array of KYC rules to apply.  Note that this
+    // array overrides *all* of the default rules.
+    // Thus, if the array does not have an entry for
+    // a particular operation, there would be
+    // no thresholds for that operation!
+    rules: KycRule[];
+
+    // Custom measures that KYC rules may refer to.
+    custom_measures: { "name" : MeasureInformation };
+
+  }
+
+.. ts:def:: KycRule
+
+  interface KycRule {
+
+    // Type of operation to which the rule applies.
+    operation_type: String;
+
+    // Measure to be taken if the given
+    // threshold is crossed over the given timeframe.
+    threshold: Amount;
+
+    // Over which duration should the threshold be
+    // computed.
+    timeframe: RelativeTime;
+
+    // Array of names of measures to apply.
+    // Names listed can be original measures or
+    // custom measures from the `AmlProgramOutcome`.
+    // A special measure "verboten" is used if the
+    // threshold may never be crossed.
+    measures: String[];
+
+    // True if the rule (specifically, operation_type,
+    // threshold, timeframe) and the general nature of
+    // the measures (verboten or approval required)
+    // should be exposed to the client.
+    // Defaults to "false" if not set.
+    exposed?: boolean;
+
+    // True if all the measures will eventually need to
+    // be satisfied, false if any of the measures should
+    // do.
+    and_combinator: boolean;
+  }
+
+If the AML program fails (exits with a failure code or
+does not provide well-formed JSON output) the AML/KYC
+process continues with the FALLBACK measure. This should
+usually be one that asks AML staff to contact the
+systems administrator.
+
+AML programs are listed in the configuration file, one program per section:
 
   .. code-block:: ini
 
@@ -521,8 +937,15 @@ one program per section:
     # Program to run.
     COMMAND = taler-helper-aml-pep
 
-    # Enabled (default is NO)
-    ENABLED = NO
+    # Human-readable description of what this
+    # AML helper program will do. Used to show
+    # to the AML staff.
+    DESCRIPTION = "check if the customer is a PEP"
+
+    # True if this AML program is enabled (and thus can be
+    # used in measures and exposed to AML staff).
+    # Optional, default is NO.
+    ENABLED = YES
 
     # **original** measure to take if COMMAND fails
     # Usually points to a measure that asks AML staff
@@ -531,37 +954,6 @@ one program per section:
     # failure.
     FALLBACK = MEASURE_NAME
 
-The JSON input of an AML program consists of three parts:
-
-* "context": JSON object that was provided as
-  part of the *measure*.  This JSON object is
-  provided under "context" in the main JSON object
-  input to the AML program.  This "context" should
-  satify both the REQUIRES clause of the respective
-  check and the output of "--requires" from the
-  AML program's command-line option.
-* "attributes": JSON object that captures the
-  output of a ``[kyc-provider-]`` or (HTML) FORM.
-  The keys in the JSON object will be the attribute
-  names and the values must be strings representing
-  the data. In the case of file uploads, the data
-  MUST be base64-encoded.
-* "history": JSON array with the results of historic
-  data collected about the user.
-
-The output of an AML programs must be JSON objects which must state:
-
-* outcome: what to do with the client's account
-* expiration_date: when does the decision expire (zero to take the next 
measure immediately)
-* combinator: "AND" if all of the 'next_measures' will eventually need to be 
satisfied, "OR" if those are choices and the user only has to satisfy one of 
them.
-* next_measures: measures to trigger upon expiration of the current outcome; 
array entries must be either a string with the name of an **original** 
context-free measure, or JSON objects with the same information that is usually 
in ``[kyc-measures-]`` configuration sections (with a check name, context, and 
AML program name).
-
-If the AML program fails (exits with a failure code or
-does not provide well-formed JSON output) the AML/KYC
-process continues with the FALLBACK measure. This should
-usually be one that asks AML staff to contact the
-systems administrator.
-
 
 Configuration of measures
 ^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -578,8 +970,7 @@ Finally, the configuration specifies a set of
     # (on an empty set of attributes).
     CHECK_NAME = IB_FORM
 
-    # Context for the check.
-    # The context can be
+    # Context for the check. The context can be
     # just an empty JSON object if there is none.
     CONTEXT = {"choices":["individual","business"]}
 
@@ -587,16 +978,15 @@ Finally, the configuration specifies a set of
     # determine the outcome and next measure.
     PROGRAM = taler-aml-program
 
-If no ``CHECK_NAME`` is provided at all, the
-AML ``PROGRAM`` is to be run immediately.  This is
-useful if no client-interaction is required to
-arrive at a decision.
+If no ``CHECK_NAME`` is provided at all, the AML ``PROGRAM`` is to be run
+immediately.  This is useful if no client-interaction is required to arrive at
+a decision.
 
 .. note::
 
-   The list of *measures* is not complete: AML staff may freely define new
-measures dynamically, usually by selecting checks, an AML program, and
-providing context.
+  The list of *measures* is not complete: AML staff may freely define new
+  measures dynamically, usually by selecting checks, an AML program, and
+  providing context.
 
 
 Sanity checking
@@ -717,7 +1107,7 @@ on GET ``/deposits/`` with the respective legitimization 
requirement row.
   COMMENT ON COLUMN legitimization_outcomes.is_active
     IS 'TRUE if this is the current authoritative legitimization outcome';
   COMMENT ON COLUMN legitimization_outcomes.new_rules
-    IS 'JSON-encoding of KYC-rules to apply to the various operation types for 
this account; KYC check should first check if active new rules for a given 
account exist (and apply specified measures); if not, it should check the 
default rules to decide if a measure is required';
+    IS 'JSON array of KycRule objects to apply to the various operation types 
for this account; all KYC checks should first check if active new rules for a 
given account exist in this table (and apply specified measures); if not, it 
should check the default rules to decide if a measure is required';
 
   CREATE INDEX legitimization_outcomes_active
     ON legitimization_outcomes(h_payto)
@@ -858,8 +1248,8 @@ the description of the check.
 Merchant modifications
 ^^^^^^^^^^^^^^^^^^^^^^
 
-A new setting is required where the merchant backend
-can be configured for a business (default) or individual.
+A new setting is required where the merchant backend can be configured for a
+business (default) or individual.
 
 We introduce new ``kyc_ok``, ``aml_decision``, ``kyc_timestamp`` and
 ``exchange_kyc_serial`` fields into a new table ``merchant_kyc`` with primary
@@ -1056,6 +1446,40 @@ For ``/kyc-webhook/``:
   to tell us anything for sure.  The result is then returned.
 
 
+Types of KYC events
+^^^^^^^^^^^^^^^^^^^
+
+The ``/aml/kyc-statistics`` endpoint exposes statistics
+for various KYC event types.
+
+We will initially support the use of the following types
+of KYC events in the SPA (and have a dialog to show the
+total number of any of these for any specified time range):
+
+* account-open
+* account-closed
+* voluntary-sar
+* mandatory-sar
+* pep-started
+* pep-ended
+* risky-started
+* risky-ended
+* account-frozen
+* account-unfrozen
+
+Based on these, the SPA should also be albe to show active
+statistics (for any given timestamp) on the total number of:
+
+* open accounts
+* frozen accounts
+* high-risk accounts
+* PEPs served
+
+.. note::
+
+   This can be done by simply running the queries with
+   a start time of zero and subtracting.
+
 
 Alternatives
 ============

-- 
To stop receiving notification emails like this one, please contact
gnunet@gnunet.org.



reply via email to

[Prev in Thread] Current Thread [Next in Thread]