Customer Proof
Info
Relevant JSON-RPC method: custodian_getCustomerProof
Why the Customer proof mechanism is needed¶
Custodians usually provide the ability to create an organisation with multiple different users, wallets and accounts within a wallet tied to the organisation. A user will authenticate the MMI Extension to the custodian using a refresh token more details provided here.
The refresh token is tied to a user who is tied to an organisation. The refresh token also provides authentication and access to one or more accounts. Once a user has imported accounts into the extension see the demo, they can then transact on that account. With MMI, a user can connect to a Dapp, initiate a transaction, confirm that transaction and is then deep-linked into their custodian UI to approve and/or sign transactions. As per the architecture overview, the custodian is required to send a webhook to the MMI backend (MMI API) in order to the extension to receive transaction status updates. To prove that the user is a customer (authenticate the user) and for the correct transaction statuses to be sent to the user that initiated the transaction, we have implemented what we call the customer proof mehcanism.
How the Customer proof mechanism is implemented¶
This custodian is required to implement a method in the JSON-RPC API called custodian_getCustomerProof
. The mechanism produces cryptographically signed tokens for users which prove that they are a customer.
They must be signed using RSA keys known only to the custodian. The custodian will publish the public part of these keys on a JWKS endpoint.
MMI provides a websocket service which communicates transaction updates to users. The purpose of this token is to allow the extension to contact MMI’s APIs as an authenticated user, without using the custodian’s refresh token.
Customer proof claims¶
This token should include the following claims, attested by the custodian:
sub
: The custodian user ID of the user, in any format. This can be in any format, although UUID is common. Any webhooks you send will include the same value asmetadata.userId
.mmi.customerId
: The customer ID of the user. This corresponds to any grouping of users, usually a customer ID or organisation ID. This can be in any format.mmi.customerName
: A human readable name for the entity correspondingiss
: The issuer of the token. This should be the URL of the custodian’s JSON-RPC API. You must provide this value to us when giving us your API URL as it is used to map tokens to issuers.
Verification¶
Verification is performed by MMI’s APIs. The custodian must host an endpoint returning a JSON Web Key Set (JWKS) corresponding to the public part of the keys used to sign the above tokens.
Info
We load these keys at the time when we register a custodian. Please let us know if they change, so that we can load a new set.
Customer proof example¶
Example request from MMI to the custodian API¶
POST http://custodian-api/eth/v1/json-rpc
Content-type: application/json
Authorization: Bearer custodian-access-token
{
"method" : "custodian_getCustomerProof"
"id" : 1,
"params" : []
"jsonrpc": "2.0",
}
Example response¶
{
"id": 1,
"jsonrpc": "2.0",
"result": {
"jwt": "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpc3MiOiJodHRwOi8vY3VzdG9kaWFuLWFwaSIsImlhdCI6MTYyODc4MzcyMiwiZXhwIjoxNjYwMzE5NzIyLCJhdWQiOiIiLCJzdWIiOiIxMjM0LTU2NzgiLCJtbWkiOiJ7XCJ2ZXJzaW9uXCI6XCI5LjguNVwifSJ9.yYSUyOAdDzh9ViSrJsJO6vU-cRESzbu4y7wRFblQ4Po"
}
}
Example response decoded¶
{
"iss": "http://custodian-api",
"iat": 1628783722,
"exp": 1660319722,
"aud": "",
"sub": "1234-5678",
"mmi": { "customerId": "9999-0000", "customerName": "ACME corporation" }
}
FAQ¶
What should we use as a customerId
claim ?¶
The customerId
claim corresponds to the legal entity that is billed for using the extension, e.g. a customer or fund. If you don’t have a concept of a customer, you can repeat the sub
claim.