summaryrefslogtreecommitdiff
path: root/design-documents
diff options
context:
space:
mode:
authorChristian Grothoff <christian@grothoff.org>2024-04-22 11:17:14 +0200
committerChristian Grothoff <christian@grothoff.org>2024-04-22 11:17:14 +0200
commitbde37ff47cd9151a2a8726dfdf27729c32d92ee0 (patch)
treed72c58405d121c08c9c6d2d9d8d7670fb51d0182 /design-documents
parent26d8e7ad3253147eeb9be1f8162d9bc81a932e87 (diff)
downloaddocs-bde37ff47cd9151a2a8726dfdf27729c32d92ee0.tar.gz
docs-bde37ff47cd9151a2a8726dfdf27729c32d92ee0.tar.bz2
docs-bde37ff47cd9151a2a8726dfdf27729c32d92ee0.zip
clarifications to DD23 based on feedback from Florian
Diffstat (limited to 'design-documents')
-rw-r--r--design-documents/023-taler-kyc.rst339
1 files changed, 205 insertions, 134 deletions
diff --git a/design-documents/023-taler-kyc.rst b/design-documents/023-taler-kyc.rst
index c6898eab..268d6e44 100644
--- a/design-documents/023-taler-kyc.rst
+++ b/design-documents/023-taler-kyc.rst
@@ -112,7 +112,8 @@ For each account we must:
* define risk-profile (902.4, 905.1)
* document the specific setup, likely not just the INI file
-* should have some key AMLA file attributes, such as:
+* should have some key Anti-Money-Laundering Act (AMLA)
+ file attributes, such as:
* File opened, file closed (keep data for X years afterwards!)
* low-risk or high-risk business relationship
@@ -145,6 +146,21 @@ be tracked in the system statistics:
* account frozen
* account unfrozen
* 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!?
Security requirements
@@ -177,19 +193,51 @@ user for *voluntary* KYC processes related to attestation (#7365).
Proposed Solution
=================
-We allow certain *conditions* to *trigger* a single specific *measures*.
-For the different *measures*, we define:
-
-* Who has to do something (AML staff, user, nobody)
-* Contextual input data to be provided (with templating, e.g. amount set dynamically based on the *trigger*)
-* A *check* to be performed (user-interactive or staff-interactive)
-* Another *measure* to take on failure of a user-interactive check
-* A *program* that uses data from the *check* as well as *context* data
- to determine an *outcome* which is the specific operational state
- (normal, held on staff, held on user, frozen, etc.) the account is to transition to
-* What information about the state to show to the user (normal, information required, pending, etc.)
-
-For the user-interactive checks we need a SPA (for KYC) that is given:
+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.
+
+For any possible *measures*, we define:
+
+* Contextual input data to be provided (with dynamic inputs,
+ e.g. amount set dynamically based on the *trigger* could be
+ in the context)
+* A *check* to be performed (checks can be user-interactive (LINK, FORM)
+ or staff-interactive (INFO))
+* A fallback *measure* to take on failure of a user-interactive check
+ (if the check fails, we cannot run the AML *program* as required inputs
+ might be missing!)
+* An (AML) *program* that uses *attribtes* from the *check* as well as
+ *context* data to determine an *outcome* represented as the
+ `AmlOutcome`.
+
+"verboten" is the name of a special *measure*, which means that crossing the
+respective transaction threshold is categorically not allowed (for this
+account). "verboten" with a threshold of zero can be used to freeze funds.
+
+Possible *outcomes* of a measure include:
+
+* The next operational state (normal, AML investigation) of the account
+ (basically, whether to add it to the work list of AML staff).
+* A new set of *rules* in the form of a `LegitimizationRuleSet` that
+ determines custom rules to apply to transactions involving the account;
+ such rules may be used to block certain transactions by using the
+ "verboten" measure. The `LegitimizationRuleSet` also must specify
+ an *expiration* time by which we fall back to a successor measure
+ *or* to the default rules.
+* A (largely) free-form set of `AccountProperties` that AML staff can
+ use to tag accounts with. Some default properties are defined, but
+ the exchange does not do anything with these and AML SPAs are free to
+ use any properties they like. Account properties are only exposed
+ to AML staff and never to the customer.
+* A set of *events* that are to be added to the timeline of the
+ operator for statistical purposes.
+
+For the user-interactive *checks* we need a KYC SPA that is given:
* instructions to render (with either a form to fill or links to external checks);
here the context could provide an array of choices!
@@ -197,27 +245,22 @@ For the user-interactive checks we need a SPA (for KYC) that is given:
should only do one at a time, and probably should then always redirect the
browser to that check.
-For the staff-interactive checks we need a SPA (for AML):
+For the staff-interactive *checks* we need an AML SPA:
* to file forms and upload documentation (without state transition)
* to decide on next measure (providing context); here, the exchange needs
to expose the list of available *measures* and required *context* for each
-For non-interactive measures (normal operation, account frozen) we need:
-
-* Expiration time (in context)
-* Measure to trigger upon expiration, again with context
- (renew documents, resume normal operation, etc.)
-
We need some customer-driven interactivity in KYB/KYC process, for example the
user may need to be given choices (address vs. phone, individual vs. business,
order in which to provide KYC data of beneficiaries). As a result, the
-exchange needs to serve some SPA for measures where the user is shown the next
-step(s) or choices (which person to collect KYC data on, whether to run
+exchange needs to serve some SPA for *measures* where the user is shown the
+next step(s) or choices (which person to collect KYC data on, whether to run
challenger on phone number of physical address, etc.). The SPA should also
potentially contain a form to allow the customer to directly upload documents
to us (like business registration) instead of to some KYC provider. This is
-because KYC providers may not be flexible enough.
+because KYC providers may not be flexible enough. The SPA should also allow
+the customer to perform KYC checks voluntarily.
Similarly, the AML staff will need to be able to trigger rather complex
KYB/KYC processes, like "need KYC on X and Y and Z" or "phone number or
@@ -229,34 +272,53 @@ documents.
Terminology
^^^^^^^^^^^
+* **Attributes**: Attributes are used to represent KYC data obtained about
+ an account holder. Attributes include passport images, address data,
+ business registration documents, and indeed arbitrary forms filed by
+ AML staff or the customer themselves. Attribute data is considered
+ sensitive private information and is thus stored encrypted within the
+ exchange database.
+
* **Check**: A check establishes a particular attribute of a user, such as
their name based on an ID document and lifeness, mailing address, phone
number, taxpayer identity, etc. Checks may be given *context* (such as
whether a customer is an individual or a business) to run correctly. Checks
can also be AML staff inserting information for plausibilization. Checks
- result in an *outcome* being decided by an external AML *program*.
+ result in *attributes* about the account's owner which are given to an
+ external AML *program* together with the *context* to determine an *outcome*.
+ KYC checks are always specified with a fallback *measure* to be taken if
+ the check fails.
* **Condition**: A condition specifies when KYC is required. Conditions
include the *type of operation*, a threshold amount (e.g. above EUR:1000)
and possibly a time period (e.g. over the last month).
* **Configuration**: The configuration determines the *legitimization rules*,
- and specifies which providers offer which *checks* at what *cost*.
+ and specifies which providers offer which *checks*.
* **Context**: Context is information provided as input into a *check* and
*program* to customize their execution. The context is initially set by the
- *trigger*, but may evolve as the *account* undergoes *measures*. For each
- *check* and *program*, the required *context* data must be specified.
-
-* **Cost**: How much would a client have to pay for a KYC process (if they
- voluntarily choose to do so for attestation).
-
-* **Expiration**: KYC legitimizations may be outdated. Expiration rules
- determine when *checks* have to be performed again.
-
-* **Legitimization rules**: The legitimization rules determine under which
- *conditions* which *checks* must be performend and the *expiration* time
- period for the *checks*.
+ *measure* (possibly including data from the *trigger*). Naturally, the
+ *program* may use its `AmlProgramInput` which includes *context* and
+ *attribute* data to compute an update *context* for the next set of
+ *measures* that it specifies in the `LegitimizationRuleSet` as part
+ of the `AmlOutcome`. Thus, *context* is something that typically
+ evolves as the *account* undergoes *measures*. Context is lost if
+ an account transitions to default *legitimization rules* due to
+ *expiration*.
+
+* **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
+ when a new *measure* is triggered in the absence of a transaction crossing
+ thresholds in the current set of *legtimization rules*.
+
+* **Legitimization rules**: The *legitimization rules* determine under which
+ *conditions* which *measures* will be taken. A `LegitimizationRuleSet`
+ always also includes an *expiration* time period for (custom, non-default)
+ *legitimization rules* after which a fallback measure* will automatically
+ apply. Legitimization rules may be *exposed* to the client (for example,
+ to allow a wallet to stay below hard withdraw thresholds) or could be secret.
* **Logic**: Logic refers to a specific bit of code (realized as an exchange
plugin) that enables the interaction with a specific *provider*. Logic
@@ -266,17 +328,19 @@ 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. 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 client (for example, to allow a
- wallet to stay below hard withdraw thresholds).
+ some *context* and a *check* to be performed as well as an AML *program*
+ which determines the *outcome*. We generally distinguish between
+ "original" measures (defined globally in the exchange configuration) and
+ "custom" measures (defined specifically for an account by AML staff).
+
+* **Outcome**: An `AmlOutcome` describes the account state that an account
+ ends up in due to either an AML staff action or an AML *program* doing some
+ computation over the attributes resulting from a *check*. Outcomes can be
+ that certain types of transactions are "verboten", that the account is (or
+ remains) under investigation by AML staff, that the account is given certain
+ properties, and/or that certain events are to be logged. Outcomes also
+ include a new set of *legitimization rules* to apply (and an *expiration*
+ time at which point a successor *measure* will be automatically taken).
* **Provider**: A provider performs a specific set of *checks* at a certain
*cost*. Interaction with a provider is performed by provider-specific
@@ -286,7 +350,10 @@ Terminology
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.
+ ``held-for-manual-review`` state. AML programs are always specified
+ with a fallback *measure* to be taken if the program fails.
+
+* **Trigger**: A specific transaction that satisfies a **Condition**.
* **Type of operation**: The operation type determines which Taler-specific
operation has triggered the KYC requirement. We support four types of
@@ -297,6 +364,13 @@ Terminology
Account owner authentication
^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+Access to the KYC SPA (or rather, its account-specific state) is controlled by
+a *target token* (which is effectively like a bearer token, except passed
+inside the URL). The *target token* ensures that only the account owner has
+access to the KYC processes. It can be obtained by authenticating using
+either the merchant private key or reserve private key, depending on the type
+of the account (IBAN or wallet-reserve respectively).
+
When we need to authenticate a bank account owner, we will simply require them
to make an outgoing wire transfer into the exchange bank account with a public
key in the wire transfer subject (just like when withdrawing), but augmented
@@ -357,11 +431,19 @@ body.
// the initial request for the KYC status using the corresponding
// private key. Will be either a reserve public key or a merchant
// (instance) public key.
- account_pub: EddsaPublicKey;
-
- // Legitimization target that the merchant should
- // use to check for its KYC status using
- // the ``/kyc-check/$REQUIREMENT_ROW`` endpoint.
+ //
+ // Absent if no public key is currently associated
+ // with the account and the client MUST thus first
+ // credit the exchange via an inbound wire transfer
+ // to associate a public key with the debited account.
+ account_pub?: EddsaPublicKey;
+
+ // Identifies a set of measures that were triggered and that are
+ // now preventing this operation from proceeding. Gives the
+ // account holder a starting point for understanding why the
+ // transaction was blocked and how to lift it. The account holder
+ // should use the number to check for the account's AML/KYC status
+ // using the ``/kyc-check/$REQUIREMENT_ROW`` endpoint.
requirement_row: Integer;
}
@@ -372,11 +454,14 @@ New endpoints
.. http:get:: /kyc-check/$REQUIREMENT_ROW
- Checks the KYC status of a particular payment target and possibly begins the
- KYC process. This endpoint is typically used by wallets or merchants that
- have been told about a KYC requirement and now want to check if the KYC
- requirement has been fulfilled. Long-polling may be used to instantly
- observe a change in the KYC requirement status.
+ Checks the KYC status of a particular payment target and possibly begins a
+ KYC process by allowing the customer to choose the next KYC measure to
+ satisfy. This endpoint is typically used by wallets or merchants that
+ have been told that a transaction is not happening because it triggered
+ some KYC/AML measure and now want to check how the KYC/AML
+ requirement could be fulfilled (or whether it already has been
+ statisfied and the operation can now proceed). Long-polling may be used
+ to instantly observe a change in the KYC requirement status.
The requirement row of the ``/kyc-check/`` endpoint encodes the
legitimization measure's serial number. It is returned in
@@ -428,7 +513,7 @@ New endpoints
The exchange is not configured to perform KYC and thus
the legal requirements are already satisfied.
:http:statuscode:`403 Forbidden`:
- The provided hash does not match the requirement row.
+ The provided signature is not acceptable for the requirement row.
:http:statuscode:`404 Not found`:
The requirement row is unknown.
@@ -458,6 +543,9 @@ New endpoints
// proceed with the KYC process (optional if
// the status type is ``200 Ok``, mandatory if the
// HTTP status is ``202 Accepted``).
+ // This URL will encode the *target token* and
+ // should in practice always point to the
+ // KYC SPA (`/kyc-spa/$TARGET_TOKEN`).
kyc_url: string;
// Array with limitations that currently apply to this
@@ -599,9 +687,6 @@ New endpoints
// Since **vATTEST**.
interface KycCheckInformation {
- // How much would this check cost the client?
- cost: Amount;
-
// English description of the check.
description: string;
@@ -689,9 +774,9 @@ New endpoints
``/kyc-proof/$H_PAYTO/$PROVIDER_SECTION`` 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. This endpoint deliberately does
- not use the ``$TARGET_TOKEN`` as the provider should not learn that token.
+ status of the user. The logic plugin should redirect the user to the KYC
+ SPA. This endpoint deliberately does not use the ``$TARGET_TOKEN`` as the
+ external KYC provider should not learn that token.
This endpoint is thus accessed from the user's browser at the *end* of a KYC
process, possibly providing the exchange with additional credentials to
@@ -1078,15 +1163,9 @@ New endpoints
// What was the justification given?
justification: string;
- // When does the outcome expire?
- expiration_time: Timestamp;
-
- // KYC rules to apply. Note that this
- // overrides *all* of the default rules
- // until the ``expiration_time`` and specifies
- // the successor measure to apply after the
- // expiration time.
- new_rules: LegitimizationRules;
+ // Outcome of the AML investigation.
+ // Primarily defines new KYC rules to apply.
+ outcome: AmlOutcome;
// When was this decision made?
decision_time: Timestamp;
@@ -1113,7 +1192,7 @@ New endpoints
collection_time: Timestamp;
// Outcome of the AML program.
- outcome: AmlProgramOutcome;
+ outcome: AmlOutcome;
}
@@ -1153,11 +1232,8 @@ New endpoints
// Identifies a GNU Taler wallet or an affected bank account.
h_payto: PaytoHash;
- // When does the outcome expire?
- expiration_time: Timestamp;
-
// What are the new rules?
- new_rules: LegitimizationRules;
+ new_rules: LegitimizationRuleSet;
// When was the decision made?
decision_time: Timestamp;
@@ -1336,18 +1412,16 @@ configuration section:
# or WALLET-BALANCE.
OPERATION_TYPE = WITHDRAW
- # Next measures to be performed. The SPA should
- # 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.
+ # Space-separated list of next measures to be performed.
+ # The SPA should 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 name "verboten" is used if the
+ # specified threshold may never be crossed
+ # (under this set of rules).
NEXT_MEASURES = SWISSNESS KYB
- # Context for each of the above measures, optional.
- MEASURE_CONTEXT_$NAME = CONTEXT
-
- # "yes" if all REQUIRED_MEASURES will eventually need
+ # "yes" if all NEXT_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
@@ -1363,13 +1437,13 @@ configuration section:
# Threshold amount above which the legitimization is
# triggered. The total must be exceeded in the given
- # timeframe. Can be 'forever'.
- THRESHOLD = AMOUNT
+ # timeframe.
+ THRESHOLD = KUDOS:100
# Timeframe over which the amount to be compared to
- # the THRESHOLD is calculated.
- # Ignored for WALLET-BALANCE.
- TIMEFRAME = DURATION
+ # the THRESHOLD is calculated.
+ # Ignored for WALLET-BALANCE. Can be 'forever'.
+ TIMEFRAME = 30 days
# Enabled (default is NO)
ENABLED = NO
@@ -1394,7 +1468,7 @@ AML programs are helper programs that can:
(but may also include FORM field names).
* Process an input JSON object of type
`AmlProgramInput` into a JSON object of
- type `AmlProgramOutcome`.
+ type `AmlOutcome`.
This is the default behavior if no command-line switches
are provided.
@@ -1429,23 +1503,15 @@ AML programs are helper programs that can:
}
-.. ts:def:: AmlProgramOutcome
+.. ts:def:: AmlOutcome
- interface AmlProgramOutcome {
+ interface AmlOutcome {
// 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
@@ -1456,15 +1522,12 @@ AML programs are helper programs that can:
// (for statistics).
events?: string[];
- // When does the outcome expire?
- expiration_time: Timestamp;
-
// KYC rules to apply. Note that this
// overrides *all* of the default rules
// until the ``expiration_time`` and specifies
// the successor measure to apply after the
// expiration time.
- new_rules: LegitimizationRules;
+ new_rules: LegitimizationRuleSet;
}
@@ -1475,17 +1538,19 @@ AML programs are helper programs that can:
// Type of operation to which the rule applies.
operation_type: string;
- // Measure to be taken if the given
+ // The measures will be taken if the given
// threshold is crossed over the given timeframe.
threshold: Amount;
- // Over which duration should the threshold be
- // computed.
+ // Over which duration should the ``threshold`` be
+ // computed. All amounts of the respective
+ // ``operation_type`` will be added up for this
+ // duration and the sum compared to the ``threshold``.
timeframe: RelativeTime;
// Array of names of measures to apply.
// Names listed can be original measures or
- // custom measures from the `AmlProgramOutcome`.
+ // custom measures from the `AmlOutcome`.
// A special measure "verboten" is used if the
// threshold may never be crossed.
measures: string[];
@@ -1499,7 +1564,10 @@ 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.
+ // do. Primarily used by the SPA to indicate how
+ // the measures apply when showing them to the user;
+ // in the end, AML programs will decide after each
+ // measure what to do next.
// Default (if missing) is false.
is_and_combinator?: boolean;
}
@@ -1629,14 +1697,14 @@ on GET ``/deposits/`` with the respective legitimization requirement row.
COMMENT ON TABLE wire_targets
IS 'All recipients of money via the exchange';
- COMMENT ON COLUMN wire_targets.payto_uri
- IS 'Can be a regular bank account, or also be a URI identifying a reserve-account (for P2P payments)';
COMMENT ON COLUMN wire_targets.h_payto
IS 'Unsalted hash of payto_uri';
COMMENT ON COLUMN wire_targets.target_token
- IS 'high-entropy random value that uniquely identifies the wire target and is used as a token to authorize access to the KYC process (without requiring a signature by target_priv); NULL if KYC is not allowed for the account (legacy)';
+ IS 'high-entropy random value that is used as a token to authorize access to the KYC process (without requiring a signature by target_priv); NULL if KYC is not allowed for the account (legacy)';
COMMENT ON COLUMN wire_targets.target_pub
- IS 'Public key (reserve_pub or merchant_pub) associated with the account; NULL if KYC is not allowed for the account (legacy)';
+ IS 'Public key (reserve_pub or merchant_pub) associated with the account; NULL if KYC is not allowed for the account (if there was no incoming KYC wire transfer yet); updated, thus NOT available to the auditor';
+ COMMENT ON COLUMN wire_targets.payto_uri
+ IS 'Can be a regular bank account, or also be a URI identifying a reserve-account (for P2P payments)';
CREATE TABLE IF NOT EXISTS legitimization_measures
(legitimization_measure_serial_id BIGINT GENERATED BY DEFAULT AS IDENTITY
@@ -1668,8 +1736,6 @@ on GET ``/deposits/`` with the respective legitimization requirement row.
,expiration_time INT8 NOT NULL DEFAULT(0)
,jproperties TEXT,
,to_investigate BOOL NOT NULL
- ,is_frozen BOOL NOT NULL
- ,is_reported BOOL NOT NULL
,is_active BOOL NOT NULL DEFAULT(TRUE)
,jnew_rules NOT NULL TEXT
)
@@ -1687,14 +1753,10 @@ on GET ``/deposits/`` with the respective legitimization requirement row.
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
- IS 'Transactions with this account should be held (until expiration data or AML staff action)';
- COMMENT ON COLUMN legitimization_outcomes.is_reported
- 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.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';
+ IS 'JSON object of type LegitimizationRuleSet 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)
@@ -1744,7 +1806,6 @@ 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_prox BYTEA NOT NULL CHECK (LENGTH(kyc_prox)=32)
,kyc_setup_serial_id INT8 NOT NULL
REFERENCES kyc_setups (kyc_setup_serial_id)
,collection_time INT8 NOT NULL
@@ -1756,8 +1817,6 @@ 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_prox
- IS 'for proximity search on encrypted data';
COMMENT ON COLUMN kyc_attributes.kyc_setup_serial_id
IS 'serial ID of the KYC setup that resulted in these attributes';
COMMENT ON COLUMN kyc_attributes.collection_time
@@ -1818,11 +1877,16 @@ table has is of type `LegitimizationMeasures`:
The ``jnew_rules`` JSON in the ``legitimization_outcomes``
-table has is of type `LegitimizationRules`:
+table has is of type `LegitimizationRuleSet`:
-.. ts:def:: LegitimizationRules
+.. ts:def:: LegitimizationRuleSet
- interface LegitimizationRules {
+ interface LegitimizationRuleSet {
+
+ // When does this set of rules expire and
+ // we automatically transition to the successor
+ // measure?
+ expiration_time: Timestamp;
// Measure to apply when the expiration time is
// reached. If not set, we refer to the default
@@ -1833,7 +1897,8 @@ table has is of type `LegitimizationRules`:
// to this account.
rules: KycRule[];
- // Custom measures that KYC rules may refer to.
+ // Custom measures that KYC rules and the
+ // ``successor_measure`` may refer to.
custom_measures: { "name" : MeasureInformation };
}
@@ -1867,6 +1932,12 @@ however, some common fields are standardized and thus described here.
// operator- or country-dependent.
business_domain?: string;
+ // Is the client's account currently frozen?
+ is_frozen?: boolean;
+
+ // Was the client's account reported to the authorities?
+ was_reported?: boolean;
+
}