TRP

Authoritative source

Travel Rule Protocol

VersionDateDescription
1.0.019th August 2020Initial Public Version
1.0.110th December 2020Bug fix
1.1.08th February 2021Clarifications, bug fixes and consistency enhancements
2.0.010th May 2021Addition of Travel Address enhanced flow
2.1.031st Oct 2021Travel Address advanced flow with inquiry tag
3.0.015th Feb 2022mTLS for client and server authentication
deprecate enhanced workflow
3.1.026th Jun 2023reworked travel address specification
3.2.010th Jul 2023Add DTI as new token identifier

Executive Summary

Inherently, involvement within the virtual asset ecosystem presents higher risks related to money laundering and terrorist financing than those found in the traditional world of fiat currency. Primarily this is due to the lack of transparency of the public keys, which are not associated with any identity.

Whilst in the traditional world, there is proven infrastructure with processes and tools designed to mitigate AML/CFT risks, given the evolution of the virtual asset ecosystem, there is now a need to find comparable solutions not only to address industry concerns but incoming global regulations. Key operators such as custodians and market participants must consider the following issues or gaps:

  1. The current inability to identify originators and/or beneficiaries of transactions.
  2. Cumbersome processes and governance to be put in place in order to confirm to whom a defined public key belongs.

There are varying approaches across the industry to define a common set of standards and to create a mechanism for the exchange of relevant information including identity and associated address details all using a common infrastructure, protocol and data set.

Introduction

The Travel Rule working group was primarily established to address a specific recommendation issued by the Financial Action Task Force ("FATF"). Members of the working group include leading industry participants from around the world who meet regularly to discuss and agree on finding a common solution to meet the regulatory standards. The information within this paper seeks to highlight a solution, referred herein as the Travel Rule Protocol (TRP).

The TRP vision is to define a set of standards which will allow Virtual Asset Service Providers (VASPs - as defined as in footnote1 below) to safely share with other trusted participants the identity of an originator and beneficiary linked to a specific virtual asset transfer. This set of standards aims to meet the requirements set by the FATF Recommendation 16 (R16), commonly known as the Travel Rule defined as below:

R16 -- Countries should ensure that originating VASPs obtain and hold required and accurate originator information and required beneficiary information on virtual asset transfers, submit the above information to the beneficiary VASP or financial institution (if any) immediately and securely, and make it available on request to appropriate authorities. Countries should ensure that beneficiary VASPs obtain and hold required originator information and required and accurate beneficiary information on virtual asset transfers, and make it available on request to appropriate authorities. Other requirements of R16 (including monitoring of the availability of information, and taking freezing action and prohibiting transactions with designated persons and entities) apply on the same basis as set out in R16. The same obligations apply to financial institutions when sending or receiving virtual asset transfers on behalf of a customer.

It is intended that adoption of the TRP is royalty and license free. However, any fees and licenses related to implementation, service of software providers, etc. will be the responsibility of the implementing VASP, including but not limited to document the legal and contractual arrangement ensuring that any exchange of information is done in compliance with applicable laws, e.g. GDPR.

The TRP has been incrementally developed by a self-selecting group of leading industry participants from around the world, collaborating openly and sharing to develop and evolve the solution. There is no single central body or organization behind the protocol, only collaboration.

The TRP working group has a regular weekly minuted meeting with a set agenda. There are other forums including chat rooms for more frequent collaboration as well as email for more infrequent formal announcements. The working group welcomes all contributions, ideas and input to the design and implementation of the protocol. Industry participants who wish to help developing the protocol, or adopt the protocol are encouraged to register at our form.

Any comments, corrections or suggestions on this version of the protocol specification can also be captured via the GitLab.

Goals

The goal of the TRP is to develop a first-generation, minimal, workable, and pragmatic API specification for compliance with the FATF Travel Rule in a timely manner, that also minimizes fragmentation and maximizes interoperability.

First Generation

