summaryrefslogtreecommitdiff
path: root/design-documents/023-taler-kyc.rst
diff options
context:
space:
mode:
authorChristian Grothoff <christian@grothoff.org>2024-04-19 14:22:44 +0200
committerChristian Grothoff <christian@grothoff.org>2024-04-19 14:22:44 +0200
commitb61c23faa8c619595e642c4a902f51ad7bb2f060 (patch)
treed809ab70442b8e5050fef15e9c8ea08132e2f5f9 /design-documents/023-taler-kyc.rst
parentcd3ff64300bda3616f68a0c0e60673e11c47fa53 (diff)
downloaddocs-b61c23faa8c619595e642c4a902f51ad7bb2f060.tar.gz
docs-b61c23faa8c619595e642c4a902f51ad7bb2f060.tar.bz2
docs-b61c23faa8c619595e642c4a902f51ad7bb2f060.zip
improve KYC spec
Diffstat (limited to 'design-documents/023-taler-kyc.rst')
-rw-r--r--design-documents/023-taler-kyc.rst215
1 files changed, 200 insertions, 15 deletions
diff --git a/design-documents/023-taler-kyc.rst b/design-documents/023-taler-kyc.rst
index 1eb0669e..c41a3695 100644
--- a/design-documents/023-taler-kyc.rst
+++ b/design-documents/023-taler-kyc.rst
@@ -236,21 +236,138 @@ Terminology
New Endpoints
^^^^^^^^^^^^^
-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
-initiate a KYC process are not very sensitive.) Given this triplet, the
-``/kyc-check/`` endpoint returns either the (positive) KYC status or redirects
-the client (202) to the next required stage of the KYC process. The
-redirection must be for an HTTP(S) endpoint to be triggered via a simple HTTP
-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.
+.. http:get:: /kyc-check/$REQUIREMENT_ROW/$H_PAYTO
+
+ Checks the KYC status of a particular payment target and possibly begins the
+ KYC process. This endpoint is 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.
+
+ The ``/kyc-check/`` endpoint is based on the legitimization requirements
+ serial number. FIXME: is this still OK?
+
+ Access is ``authenticated`` by also passing the hash of the payto://-URI.
+ (Weak authentication is acceptable, as the KYC status or the ability to
+ initiate a KYC process are not very sensitive.) Given this triplet, the
+ ``/kyc-check/`` endpoint returns either the (positive) KYC status or redirects
+ the client (202) to the next required stage of the KYC process. The
+ redirection must be for an HTTP(S) endpoint to be triggered via a simple HTTP
+ 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.
+
FIXME: update /kyc-check/ endpoint to expose *public* outcomes of previous
checks (such as hard withdrawal limits)!
+ **Request:**
+
+ :query timeout_ms=NUMBER: *Optional.* If specified, the exchange will
+ wait up to ``timeout_ms`` milliseconds if the payment target
+ is currently not legitimized. Ignored if the payment target
+ is already legitimized. Note that the legitimization would be
+ triggered by another request to the same endpoint with a valid
+ ``token``.
+
+ **Response:**
+
+ :http:statuscode:`200 Ok`:
+ The KYC operation succeeded, the exchange confirms that the
+ payment target already authorized to transact.
+ The response will be an `AccountKycStatus` object.
+ :http:statuscode:`202 Accepted`:
+ The user should be redirected to the provided location to perform
+ the required KYC checks to satisfy the legal requirements. Afterwards, the
+ ``/kyc-check/`` request should be repeated to check whether the
+ user has completed the process.
+ The response will be an `AccountKycRedirect` object.
+ :http:statuscode:`204 No content`:
+ The exchange is not configured to perform KYC and thus
+ the legal requirements are already satisfied.
+ :http:statuscode:`402 Payment Required`:
+ The client must pay the KYC fee for the KYC process.
+ **This is currently not implemented, see #7365.**
+ :http:statuscode:`403 Forbidden`:
+ The provided hash does not match the payment target.
+ :http:statuscode:`404 Not found`:
+ The payment target is unknown.
+ :http:statuscode:`451 Unavailable for Legal Reasons`:
+ The transaction cannot be completed due to AML rules.
+ Thus, the operation is currently not stuck on KYC, but
+ on exchange staff performing their AML review. The user
+ should be told to wait and/or contact the exchange operator
+ if the situation persists.
+ The response will be a `AccountAmlBlocked` object.
+
+ **Details:**
+
+ .. ts:def:: AccountKycStatus
+
+ interface AccountKycStatus {
+
+ // Details about the KYC check that the user
+ // passed.
+ kyc_details: KycDetails;
+
+ // Current time of the exchange, used as part of
+ // what the exchange signs over.
+ now: Timestamp;
+
+ // EdDSA signature of the exchange affirming the account
+ // is KYC'ed, must be of purpose
+ // ``TALER_SIGNATURE_EXCHANGE_ACCOUNT_SETUP_SUCCESS``
+ // and over ``TALER_AccountSetupStatusSignaturePS``.
+ exchange_sig: EddsaSignature;
+
+ // public key used to create the signature.
+ exchange_pub: EddsaPublicKey;
+
+ // Current AML state for the target account. Non-zero
+ // values indicate that the transfer is blocked due to
+ // AML enforcement.
+ aml_status: Integer;
+
+ }
+
+ .. ts:def:: AccountKycRedirect
+
+ interface AccountKycRedirect {
+
+ // URL that the user should open in a browser to
+ // proceed with the KYC process.
+ kyc_url: string;
+
+ // Current AML state for the target account. Non-zero
+ // values indicate that the transfer is blocked due to
+ // AML enforcement.
+ aml_status: Integer;
+
+ }
+
+ .. ts:def:: AccountAmlBlocked
+
+ interface AccountAmlBlocked {
+
+ // Current AML state for the target account. Non-zero
+ // values indicate that the transfer is blocked due to
+ // AML enforcement.
+ aml_status: Integer;
+
+ }
+
+ .. ts:def:: KycDetails
+
+ // Object that specifies which KYC checks are satisfied.
+ interface KycDetails {
+
+ // Keys are the names of the check(s).
+ // The values are for now always empty objects.
+
+ }
+
+
+
.. http:get:: /kyc-spa/{$HASH,$FILENAME}
A set of ``/kyc-spa/$HASH`` GET endpoints is created per client ``$HASH``
@@ -439,7 +556,7 @@ checks (such as hard withdrawal limits)!
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``
+.. http:post:: /kyc-wallet``
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
@@ -452,6 +569,68 @@ checks (such as hard withdrawal limits)!
cryptographically enforce this), such modifications are a terms of service
violation which may have legal consequences for the user.
+ Setup KYC identification for a wallet. Returns the KYC UUID.
+ This endpoint is used by compliant Taler wallets when they
+ are about to hit the balance threshold and thus need to have
+ the customer provide their personal details to the exchange.
+ The wallet is identified by its long-lived reserve public key
+ (which is used for P2P payments, not for withdrawals).
+
+ **Request:**
+
+ The request body must be a `WalletKycRequest` object.
+
+ **Response:**
+
+ :http:statuscode:`204 No Content`:
+ KYC is disabled at this exchange, or the balance
+ is below the threshold that requires KYC, or this
+ wallet already satisfied the KYC check for the
+ given balance.
+ :http:statuscode:`403 Forbidden`:
+ The provided signature is invalid.
+ This response comes with a standard `ErrorDetail` response.
+ :http:statuscode:`451 Unavailable for Legal Reasons`:
+ The wallet must undergo a KYC check. A KYC ID was created.
+ The response will be a `WalletKycUuid` object.
+
+ **Details:**
+
+ .. ts:def:: WalletKycRequest
+
+ interface WalletKycRequest {
+
+ // Balance threshold (not necessarily exact balance)
+ // to be crossed by the wallet that (may) trigger
+ // additional KYC requirements.
+ balance: Amount;
+
+ // EdDSA signature of the wallet affirming the
+ // request, must be of purpose
+ // ``TALER_SIGNATURE_WALLET_ACCOUNT_SETUP``
+ reserve_sig: EddsaSignature;
+
+ // long-term wallet reserve-account
+ // public key used to create the signature.
+ reserve_pub: EddsaPublicKey;
+ }
+
+ .. ts:def:: WalletKycUuid
+
+ interface WalletKycUuid {
+
+ // UUID that the wallet should use when initiating
+ // the KYC check.
+ requirement_row: number;
+
+ // Hash of the payto:// account URI for the wallet.
+ h_payto: PaytoHash;
+
+ }
+
+
+
+
.. http:get:: /aml/$OFFICER_PUB/measures
To enable the AML staff SPA to give AML staff a choice of possible measures, a
@@ -462,7 +641,10 @@ checks (such as hard withdrawal limits)!
**Request**:
- FIXME: see other AML GET requests?
+ *Taler-AML-Officer-Signature*: The client must provide Base-32 encoded EdDSA
+ signature with ``$OFFICER_PRIV``, affirming the desire to obtain AML data.
+ Note that this is merely a simple authentication mechanism, the details of
+ the request are not protected by the signature.
**Response**:
@@ -560,7 +742,10 @@ checks (such as hard withdrawal limits)!
**Request**:
- FIXME: add authorization checks, as with other /aml/ requests.
+ *Taler-AML-Officer-Signature*: The client must provide Base-32 encoded EdDSA
+ signature with ``$OFFICER_PRIV``, affirming the desire to obtain AML data.
+ Note that this is merely a simple authentication mechanism, the details of
+ the request are not protected by the signature.
: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.
@@ -607,7 +792,7 @@ receive wallet-to-wallet payments. Then, *before* a wallet performs an
operation that would cause it to exceed the balance threshold in terms of
funds held from a particular exchange, it *should* first request the user to
complete the KYC process. For that, the wallet should POST to the new
-``/wallet-kyc`` endpoint, providing its long-term reserve-account public key
+``/kyc-wallet`` endpoint, providing its long-term reserve-account public key
and a signature requesting permission to exceed the account limit.