summaryrefslogtreecommitdiff
path: root/design-documents
diff options
context:
space:
mode:
authorChristian Grothoff <christian@grothoff.org>2024-04-19 15:44:05 +0200
committerChristian Grothoff <christian@grothoff.org>2024-04-19 15:44:05 +0200
commit4e88432b2de58f09a4ceb84434ce03f649fb1692 (patch)
treedba85737c47ea3842de20ebe9b5479c9e20b33a3 /design-documents
parent51f17bc444a8604253e22c55d09e59c1f871f563 (diff)
downloaddocs-4e88432b2de58f09a4ceb84434ce03f649fb1692.tar.gz
docs-4e88432b2de58f09a4ceb84434ce03f649fb1692.tar.bz2
docs-4e88432b2de58f09a4ceb84434ce03f649fb1692.zip
improve KYC spec
Diffstat (limited to 'design-documents')
-rw-r--r--design-documents/023-taler-kyc.rst115
1 files changed, 94 insertions, 21 deletions
diff --git a/design-documents/023-taler-kyc.rst b/design-documents/023-taler-kyc.rst
index 6ace74cb..28f49461 100644
--- a/design-documents/023-taler-kyc.rst
+++ b/design-documents/023-taler-kyc.rst
@@ -370,8 +370,13 @@ New Endpoints
threshold: Amount;
// True if this is a soft limit that could be raised
- // by passing KYC checks.
- soft: boolean;
+ // by passing KYC checks. Clients *may* deliberately
+ // try to cross limits and trigger measures resulting
+ // in 451 responses to begin KYC processes.
+ // Clients that are aware of hard limits *should*
+ // inform users about the hard limit and prevent flows
+ // in the UI that would cause violations of hard limits.
+ soft_limit: boolean;
}
@@ -639,8 +644,6 @@ New Endpoints
}
-
-
.. http:get:: /aml/$OFFICER_PUB/measures
To enable the AML staff SPA to give AML staff a choice of possible measures, a
@@ -688,8 +691,8 @@ New Endpoints
// Name of an AML program.
prog_name: string;
- // Context for the check. Could be empty.
- context: Object;
+ // Context for the check. Optional.
+ context?: Object;
}
@@ -954,7 +957,7 @@ configuration section:
# them. Not actually enforced by the exchange, but
# primarily used to inform the user whether this is
# an "and" or "or". YES for "and".
- AND_COMBINATOR = YES
+ IS_AND_COMBINATOR = YES
# YES if the rule (specifically, operation type,
# threshold, timeframe) and the general nature of
@@ -1056,19 +1059,19 @@ AML programs are helper programs that can:
// Can be used to store properties such as PEP,
// risk category, type of business, hits on
// sanctions lists, etc.
- properties?: Object;
+ properties?: AccountProperties;
// Types of events to add to the KYC events table.
// (for statistics).
events?: string[];
// When does the outcome expire?
- expiration: Timestamp;
+ expiration_time: 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;
+ successor_measure?: string;
// Array of KYC rules to apply. Note that this
// array overrides *all* of the default rules.
@@ -1078,7 +1081,7 @@ AML programs are helper programs that can:
rules: KycRule[];
// Custom measures that KYC rules may refer to.
- custom_measures: { "name" : MeasureInformation };
+ custom_measures?: { "name" : MeasureInformation };
}
@@ -1114,7 +1117,8 @@ AML programs are helper programs that can:
// True if all the measures will eventually need to
// be satisfied, false if any of the measures should
// do.
- and_combinator: boolean;
+ // Default (if missing) is false.
+ is_and_combinator?: boolean;
}
If the AML program fails (exits with a failure code or
@@ -1251,7 +1255,6 @@ on GET ``/deposits/`` with the respective legitimization requirement row.
REFERENCES wire_targets (h_payto)
,start_time INT8 NOT NULL
,jmeasures VARCHAR[] NOT NULL
- ,is_and_combinator BOOL NOT NULL DEFAULT(FALSE)
,is_finished BOOL NOT NULL DEFAULT(FALSE)
)
PARTITION BY HASH (h_payto);
@@ -1260,10 +1263,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.is_finished
IS 'Set to TRUE if this set of measures was processed; used to avoid indexing measures that are done';
- COMMENT ON COLUMN legitimization_requirements.is_and_combinator
- IS 'Set to TRUE each of the measures will ultimately need to be satisfied; FALSE if the user has the choice to satisfy one of them';
COMMENT ON COLUMN legitimization_requirements.jmeasures
- IS 'array with KYC/AML measures for the account encoded in JSON';
+ IS 'JSON object of type LegitimizationMeasures with KYC/AML measures for the account encoded';
CREATE INDEX ON legitimization_measures (h_payto)
WHERE NOT finished;
@@ -1274,12 +1275,12 @@ on GET ``/deposits/`` with the respective legitimization requirement row.
REFERENCES wire_targets (h_payto)
,decision_time INT8 NOT NULL DEFAULT(0)
,expiration_time INT8 NOT NULL DEFAULT(0)
- ,jproperties VARCHAR,
+ ,jproperties TEXT,
,to_investigate BOOL NOT NULL
,is_frozen BOOL NOT NULL
,is_reported BOOL NOT NULL
,is_active BOOL NOT NULL DEFAULT(TRUE)
- ,new_rules NOT NULL TEXT
+ ,jnew_rules NOT NULL TEXT
)
PARTITION BY HASH (h_payto);
@@ -1292,7 +1293,7 @@ on GET ``/deposits/`` with the respective legitimization requirement row.
COMMENT ON COLUMN legitimization_outcomes.expiration_time
IS 'time when the decision expires and the expiration new_rules should be applied';
COMMENT ON COLUMN legitimization_outcomes.jproperties
- IS 'JSON with account properties, such as PEP status, business domain, risk assessment, etc.';
+ IS 'JSON object of type AccountProperties, such as PEP status, business domain, risk assessment, etc.';
COMMENT ON COLUMN legitimization_outcomes.to_investigate
IS 'AML staff should investigate the activity of this account';
COMMENT ON COLUMN legitimization_outcomes.is_frozen
@@ -1301,8 +1302,8 @@ on GET ``/deposits/`` with the respective legitimization requirement row.
IS 'Set to TRUE if the activity of the account was reported to authorities';
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 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';
+ COMMENT ON COLUMN legitimization_outcomes.jnew_rules
+ IS 'JSON object of type LegitimizationRules with rules 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)
@@ -1407,6 +1408,78 @@ on GET ``/deposits/`` with the respective legitimization requirement row.
CREATE INDEX kyc_event_index
ON kyc_events(event_type,event_timestamp);
+
+The ``jmeasures`` JSON in the ``legitimization_measures``
+table has is of type `LegitimizationMeasures`:
+
+.. ts:def:: LegitimizationMeasures
+
+ interface LegitimizationMeasures {
+
+ // Array of legitimization measures that
+ // are to be applied.
+ measures: MeasureInformation[];
+
+ // True if the client is expected to eventually satisfy all requirements.
+ // Default (if missing) is false.
+ is_and_combinator?: boolean;
+ }
+
+
+The ``jnew_rules`` JSON in the ``legitimization_outcomes``
+table has is of type `LegitimizationRules`:
+
+.. ts:def:: LegitimizationRules
+
+ interface LegitimizationRules {
+
+ // 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;
+
+ // Legitimization rules that are to be applied
+ // to this account.
+ rules: KycRule[];
+
+ // Custom measures that KYC rules may refer to.
+ custom_measures: { "name" : MeasureInformation };
+ }
+
+
+The ``jproperties`` JSON in the ``legitimization_outcomes`` table has is of
+type `AccountProperties`. All fields in this object are optional. The actual
+properties collected depend fully on the discretion of the exchange operator;
+however, some common fields are standardized and thus described here.
+
+.. ts:def:: AccountProperties
+
+ interface AccountProperties {
+
+ // True if this is a politically exposed account.
+ // Rules for classifying accounts as politically
+ // exposed are country-dependent.
+ pep?: boolean;
+
+ // True if this is a sanctioned account.
+ // Rules for classifying accounts as sanctioned
+ // are country-dependent.
+ sanctioned?: boolean;
+
+ // True if this is a high-risk account.
+ // Rules for classifying accounts as at-risk
+ // are exchange operator-dependent.
+ high_risk?: boolean;
+
+ // Business domain of the account owner.
+ // The list of possible business domains is
+ // operator- or country-dependent.
+ business_domain?: string;
+
+ }
+
+
+
KYC forms
^^^^^^^^^