diff options
author | Christian Grothoff <christian@grothoff.org> | 2024-04-22 11:17:14 +0200 |
---|---|---|
committer | Christian Grothoff <christian@grothoff.org> | 2024-04-22 11:17:14 +0200 |
commit | bde37ff47cd9151a2a8726dfdf27729c32d92ee0 (patch) | |
tree | d72c58405d121c08c9c6d2d9d8d7670fb51d0182 /design-documents | |
parent | 26d8e7ad3253147eeb9be1f8162d9bc81a932e87 (diff) | |
download | docs-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.rst | 339 |
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; + } |