Industry participants acknowledge that mainstream adoption of virtual assets as an asset class will take time, and encouragingly there is evidence that its evolution is progressing with increasing focus by regulators and central banks imposing regulatory requirements. The TRP aims to initiate one of the first steps on this journey by launching a first-generation solution for compliance with the FATF Travel Rule.

Minimal, Workable, Pragmatic API

The TRP has been developed with sufficient flexibility allowing straightforward adoption for a wide range of industry participants. By focusing closely on FATF R16 and limiting the scope of the solution, the TRP aims to create a simple API specification for required information exchange that will seamlessly integrate with existing business IT frameworks.

Minimize Fragmentation & Maximize Interoperation

There are a number of potentially more comprehensive Travel Rule solutions in development across the industry participants. By focusing closely on FATF R16 and limiting the scope of the solution, the TRP aims to create a simple API specification for the information exchange that is easy to implement and integrate with existing business solutions, as well as having an easy path to interoperate with other emerging industry Travel Rule solutions as they mature. Any investment made should be transferable to future industry solutions.

Design Philosophy

The underlying design principles of the Travel Rule Protocol:

  1. Compliance with FATF R16
  2. Data privacy: Bilateral exchange for minimal data leakage
  3. Iterative and incremental with early MVP launch
  4. Open for industry collaboration and adoption
  5. Aligned with emerging industry standards such as IVMS101
  6. Any investment made should be transferable to future industry solutions
  7. Each member controls the data that they share

Indication of Requirement Levels

This document follows rfc2119 to indicate requirement levels.

Unspecified Behavior

TRP leaves certain aspects of the protocol unspecified. It is a deliberate decision that enables to accommodate as many use cases as possible. This is a necessity due to the nature of travel rule which spans various jurisdictions and needs to be applicable to a diverse variety of VASPs.

We use the following sanity check when judging about unspecified behavior:

When two VASPs implement a certain aspect differently but still are able to interoperate then we MUST omit detailing that aspect in the specification.

If you have found cases that are unspecified but violate the above sanity check then this is considered a bug and we'd kindly ask you to open an issue.

Example

The layout for callback URLs is unspecified because when two VASPs implement them differently they are still able to interoperate. Leaving them unspecified gives VASPs the freedom to encode any data into the URL that the VASP might find useful. It also allows us to extend the protocol without breaking backwards compatibility with respect to callback URLs.

Travel Address

In TRP, the originator VASP receives a special payment address, called Travel Address, instead of a normal blockchain address from the end user. This Travel Address is a base58check encoded, unique URL with a "ta" string prefix. The encoding MUST use the bitcoin alphabet. The URL MUST contain the query pair t=i which stands for "tag = inquiry". It is used to identify the URL type and to allow for future extensibility. The URL MUST omit the scheme part, e.g. https://. It is already determined in the protocol specification and, hence, redundant information.

The following code defines reference travel address encoding/decoding functions for Python >= 3.9. Error handling has been omitted for brevity.

def encode_travel_address(url: str) -> str:
    import based58
    return f"""ta{based58.b58encode_check(url.removeprefix("https://").encode()).decode()}"""

def decode_travel_address(ta: str) -> str:
    import based58
    return based58.b58decode_check(ta.removeprefix("ta").encode()).decode()

Once the Travel Address is decoded by the originator VASP a request is made to that URL to inquire for permission to execute an transaction.

This mechanism hence allows to:

  • decline transfers
  • conduct KYC checks
  • easily share transaction ids

which solves many practical problems for compliance teams.

