summaryrefslogtreecommitdiff
path: root/design-documents/023-taler-kyc.rst
diff options
context:
space:
mode:
authorChristian Grothoff <christian@grothoff.org>2024-04-22 16:48:28 +0200
committerChristian Grothoff <christian@grothoff.org>2024-04-22 16:48:28 +0200
commitd88de457c4d835d323067e25f5e41a06a495fb42 (patch)
tree222f0b8da4fd7db604f912e52ab25e8987fdb9a3 /design-documents/023-taler-kyc.rst
parent4090f56d3bac3d1375b95b8dbdcf3dcb0b69b917 (diff)
downloaddocs-d88de457c4d835d323067e25f5e41a06a495fb42.tar.gz
docs-d88de457c4d835d323067e25f5e41a06a495fb42.tar.bz2
docs-d88de457c4d835d323067e25f5e41a06a495fb42.zip
update DD23
Diffstat (limited to 'design-documents/023-taler-kyc.rst')
-rw-r--r--design-documents/023-taler-kyc.rst87
1 files changed, 60 insertions, 27 deletions
diff --git a/design-documents/023-taler-kyc.rst b/design-documents/023-taler-kyc.rst
index 268d6e44..6b2629c4 100644
--- a/design-documents/023-taler-kyc.rst
+++ b/design-documents/023-taler-kyc.rst
@@ -148,19 +148,26 @@ be tracked in the system statistics:
* account closed
* sanction list import / update
-TODO
-^^^^
-* Need to import new sanction lists (whenever they are
- published) and then check existing AMLA files against
- those lists.
-* New table for form upload data, or re-use
- kyc_attributes table? What about foreign key
- constraints on kyc_attributes in that case?
- Do we just allow NULL for kyc_setup_serial_id if
- we just got a form upload?
-* requirement_row = measure + target? trigger?
- Coherent with what we return from 451!?
+TODO: Sanction lists
+^^^^^^^^^^^^^^^^^^^^
+
+We need to be able to import new sanction lists (whenever they are published)
+and then check existing AMLA files against those lists. Additionally, newly
+created AMLA files must be checked against the current list and some "measure"
+applied in case of a match.
+
+This will primarily require us to define an endpoint to upload a sanction list
+and to define a new table to track the list of sanctioned entities. As it is
+expected that sanction lists will not permit fully automated determinations in
+all cases, an external "sanction check" program should be configured which
+compares records against the current list and determines the correct measure,
+such as no change, further manual review by AML staff, or even automatic
+freeze (and report) depending on how well the records match.
+
+Basically, the "sanction check" program takes the sanction list and an
+attribute set to compute the same kind of `AmlOutcome` that an AML program
+outputs given a context and an attribute set.
Security requirements
@@ -197,9 +204,15 @@ The main state of an account is represented by a set of `KycRules` (the
`LegitimizationRuleSet`) which specify the current *rules* to apply to
transactions involving the account. Rules can *exposed* to the account owner,
or can be secret. Each *rule* specifies certain *conditions* which, if met,
-*trigger* a single specific *measure*. Except for the default rule set, every
-legitimization rule set also has an *expiration* time after which a successor
-*measure* (or the default rule set) is automatically triggered.
+*trigger* a single specific *measure*. After a *rule* was *triggered* and
+before the *outcome* of the respective *measure* has been produced (say
+because the user did not yet enter their data or the AML officer is still
+reviewing the case), the existing rules remain in force. Rules have a display
+priority, and if a second rule with a higher display priority is also
+triggered, the *measures* of the higher-priority rule become the active
+*measures*. Except for the default rule set, every legitimization rule set
+also has an *expiration* time after which a successor *measure* (or the
+default rule set) is automatically triggered.
For any possible *measures*, we define:
@@ -307,6 +320,12 @@ Terminology
an account transitions to default *legitimization rules* due to
*expiration*.
+* **Display priority**: Every rule has a *display priority*. If a second
+ *rule* is *triggered* before the *outcome* of a *rule* could be determined,
+ the *rule* with the larger *display priority* becomes the requirement that
+ the account owner has to satisfy (and that thus will be displayed by the
+ KYC SPA).
+
* **Expiration**: Except for the default rules, any set of KYC rules is
subject to *expiration*. This can be because *attributes* become outdated or
because sanctions have a time limit. The expiration time thus determines
@@ -951,13 +970,13 @@ New endpoints
// Available original measures that can be
// triggered directly by default rules.
- roots: { "$measure_name" : MeasureInformation };
+ roots: { "$measure_name" : MeasureInformation; };
// Available AML programs.
- programs: { "$prog_name" : AmlProgramRequirement };
+ programs: { "$prog_name" : AmlProgramRequirement; };
// Available KYC checks.
- checks: { "$check_name" : KycCheckInformation };
+ checks: { "$check_name" : KycCheckInformation; };
}
@@ -1570,6 +1589,13 @@ AML programs are helper programs that can:
// measure what to do next.
// Default (if missing) is false.
is_and_combinator?: boolean;
+
+ // If multiple rules apply to the same account
+ // at the same time, the number with the highest
+ // rule determines which set of measures will
+ // be activated and thus become visible for the
+ // user.
+ display_priority: integer;
}
If the AML program fails (exits with a failure code or
@@ -1712,6 +1738,7 @@ on GET ``/deposits/`` with the respective legitimization requirement row.
REFERENCES wire_targets (target_token)
,start_time INT8 NOT NULL
,jmeasures VARCHAR[] NOT NULL
+ ,display_priority INT4 NOT NULL
,is_finished BOOL NOT NULL DEFAULT(FALSE)
)
PARTITION BY HASH (h_payto);
@@ -1722,6 +1749,8 @@ on GET ``/deposits/`` with the respective legitimization requirement row.
IS 'Time when the measure was triggered (by decision or rule)';
COMMENT ON COLUMN legitimization_requirements.jmeasures
IS 'JSON object of type LegitimizationMeasures with KYC/AML measures for the account encoded';
+ COMMENT ON COLUMN legitimization_requirements.display_priority
+ IS 'Display priority of the rule that triggered this measure; if in the meantime another rule also triggers, the measure is only replaced if the new rule has a higher display priority';
COMMENT ON COLUMN legitimization_requirements.is_finished
IS 'Set to TRUE if this set of measures was processed; used to avoid indexing measures that are done';
@@ -1806,8 +1835,9 @@ on GET ``/deposits/`` with the respective legitimization requirement row.
(kyc_attributes_serial_id BIGINT GENERATED BY DEFAULT AS IDENTITY
,h_payto BYTEA PRIMARY KEY CHECK (LENGTH(h_payto)=32)
REFERENCES wire_targets (h_payto)
- ,kyc_setup_serial_id INT8 NOT NULL
+ ,kyc_setup_serial_id INT8
REFERENCES kyc_setups (kyc_setup_serial_id)
+ DEFAULT NULL
,collection_time INT8 NOT NULL
,expiration_time INT8 NOT NULL
,trigger_outcome_serial INT8 NOT NULL
@@ -1818,7 +1848,7 @@ on GET ``/deposits/`` with the respective legitimization requirement row.
COMMENT ON COLUMN kyc_attributes.h_payto
IS 'identifies the account this is about';
COMMENT ON COLUMN kyc_attributes.kyc_setup_serial_id
- IS 'serial ID of the KYC setup that resulted in these attributes';
+ IS 'serial ID of the KYC setup that resulted in these attributes, NULL if the attributes are from a form directly supplied by the account owner';
COMMENT ON COLUMN kyc_attributes.collection_time
IS 'when were these attributes collected';
COMMENT ON COLUMN kyc_attributes.expiration_time
@@ -1888,7 +1918,7 @@ table has is of type `LegitimizationRuleSet`:
// measure?
expiration_time: Timestamp;
- // Measure to apply when the expiration time is
+ // Name of the measure to apply when the expiration time is
// reached. If not set, we refer to the default
// set of rules (and the default account state).
successor_measure?: string;
@@ -1899,7 +1929,7 @@ table has is of type `LegitimizationRuleSet`:
// Custom measures that KYC rules and the
// ``successor_measure`` may refer to.
- custom_measures: { "name" : MeasureInformation };
+ custom_measures: { "$measure_name" : MeasureInformation; };
}
@@ -1957,12 +1987,15 @@ exchange. Here we describe the forms that must be supported:
resulting HTML FORM field name must be "choice" and it must be mapped to
strings from the choices list.
-* **UPLOAD**: Asks the client to upload a single file. The context may include
- "extensions: string[]" with a list of allowed file extensions the client's
+* **UPLOAD**: Asks the client to upload a single file.
+ The context must include a ``validity_duration`` which
+ will be converted to the ``expiration_time`` for
+ the uploaded data. The context may furthermore include
+ ``extensions?: string[]`` with a list of allowed file extensions the client's
file must end with (e.g. "png", "pdf", "gif"). In the absence of this
- context, any file may be uploaded. The context may also include
- "size_limit: Integer" with the maximum file size in bytes that can be
- uploaded. The resulting HTML FORM must have two fields, "filename" and
+ context, any file may be uploaded. The context may also include a
+ ``size_limit?: Integer`` with the maximum file size in bytes that can be
+ uploaded. The resulting HTTP POST should provide at least two fields, "filename" and
"filedata". "filename" must be set to the basename of the original file (to
the extend that it is available), and "filedata" to the base64-encoding of
the uploaded data.