The Travel Address is inspired by the LNURL standard but lacks its major shortcomings:

  • base58check results in shorter strings than bech32 used in `LNURL.

  • base58check doesn't have a maximum length limit as opposed to bech32 used in LNURL. Even though the LNURL standard specifically opts out of that limit check (because bech32 is used to encode a URL instead of binary data), in practise it is hard to find libraries that don't enforce that limit.

  • LNURL's name suggests misleadingly that the lightning network is a component of LNURL. While this is strictly not the case we found it hard to explain this to parties not familiar with the LNURL standard.

Travel Address Test Vectors

Encoding

InputExpected Result
beneficiary.com/x/12345?t=ita2W2HPKfHxgSgrzY178knqXHg1H3jfeQrwQ9JrKBs9wv
beneficiary.com/x/12345Error due to missing query string "t=i"
https://beneficiary.com/x/12345?t=iError due to URI scheme presence
beneficiary/x/12345?t=iError due to unresolvable TLD

Decoding

InputExpected Result
ta2W2HPKfHxgSgrzY178knqXHg1H3jfeQrwQ9JrKBs9wvbeneficiary.com/x/12345?t=i
2W2HPKfHxgSgrzY178knqXHg1H3jfeQrwQ9JrKBs9wvError due to missing ta prefix
taEJKtAQyrS5x6i59GBS2fcbcUxoR14dYiW9cZuError due to missing query string "t=i"
ta2BCfkBRHmbhyZuKHmEdHpypmo7HG4RJVgaWYR4LkKGLyAtJQkDtJrKError due to URI scheme presence
taEJKtAQyrS5x6i59GKB6iMPx1iDzs8HXGNhbk1Error due to unresolvable TLD

Minimal Core Protocol with Extensions

The first part of the goals of the TRP:

"first generation, minimal, workable, and pragmatic API specification for compliance with the FATF Travel Rule in a timely manner"

is centered around having a simple minimal protocol that is easy to implement and to comply with.

The second part of the goals is to:

"minimize fragmentation and maximize interoperation"

In order to meet both of these goals the TRP is separated into two parts:

  1. A minimal core protocol
  2. Extensions

The minimal core protocol should contain mandatory elements that cover the bare minimum FATF R16 requirements. This meets the first part of the goals.

However, it is acknowledged that one size does not fit all, taking into account differing jurisdictional and compliance requirements on what information is to be exchanged. To help accommodate the second goal an extension mechanism is proposed.

The minimum core protocol will comply with the mandatory elements of R16, all other requirements will be added using the extension mechanism.

Security

TRP uses TLS 1.3 to secure all protocol traffic. This is a well-understood and widely-adopted solution for communication security.

Client Authentication

Clients are authenticated using a X.509 certificate. Those are most commonly used to authenticate a server when using TLS.

It is referred to as mutual TLS (mTLS) when both, client and server, are authenticated using X.509 certificates.

In TRP, a server MUST implement the /identity endpoint. A server's client certificate MAY be obtained by a GET request to the /identity endpoint. It is returned in a JSON document to allow for future extension. The expected response looks as following:

HTTP 200

{
    "x509": [x509 certificate in PEM format]
}

The PEM format is of type string. Further details can be obtained here.

TRP servers are required to reject connections from clients that cannot authenticate themselves using mTLS. The only exception is the /identity endpoint.

A VASP is free to choose any CA provider. In TRP, mTLS is used purely for establishing a secure communication channel. There is no additional semantics attached to the X509 certificates.

Because mTLS is established and well-understood it can be used without custom implementation out-of-the-box with nginx.

Technical implementation - Core Protocol

Headers

Each request must have the following header fields:

FieldDescriptionExample value
api-versionVersion of the API3.2.0
request-identifierUnique UUID V4 value for this particular API call (different for all calls)2351f3f1-bcff-4a06-a07a-8de94220a9b0

Each response must include the headers api-version and request-identifier. The former holds the version of the API the responder is using, the latter echoes the request-identifier back to the sender.

Sample Header

api-version: 3.2.0
request-identifier: 2351f3f1-bcff-4a06-a07a-8de94220a9b0

Motivation

TRP solves the following issues:

  1. enables to decline transactions a priori by using a transfer inquiry. This reduces the workload significantly for the compliance team.

  2. enables to negotiate a payment address after the KYC checks have been completed. This eliminates most unwanted payments.

  3. enables to share the transaction id after the blockchain payment has been executed by using the transfer confirmation. This eliminates the need for signed but unbroadcasted transactions that require low-level tinkering and are risky because they can be executed by simply broadcasting them. The transaction id is useful for the beneficiary to check if he has received the payment and trigger a human interaction in case it wasn't received.

Overview

Note that the sequence diagram below embeds the travel rule protocol into a wider context for illustration purposes. This includes user interaction via user interface, payee to payer interaction and on-chain transactions. The steps belonging strictly to the protocol are enumerated in steps one to three.

Hence, VASPs MAY diverge in steps depicted in the diagram that are not part of the three protocol steps. There are plausible reasons why a VASP would decide to do so:

  • to better accommodate to its risk based approach

  • to adapt to legal requirements of a particular jurisdiction

  • to work around legacy systems with limited integration capabilities

E.g. VASPs MAY decide to also accept a wallet address (depicted in grey) as an user interface input field and execute the virtual asset transaction before receiving an approval from but not before sending IVMS 101 payload to the beneficiary VASP. Please note, that following such an user interaction defeats the advantages listed in the motivation section above. VASPs MUST ensure that any interactions they decide for are compliant with the law in their jurisdiction.

actor "ORIGINATOR USER" #lightblue
entity "ORIGINATOR VASP" #blue

entity "BENEFICIARY VASP" #purple
actor "BENEFICIARY USER" #lightgreen

group "BENEFICIARY USER" wants to receive virtual assets from "ORIGINATOR USER", Happy Path

group User Interaction
"BENEFICIARY USER" -> "BENEFICIARY VASP": I would like to receive funds
"BENEFICIARY VASP" -> "BENEFICIARY USER": Generates Travel Address ta6MNBj2u4art71g... which encodes\nbeneficiary.com/api/3fc3645b439c?t=i
"BENEFICIARY USER" -> "ORIGINATOR USER": Gives Travel Address (ta6MNBj2u4art71g...)\n+beneficiary details <font color=grey>+optional wallet address
"ORIGINATOR USER" -> "ORIGINATOR VASP": Sends P1=(Travel Address,\nBeneficiary Details)
"ORIGINATOR VASP" -> "ORIGINATOR VASP": Sanctions/PEP Checks Beneficiary Details
end

autonumber
"ORIGINATOR VASP" -> "BENEFICIARY VASP": **POST to beneficiary.com/api/3fc3645b439c?t=i (decoded Travel Address)**
note right: {\n  "IVMS101": ...,\n  "asset": {\n    "dti": [digital token identifier as per Digital Token Identifier Foundation]\n  },\n  "amount": [amount in lowest denomination],\n  "callback": "https://originator.com/inquiryResolution?q=4585839457"\n}

autonumber stop
"ORIGINATOR VASP" -[#grey]-> "BENEFICIARY VASP": <font color=grey>Optionally executes a virtual asset transfer resulting in a tx identifier
"BENEFICIARY VASP" -> "BENEFICIARY VASP": Sanctions/PEP Checks on Originator User Details
autonumber resume

"BENEFICIARY VASP" -> "ORIGINATOR VASP": **POST to https://originator.com/inquiryResolution?q=4585839457**
note left: {\n  "approved": [payment address],\n  "callback": "https://beneficiary.com/transferConfirmation?q=3454366424"\n}

autonumber stop
"ORIGINATOR VASP" -> "ORIGINATOR VASP": On chain analytics on [payment address]
"ORIGINATOR VASP" -> "BENEFICIARY VASP": Executes a virtual asset transfer resulting in a tx identifier
autonumber resume

"ORIGINATOR VASP" -> "BENEFICIARY VASP": **POST to https://beneficiary.com/transferConfirmation?q=3454366424**
note right: {"txid": [some asset-specific tx identifier]}
end

Detailed Protocol Flow

An example protocol flow looks like this:

ta6MNBj2u4art71gN99C6xniYrNfDUF26QgZHdXwd6zzYsvk1S6M5A15K2REHRULnZHnJs88

It encodes:

beneficiary.com/implementation/defined/path?t=i
{
    "asset": {
        "dti": [digital token identifier as per Digital Token Identifier Foundation],
    },
    "amount": [amount in lowest denomination of asset],
    "callback": "https://originator.com/implementation/defined/path/for/inquiryResolution",
    "IVMS101": {
        "originator": {
            "originatorPersons": [
                {
                    "naturalPerson": {
                        "name": {
                            "nameIdentifier": [
                                {
                                    "primaryIdentifier": "Post",
                                    "secondaryIdentifier": "Johnny",
                                    "nameIdentifierType": "LEGL"
                                }
                            ]
                        },
                        "geographicAddress": [
                            {
                                "addressType": "GEOG",
                                "streetName": "Potential Street",
                                "buildingNumber": "123",
                                "buildingName": "Cheese Hut",
                                "postCode": "91361",
                                "townName": "Thousand Oaks",
                                "countrySubDivision": "California",
                                "country": "US"
                            }
                        ],
                        "customerIdentification": "1002390"
                    }
                }
            ]
        },
        "beneficiary": {
            "beneficiaryPersons": [
                {
                    "naturalPerson": {
                        "name": {
                            "nameIdentifier": [
                                {
                                    "primaryIdentifier": "MachuPichu",
                                    "secondaryIdentifier": "Freddie",
                                    "nameIdentifierType": "LEGL"
                                }
                            ]
                        }
                    }
                }
            ]
        },
        "originatingVASP": {
            "originatingVASP": {
                "legalPerson": {
                    "name": {
                        "nameIdentifier": [
                            {
                                "legalPersonName": "VASP A",
                                "legalPersonNameIdentifierType": "LEGL"
                            }
                        ]
                    },
                    "nationalIdentification": {
                        "nationalIdentifier": "506700T7Z685VUOZL877",
                        "nationalIdentifierType": "LEIX"
                    }
                }
            }
        }
    }
}

DTI is a digital token identifier as per Digital Token Identifier Foundation. It enables the unique identification of digital tokens based on ISO 24165. For more information, see the DTI Implementation Guide.

The DTI of Bitcoin is 4H95J0R2X.

Response data

HTTP OK 200

{
    "version": "3.2.0"
}

or, in case the inquiry is auto-approved,

{
  "approved": {
    "address": "some payment address",
    "callback": "https://beneficiary.com/implementation/defined/path/for/transferConfirmation"
  }
}

or, in case the inquiry is auto-rejected,

{
    "rejected": "human readable comment" [or null]
}

Transfer Inquiry Resolution

The callback URL from the transfer inquiry is used to send the following POST request

{
    "approved": {
        "address": "some payment address",
        "callback": "https://beneficiary.com/implementation/defined/path/for/transferConfirmation"
    }
}

or

{
    "rejected": "human readable comment" [or null]
}

Response data

HTTP 204 No Content

Transfer Confirmation

The callback URL from the transfer inquiry resolution is used to send the following POST request

{
    "txid": [some asset-specific tx identifier]
}

or

{
    "canceled": "human readable comment" [or null]
}

The txid should be communicated only if - as the name of the API endpoint suggests - the transaction has been confirmed.

Response data

HTTP 204 No Content

General error handling

Invalid/Expired URLs

A Travel Address can expire (e.g. customer closes account) or be invalid (e.g. someone crafts a URL with arbitrary parameters). Also a callback URL can expire (e.g. already called or timed out) or be invalid by construction. A backend must reply in such a case with an HTTP status code 404 NOT FOUND.

Error on server side

If an error is triggered on the server side (e.g. database unreachable) then a backend must reply with HTTP status code 500 INTERNAL SERVER ERROR.

Extensions

Entirely optional, zero or more extensions can be supported. Users of the TRP protocol should agree on a bilateral basis on which extensions they will use.

Scope

Extensions can add any and all HTTP headers or parameters.

The body of the requests can be added to the designated location.

Caveats

Conflicts between extensions

With the number of extensions growing the risk of conflicts or incompatibilities between extensions grows exponentially. New extension authors should take special care to investigate and address any conflicts.

Promotions from extension to core

Extensions might prove a comfortable testing ground for new functionality. When an extension is universally used it could be promoted to the core protocol. The promotion mechanism is still to be decided.

Fallback

Implementations should cater to as many extensions as possible. Some form of auto-discovery and if practical fallback should be catered for.

Core protocol additions

In order to support extensions some extension-specific handling is required in the core protocol beyond what is necessary for R16 compliance. These are described in the following section.

API-Extensions header

The support of an extension is signaled through the HTTP header field api-extensions.

FieldDescriptionExample value
api-extensionsComma separated list of extensions to the base the TRP protocol to be used when processing this requestrequest-signing,beneficiary-details-response

api-extensions must be omitted when no extensions are enabled.

Sample header with API-extensions:

api-version: 3.2.0
api-extensions: request-signing,beneficiary-details-response
request-identifier: 2351f3f1-bcff-4a06-a07a-8de94220a9b0
Extension not supported response code

A server should be able to inform a client that it is unable or unwilling to support the extensions as defined in the client request's api-extensions header. Two HTTP response codes are applicable, the 422 - Unprocessable Entity and the 501 - Not Implemented. Either one of them is applicable in different extension cases.

Request body

Extensions have a reserved top level key in JSON payloads called extensions. Each extension then has a key below that with a specific payload. For example:

{
  "IVMS101": ...
  "extensions": {
    "offchainData": {
      "refId": ...,
    }
  }
}

When no extensions are used in the request, i.e. the api-extensions header is absent, the key extensions must be omitted.

Compliance with FATF Recommendation 16

The key part of the FATF VASP Recommendations is:

A. As described in INR.15, paragraph 7(b), all of the requirements set forth in Recommendation 16 apply to VASPs or other obliged entities that engage in VA transfers, including the obligations to obtain, hold, and transmit required originator and beneficiary information in order to identify and report suspicious transactions, monitor the availability of information, take freezing actions, and prohibit transactions with designated persons and entities.

By exchanging originator and beneficiary information between VASPs, the TRP facilitates compliance with this requirement. Information must be stored by each VASPs themselves. No central or distributed database is proposed.

A. Further, countries should ensure that beneficiary institutions (whether a VASP or other obliged entity) obtain and hold required (not necessarily accurate) originator information and required and accurate beneficiary information, as set forth in INR. 16. The required information includes the:

  1. originator's name (i.e., the sending customer); The TRP facilitates compliance with this requirement.
  2. originator's account number where such an account is used to process the transaction (eg: the VA wallet); The TRP facilitates compliance with this requirement. The account is the public address.
  3. originator's physical (geographical) address, or national identity number, or customer identification number (i.e., not a transaction number) that uniquely identifies the originator to the ordering institution, or date and place of birth; The TRP facilitates compliance with this requirement. The TRP working group has agreed to use LEI or GEOG from IVMS101 in first phase.
  4. beneficiary's name; and The TRP facilitates compliance with this requirement.
  5. beneficiary account number where such an account is used to process the transaction (eg: the VA wallet). It is not necessary for the information to be attached directly to the VA transfer itself. The information can be submitted either directly or indirectly, as set forth in INR. 15. The TRP facilitates compliance with this requirement. The account is the public address.

Authoritative Version

This document provides a description of the TRP and its usage. Where possible this document will be updated and new versions issued as the protocol is revised.

References

1

See definition of Virtual Asset Service Providers at https://www.fatf-gafi.org/glossary/u-z/

End of Document