-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathsearchindex.en.js
410 lines (410 loc) · 278 KB
/
searchindex.en.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
var relearn_searchindex = [
{
"breadcrumb": "TRISA Developer Documentation \u003e TRISA Protocol and API",
"content": "The TRISA protocol enables peer-to-peer exchange of compliance information over a mutually authenticated connection so that the identity of both the sender and the recipient can be verified. The protocol contains methods for unary and streaming information exchanges as well as helper functions for key exchange and address confirmation to facilitate the secure transfer of PII information. The protocol itself is designed to be flexible, adaptable to regulatory changes, the needs of different types of VASPs, and future proofing for tomorrow’s technology.\nThe goal of a TRISA information transfer is to synchronize compliance information such that both the Originator and the Beneficiary VASPs can cryptographically prove they have identical compliance information for a specific transaction. The sending VASP encrypts and digitally signs the compliance payload along with a timestamp of when the compliance information is sent. The receiving VASP will verify the payload and add the timestamp of receipt, re-encrypting and digitally signing the payload, echoing it back to the sender. At the end of the information transfer, both parties will have an identical payload and digital signature that they will store for the duration of regulatory compliance.\nThis section describes the transfer protocol at a high level as well as issues and considerations for TRISA implementers joining the network.\nProtocol The protocol for sending transaction identity information is:\nDetermine how to connect to the Beneficiary VASP using the Global Directory Service. Establish a secure, mutually authenticated TLS connection between the VASPs to assure privacy of data in transit. Originator VASP sends a PII information transfer request to the Beneficiary VASP in a secure envelope with a unique message identifier. Beneficiary VASP verifies counterparty PII information (and may update it as necessary) and returns a signed secure envelope with the receipt timestamp using the same message identifier. Once the Originator VASP has confirmed all required compliance information has been correctly received, Originator VASP posts a transaction to the blockchain. If necessary, Originator VASP updates the transaction payload in the secure envelope with the transaction ID, signs it and sends it to the Beneficiary VASP using the same envelope ID. The Beneficiary VASP updates the receipt timestamp, signs and returns the secure envelope using the same envelope ID. At this point the Originator and Beneficiary VASPs have identical encrypted and digitally signed payloads for a completed transaction on the blockchain; both VASPs should maintain this information on durable long term storage for the compliance period. Communication between exchanges begins when the originating exchange establishes a TLS connection:\nsequenceDiagram participant Alice participant Alice's VASP participant Bob's VASP participant Bob Alice-\u003e\u003eAlice's VASP: 1) Send (Network, Amount, Address, Beneficiary VASP) Alice's VASP-\u003e\u003eBob's VASP: 2) Connect (Originating KYV Certificate) Bob's VASP-\u003e\u003eBob's VASP: 3) Verify Originating KYC Certificate Bob's VASP--\u003e\u003eAlice's VASP: 4) Return (Beneficiary KYV Certificate) Alice's VASP-\u003e\u003eAlice's VASP: 5) Verify Beneficiary KYC Certificate Alice's VASP-\u003e\u003eBob's VASP: 6) Transaction Data (Blockchain, Amount, Address, Alice's Info) Bob's VASP-\u003e\u003eBob: 7) Optional Transaction Notification Bob's VASP--\u003e\u003eAlice's VASP: 8) Receipt (Bob's info, Signature) Alice's VASP-\u003e\u003eAlice's VASP: 9) Process Virtual Asset Transaction (Blockchain, Amount, Address) Alice's VASP-\u003e\u003eBob's VASP: 10) Confirmation (Receipt ID, Blockchain TXID) Alice's VASP--\u003e\u003eAlice: 11) Transaction Confirmation Mutual authentication can be facilitated over the connection protocol as the Originator VASPs (here called “Alice’s VASP” as a real-world example) also provides their identification certificate to the destination exchange (here Bob’s VASP). Once a secure connection is established, the Originating VASP can then initiate the virtual asset transfer to the Beneficiary VASP along with the information required under the Travel Rule. To prove it has received the data, the Destination VASP sends a timestamped and digitally signed receipt that includes the hash of the identity information that was sent. The Originator VASP must keep this information to meet its record-keeping obligations under FATF recommendations.\nConnection Optimization Because establishing a new SSL/TLS mutually authenticated session between VASPs for every single transaction could prove to be overly costly in computation for key exchange and session establishment, it is acceptable to keep a connection open and exchange data for multiple transactions over a single connection. This is similar to how a browser keeps HTTPS web connections open for accessing multiple web pages in a single connection with a web server.\nThe v1beta1 implementation of the TRISA protocol uses the gRPC library to establish secure communication. gRPC includes a bidirectional streaming mode that allows long running connections with high throughput messaging between nodes. This mode is optional in TRISA but can be used to support batch messaging and increase the performance of TRISA messaging.\nBatch Processing Many VASPs (primarily exchanges who have large daily transaction volumes) are looking to retrofit Travel Rule compliance onto existing cryptocurrency transaction flows. The idea is to support batch transaction processing at the end of a day of trading and transactions. Batch processing can be done without impacting the Straight Through Processing (STP) of existing VASP data processing and transaction processing pipelines.\nFor example, some VASPs have optimized blockchain transactions to group 50-200 payments in a single blockchain transaction, which dramatically reduces transaction costs. VASPs can use TRISA to batch the originator and recipient data and not interrupt their existing optimized payment flows. However, there are two issues with this approach that are not solved in this version of the TRISA whitepaper:\nFunds availability: According to FinCEN, batch processing is acceptable, but funds received cannot be delivered to the recipient until the corresponding Originator information has been provided and scanned for sanctions and risk compliance. This requirement can delay the availability of inbound cryptocurrency payments to customers for many hours. Transaction finality: FATF, FinCEN and other guidance and regulation allows VASPs to process private transactions without Travel Rule compliance. VASP-to-VASP transactions, however, must send Originator and Beneficiary information. This requirement raises the problem of how a VASP is to know that an outbound or inbound blockchain transaction is from a private wallet, or from another VASP. In a world of batch processing, there is no current solution for a VASP to determine if a payment inbound or outbound is to or from a private wallet in a deterministic fashion. This limitation argues for real-time address detection. The TRISA community is still researching this issue. Perhaps timeouts (24 hours, for example) will suffice. Otherwise a real-time verification and processing model is preferred, as this solution preserves one of the most valued capacities of cryptocurrencies—near real-time transfer of funds globally with provable receipt of said funds. Asynchronous Transfers When a Beneficiary VASP receives Travel Rule transfer information from the Originating VASP through the TRISA protocol it may not always be able to respond immediately with any needed corrections or fill in for the missing/incorrect Beneficiary information provided. Thus the Beneficiary VASP should be able to respond back, at a later time, with the correct beneficiary information or provide errors if appropriate e.g., the beneficiary address is not owned by the Beneficiary VASP.\nThe Beneficiary VASP will return a control flow response to the transfer message to notify the Originating VASP that they will handle the compliance transfer in an asynchronous manner. The reply is also composed as a secure message with digitally signed timestamps for auditing purposes. Inside of the transaction payload, the Beneficiary VASP will provide additional information about when the Originating VASP can expect a response. The Originating VASP should delay any further action or communication until either the expected time frame expires or they receive a follow-on response from the Beneficiary VASP.\nmessage Pending { string envelope_id = 1; // TRISA envelope ID string received_by = 2; // recipient or recipient VASP name string received_at = 3; // when request was received (RFC3339) string message = 4; // optional message for counterparty string reply_not_after = 5; // when response will be returned (RFC3339) string reply_not_before = 6; // response will not be sent before (RFC3339) string extra_json = 7; // extra data (JSON-formatted) Transaction transaction = 15; // original transaction for reference } The Originating VASP should be prepared to receive such asynchronous callbacks from the Beneficiary VASP and take appropriate measures to handle it by caching the original message and awaiting a subsequent transfer message from the Beneficiary VASP. All messages that refer to the same blockchain transaction will contain the same envelope ID so that all messages may be linked together. Messages are ordered by the digitally signed timestamps in the payload, so it is important for integrators to ensure they are correctly decrypting payloads and sending correctly modified responses with new timestamps.\nOnce the Beneficiary VASP has completed their compliance processing, they should initiate a TRISA transfer back to the originating VASP that accepts the original transfer by providing the original or corrected compliance information or rejects it by providing an error in the secure envelope. This will give the Originating VASP conclusive information to take follow on actions like executing the transaction on the chain or handling the error and following the appropriate workflow.",
"description": "How the TRISA protocol works",
"tags": [],
"title": "TRISA Protocol",
"uri": "/api/protocol/index.html"
},
{
"breadcrumb": "TRISA Developer Documentation",
"content": "Welcome! If you’re new to TRISA, this guide will provide a path to help get you started.\nIf you just want to get started as quickly as possible, consider simply using the TRISA Envoy self-hosted node. If you are a hands-on developer, you may wish to skip to the section for technical implementers. If you are an administrator or technical leader at your organization, you may wish to skip to the administrative guide. Getting Started with TRISA There are three key steps to getting started integrating TRISA into your organization’s Travel Rule solution:\nRegister with the TRISA Directory Service: Before you can integrate the TRISA protocol into your VASP software, you must create an account and register with the TRISA Global Directory Service (GDS). This process is typically done by an administrator or technical leader at the organization and takes 1-2 business days. For more complete details, visit the documentation on registration. Implement the TRISA Protocol using TestNet: To integrate TRISA, you will need to implement a TRISA node that can act as both a server and a client in TRISA exchanges. This process will require a team of developers and generally takes a few months. The TRISA TestNet is designed to support you with the development and testing of your TRISA node. It will enable you to perform live tests and validate transactions that share sensitive information safely and securely. Check out the implementation overview for more details about how to get started. Implement your MainNet TRISA Node: Once you have fully tested your implementation using the TestNet and RobotVASPs, you can quickly switch to the production TRISA Network by installing MainNet certificates to your TRISA node. Note that this may require registering for MainNet certificates if those were not requested in step 3. This page will provide resources for getting started for both VASP administrators as well as technical implementation teams.\nFor Administrators If you’re an administrator or technical leader whose organization is using (or planning to adopt) the TRISA protocol, this section is for you!\nThese are the key portions of the documentation you will need to get started:\nJoining TRISA Registering with the Global Directory Service TRISA FAQ TRISA Glossary External links and resources for TRISA Integrating TRISA will require a team of engineers capable of implementing the TRISA protocol. When considering setting up your own server to host your own TRISA node, you must consider items necessary that may incur significant costs and resources, such as the server itself, long-term data storage solution, and developer time to configure and test. If your organization does not have access to a technical team or resources, you may instead choose to integrate with a 3rd-party TRISA solution. A list of some of the commercial TRISA solutions is available in this guide.\nFor Technical Implementers If you’re a developer whose organization is using (or planning to adopt) the TRISA protocol, this section is for you!\nThese are the key portions of the documentation you will need to get started:\nTRISA Protocol and API Working with TRISA Data Testing and Deployment Prerequisites To begin setup, you’ll need the following:\nIdentity Certificates (from TRISA GDS registration) The public key used for the CSR to obtain your certificate The associated private key The host name of the TRISA directory service Ability to bind to the address:port that is associated with your VASP in the TRISA directory service. Integration Overview Integrating VASPs must run their own implementation of the protocol. Integrators are expected to integrate incoming transfer requests and key exchanges and may optionally also integrate outgoing transfer requests and key exchanges.\nIntegrating the TRISA protocol involves both a client component and server component.\nThe client component will interface with the TRISA Global Directory Service (GDS) instance to lookup other VASPs that integrate the TRISA messaging protocol. The client component is utilized for outgoing transactions from your VASP to verify the receiving VASP is TRISA compliant.\nThe server component receives requests from other VASPs that integrate the TRISA protocol and provides responses to their requests. The server component provides callbacks that must be implemented so that your VASP can return information satisfying the TRISA Network protocol.\nCurrently, a reference implementation of the TRISA Network protocol is available in Go.\nhttps://github.com/trisacrypto/testnet/blob/main/pkg/rvasp/trisa.go\nIf a language beside Go is required, client libraries may be generated from the protocol buffers that define the TRISA Network protocol.\nIntegration Notes The TRISA Network protocol defines how data is transferred between participating VASPs. The recommended format for data transferred for identifying information is the IVMS101 data format. It is the responsibility of the implementing VASP to ensure the identifying data sent/received satisfies the FATF Travel Rule.\nThe result of a successful TRISA transaction results in a key and encrypted data that satisfies the FATF Travel Rule. TRISA does not define how this data should be stored once obtained. It is the responsibility of the implementing VASP to handle the secure storage of the resulting data for the transaction.\nSome other considerations you will need to make to be prepared to fully integrate TRISA include:\nHow will your TRISA endpoint integrate with your existing backend systems? How will you handle key management (e.g. your own private keys as well as the public keys of your counterparties)? Are you prepared to store envelopes securely and in compliance with privacy regulations once you have received them from your counterparties? For more considerations, see our Best Practices documentation.",
"description": "Getting Started with TRISA",
"tags": [],
"title": "Getting Started",
"uri": "/getting-started/index.html"
},
{
"breadcrumb": "TRISA Developer Documentation \u003e TRISA Protocol and API",
"content": "In TRISA v1.1 an optional transfer_state field was added to the secure envelope to assist TRISA implementers managing various TRISA data exchange workflows. While completely optional, the transfer_state signals to the counterparty (the recipient of the secure envelope) the intent of the current transfer message. The transfer state is an enum, and the available states are described below:\nCode State Description 0 UNSPECIFIED The transfer state is unknown or purposefully not specified (default case) 1 STARTED This is the first message in the TRISA workflow 2 PENDING Action is required by the sending party, await a following RPC 3 REVIEW Action is required by the receiving party (rarely used in transfers, useful for applications) 4 REPAIR Some part of the payload of the TRISA exchange requires repair (attached to error envelopes) 5 ACCEPTED The TRISA exchange is accepted and the counterparty is awaiting the on-chain transaction 6 COMPLETED The TRISA exchange and the on-chain transaction have been completed 7 REJECTED The TRISA exchange is rejected and no on-chain transaction should proceed (attached to error envelopes) The state transitions are described by the following flow-chart:\nflowchart LR STARTED autoAccept{{Review Required?}} STARTED--\u003eautoAccept autoAccept -- Yes --\u003e PENDING autoAccept -- No --\u003e ACCEPTED accept{{Accept Transfer?}} reject{{Retry and Fix?}} PENDING--\u003eaccept accept -- Yes --\u003e ACCEPTED accept -- No --\u003e reject reject -- No --\u003e REJECTED reject -- Yes --\u003e REPAIR REPAIR --\u003e PENDING ACCEPTED -- TxID --\u003e COMPLETED Workflows While the flow diagram above does a good job explaining how to transition a Transfer between states, it does not describe how those states might be engaged in practice using the TransferRPC and different payloads. This section contains sequence diagrams for standard workflows and exchanges.\nKeep in mind that the goal of a TRISA workflow is to ensure that both counterparties have the exact same Travel Rule payload, stored using a cryptographic method that only they can decrypt.\nIn practice, this means that an RPC request may be “echoed” as a response – e.g. you may receive a secure envelope where the only action you have to take to “accept” the request is to send the same payload back to the requester, encrypted using the requester’s public keys. This also means that you should not omit travel rule information payloads from each response as the last message contains the payload in the “final state” ready to be stored for the compliance statute of limitations.\nStandard Accept Workflow The following sequence diagram shows the RPCs needed to perform the simplest and most common Travel Rule information exchange:\nsequenceDiagram autonumber participant O as Originator VASP participant B as Beneficiary VASP rect rgb(27, 206, 159 ) note over O,B: RPC 1 O -\u003e\u003e B: Transfer Started B -\u003e\u003e O: Pending end critical B -\u003e\u003e B: KYC and Sanctions Checks end rect rgb(27, 206, 159 ) note over O,B: RPC 2 B -\u003e\u003e O: Accepted O -\u003e\u003e B: Accepted end critical O -\u003e\u003e O: Perform on chain transaction end rect rgb(27, 206, 159 ) note over O,B: RPC 3 O -\u003e\u003e B: Completed B -\u003e\u003e O: Completed end In RPC 1: the originator VASP sends a Secure Envelope with a Travel Rule payload to the beneficiary VASP. FATF recommends that this payload contains a complete IVMS101 payload, including the beneficiary details. The counterparty then returns a pending message with a pending payload to indicate that they need to perform their own KYC and sanctions checks before approving. A pending response is normal in the case of human-in-the-loop decision making, but some VASPs may have the ability to auto-approve transactions. To Include or Not Include Beneficiary Data Some VASPs may be willing to “repair” an IVMS101 payload if the beneficiary details are not provided (e.g. by populating those details in the response). So it may be possible to send an incomplete Travel Rule information exchange request in order to complete the transaction. TRISA is a peer-to-peer network, and VASP behavior will differ based on their jurisdictional responsibilities. When in doubt, we recommend you directly contact the compliance officer at the VASP and establish a mechanism between your entities for ensuring Travel Rule compliance occurs smoothly.\nAfter performing KYC sanctions checks and confirming that the transfer may proceed, the beneficiary VASP initiates RPC 2, sending an accepted envelope with the travel rule payload; the originator VASP echos this acceptance back.\nThe originator VASP may now apply the transaction to the specified chain. After they have performed the on-chain transaction, they will send a final message to the beneficiary VASP, updating the payload with the transaction details and marking the transfer as completed. The beneficiary VASP will echo the payload back to the originator VASP.\nReject Transfer Workflow In the case where the counterparty KYC and sanctions checks have identified a high risk entity, the beneficiary VASP must reject the transfer and indicate that the transfer should not continue by sending a rejection back to the originating VASP.\nA rejection is a SecureEnvelope that does not contain a payload but rather contains an error code with retry = false. For example, the following secure envelope might be sent:\n{ \"id\": \"envelope-id\", \"timestamp\": \"rfc3339 timestamp\", \"error\": { \"code\": \"HIGH_RISK\", \"message\": \"We have identified the indicated beneficiary on a sanctions list.\", \"retry\": false }, \"sealed\": false } The workflow for rejection is as follows:\nsequenceDiagram autonumber participant O as Originator VASP participant B as Beneficiary VASP rect rgb(27, 206, 159 ) note over O,B: RPC 1 O -\u003e\u003e B: Transfer Started B -\u003e\u003e O: Pending end critical B -\u003e\u003e B: KYC and Sanctions Checks Failed end rect rgb(240,186,200) note over O,B: RPC 2 B -\u003e\u003e O: Rejected O -\u003e\u003e B: Rejected end critical O -\u003e\u003e O: Stop transaction end Note that the originator VASP should not perform any actions on the blockchain specified after receiving a rejection according to the rules of their jurisdiction. If the beneficiary VASP receives the block chain transaction anyway, they should proceed by quarantining the transaction according to the rules of their jurisdiction. Keep in mind that sending a TRISA rejection message does not prevent any blockchain transactions, it is simply a signal to the counterparty not to proceed.\nRepair Workflow If not enough information has been provided by the originating VASP or something went wrong handling the travel rule information exchange, the beneficiary VASP may indicate that the originating VASP should try again and fix the specified problems by sending a repair message back to the originating VASP.\nA repair is a SecureEnvelope that does not contain a payload but rather contains an error code with retry = true. For example, the following secure envelope might be sent:\n{ \"id\": \"envelope-id\", \"timestamp\": \"rfc3339 timestamp\", \"error\": { \"code\": \"INCOMPLETE_IDENTITY\", \"message\": \"Our jurisdiction requires the date of birth of the originator.\", \"retry\": true }, \"sealed\": false } The repair workflow is as follows:\nsequenceDiagram autonumber participant O as Originator VASP participant B as Beneficiary VASP rect rgb(27, 206, 159 ) note over O,B: RPC 1 O -\u003e\u003e B: Transfer Started B -\u003e\u003e O: Pending end critical B -\u003e\u003e B: KYC and Sanctions Checks end rect rgb(240,186,200) note over O,B: RPC 2 B -\u003e\u003e O: Repair O -\u003e\u003e B: Pending end critical O -\u003e\u003e O: Review and fix travel rule information end rect rgb(240,186,200) note over O,B: RPC 3 O -\u003e\u003e B: Review B -\u003e\u003e O: Pending end critical B-\u003e\u003e B: Validate fixes meet requirements end rect rgb(27, 206, 159 ) note over O,B: RPC 4 B -\u003e\u003e O: Accepted O -\u003e\u003e B: Accepted end critical O -\u003e\u003e O: Perform on chain transaction end rect rgb(27, 206, 159 ) note over O,B: RPC 5 O -\u003e\u003e B: Completed B -\u003e\u003e O: Completed end It’s possible that multiple repair and review messages might be sent back and forth in order to resolve a transaction. TRISA encourages all VASPs to recognize the limited resources of compliance teams and to work to minimize exchanges as much as possible by providing as much detail about a repair as possible and directly contacting compliance officers for assistance in ensuring the transaction might be repaired effectively.",
"description": "Various workflow scenarios for handling travel rule information exchanges",
"tags": [],
"title": "TRISA Workflows",
"uri": "/api/workflows/index.html"
},
{
"breadcrumb": "TRISA Developer Documentation \u003e TRISA Envoy",
"content": "This guide assumes that you’re ready to deploy your Envoy node and that you’ve already obtained either TRISA TestNet or MainNet certificates as described by the Joining TRISA guide. If you haven’t already, please go to the TRISA Global Directory Service (vaspdirectory.net) to register for your certificates!\nLocal Development If you’d like information about how to run Envoy locally using Docker Compose and self-signed keys generated using openssl please go to the repository at trisacrypto/envoy and follow the instructions in the README.md.\nThe general/top-level steps to deploy an Envoy node are as follows:\nObtain and decrypt TRISA certificates Setup a deployment environment (e.g. a cloud instance or kubernetes cluster) Configure the Envoy node via the environment Deploy your Envoy node using one of the instructions below Ensure that you can reach your node at port 443 Configure DNS to point your TRISA endpoint at your node Create users/api keys to access the internal UI/API Deploying Envoy There are many ways to deploy Envoy and a lot depends on your internal infrastructure or cloud service provider. This guide provides examples for deploying Envoy using a Kubernetes cluster (the default way that we deploy our services) or using systemd on Ubuntu to run your Envoy service on a cloud instance.\nUsing Kubernetes The easiest way to install Envoy on Kubernetes is to use our helm chart. A simple one liner for the install would be:\nhelm install [RELEASE] trisacrypto/envoy \\ --set isTestnet=true \\ --set trisa.endpoint=testnet.vaspname.com:443 \\ --set trisa.web.origin=https://envoy.vaspname.com \\ --set certificate.name=testnet.vaspname.com.pem --set certificate.data=$(base64 -i ./secrets/testnet.vaspname.com.pem) The placeholders above are as follows:\n[RELEASE]: the name of the release for helm, usually vaspname and vaspname-testnet. testnet.vaspname.com:443: the TRISA endpoint for peer-to-peer travel rule information exchanges whose domain matches those issued for your certificates. https:///envoy.vaspname.com: the URL where you would like to hose the Envoy UI and API in order to interact with the Envoy node. testnet.vaspname.com.pem: by convention, the certificate name is the name of the domain followed by the .pem extension. ./secrets/testnet.vaspname.com.pem: path to the decrypted certificates issued to you by the Global directory service. To uninstall the chart:\nhelm uninstall [RELEASE] See the Envoy helm chart documentation for more on how to use a values file, manage secrets such as certificates, or just see the types of Kubernetes objects being generated by the chart so that you can create your own deployments.\nUsing systemd Coming Soon!\nCompiling and Installing Envoy Envoy is written in the Go programming language and so can be compiled using the go toolchain. If you have go installed on your computer, it may be possible for you to simply run:\n$ go install github.com/trisacrypto/envoy/cmd/envoy@latest To compile and install the latest version of envoy on your $PATH. Or if you prefer to install a specific version of Envoy:\n$ go install github.com/trisacrypto/envoy/cmd/[email protected] The complicating factor is that CGO is required to compile Envoy, which means you may have to set the CGO_ENABLED=1 environment variable. Additionally you’ll have to have either clang or gcc installed to compile the dependent packages for your architecture if they cannot be installed using go modules.\nBuilding the Docker Image You can build the Envoy Docker image using the Dockerfile in the root of the trisacrypto/envoy repository. After cloning the repository and changing into its root directory, run:\n$ docker build -t [TAG] . If you’d like to build the image for a different platform, you can use docker buildx as follows:\n$ docker buildx build -t [TAG] --platform linux/amd64,linux/arm64 . Feel free to push the resulting image to your container registry of choice; or just use the default Docker images on DockerHub!\nAccessing Envoy Although you can create users and API keys using the user interface there is a bit of a chicken and egg problem: how do you create a user to log in to the user interface to create a user? Additionally, if you’ve disabled the UI, how do you create API keys for the internal API? Luckily the envoy command has some helper tools to do this on your behalf.\nRunning the Envoy Command To create users and API keys, wherever you run the envoy command will need to have the correct configuration to reach the database that backs Envoy. In practice, this typically means that you need to run the envoy command on the instance where you deployed it. For example, if you’ve deployed using Kubernetes you could run:\n$ kubectl -n [NAMESPACE] exec -it [POD] -- envoy -h Alternatively you will have to SSH into the instance you’re running, and ensure that envoy is on your $PATH and that you have the correct permissions to execute it.\nCreating Users Use the following command to create a user:\n$ envoy createuser -n [NAME] -e [EMAIL] -r [ROLE] This command will create the specified user and will print out the password that you can use to login to the user interface with.\nRole can be one of:\nadmin: has full access to the UI compliance: can perform compliance related actions but not create users/apikeys observer: only has read-only access to the Envoy node Creating API Keys Use the following command to create an API key that has all permissions:\n$ envoy createapikey all Alternative, you can specify which permissions you want the API key to have by listing them each in a space delimited form:\n$ envoy createapikey users:manage users:view The list of the permissions you can add to an API key can be found in the API guide permissions table.",
"description": "A quick guide on deploying your Envoy node",
"tags": [],
"title": "Deploying Envoy",
"uri": "/envoy/deploy/index.html"
},
{
"breadcrumb": "TRISA Developer Documentation \u003e OpenVASP/TRP Integration",
"content": "The TRP Bridge implements http.Handler objects for each TRP request type and which can be passed to a basic http.Server and easily built into your TRISA node. A minimal example that simply logs incoming requests and return no error is below:\npackage main import ( \"log\" \"net/http\" \"github.com/trisacrypto/trisa/pkg/openvasp\" ) // TRPHandler implements both the InquiryHandler and the Confirmation Handler interfaces type TRPHandler struct{} // OnInquiry implements the InquiryHandler interface and is used to respond to TRP // transfer inquiry requests that initiate or conclude the TRP protocol. func (t *TRPHandler) OnInquiry(in *openvasp.Inquiry) (*openvasp.InquiryResolution, error) { // TODO: add your Transfer Inquiry code here! log.Printf( \"received trp inquiry with request identifier %q\\n\", in.TRP.RequestIdentifier ) return nil, nil } // OnConfirmation implements the ConfirmationHandler interface and is used to respond to // TRP callbacks from the beneficiary VASP. func (t *TRPHandler) OnConfirmation(in *openvasp.Confirmation) error { // TODO: add your Transfer Confirmation code here! log.Printf( \"received trp confirmation with request identifier %q\\n\", in.TRP.RequestIdentifier ) return nil } func main() { // Create a new handler object handler := \u0026TRPHandler{} // Create a mux to route requests to different paths to different handlers. mux := http.NewServeMux() mux.Handle(\"/transfers\", openvasp.TransferInquiry(handler)) mux.Handle(\"/confirm\", openvasp.TransferConfirmation(handler)) log.Printf( \"waiting for TRP requests with API version %s at http://localhost:8080\\n\", openvasp.APIVersion ) // Serve the TRP API server on port 8080. In production applications you would // likely configure mTLS and TLS termination at the server first. http.ListenAndServe(\":8080\", mux) } Transfer Inquiry The openvasp.TransferInquiry function accepts an object that implements the openvasp.InquiryHandler interface and returns an http.Handler that wraps the InquiryHandler to handle TRP Transfer Inquiry POST requests. The InquiryHandler is defined as follows:\ntype InquiryHandler interface { OnInquiry(*Inquiry) (*InquiryResolution, error) } The HTTP handler returned performs the following operations when an incoming HTTP POST request is received:\nValidates the incoming TRP request Parses the TRP Inquiry object along with any extensions. Calls the handler’s OnInquiry method Returns success or failure based on the returned value of OnInquiry. To return a failure condition from the OnInquiry() function, users may return an openvasp.StatusError that specifies the HTTP status code and message to return. This is useful particularly to return 404 errors if the Travel Address is incorrect or no beneficiary account exists at the endpoint. If a generic error is returned, then the handler will return a 500 Internal Server Error along with the err.Error() text.\nfunc (t *TRPHandler) OnInquiry(in *openvasp.Inquiry) (*openvasp.InquiryResolution, error) { // Lookup Travel Address and return a 404 error if beneficiary is not found. if notFound { return nil, \u0026openvasp.StatusError{Code: http.StatusNotFound} } } To return a succesful 200 OK response, return an openvasp.InquiryResolution object or simply nil, nil.\nThe semantics are as follows:\nIf the resolution response is nil or contains just the Version, then the counterparty expects a subsequent POST request to the callback in the request. The inquiry can be automatically approved by returning the Approved field without the Version or the Rejected fields (these must be zero valued). The inquiry can be automatically rejected by specifying a Rejected reason without the Version or the Approved fields (these must be zero valued). Transfer Confirmation The openvasp.TransferConfirmation function accepts an object that implements the openvasp.ConfirmationHander interface and returns an http.Handler that wraps the ConfirmationHander to handle TRP Transfer Confirmation POST requests. The ConfirmationHander is defined as follows:\ntype ConfirmationHandler interface { OnConfirmation(*Confirmation) error } When an incoming HTTP POST request is received (e.g. to the callback URL specified in the transfer inquiry), the HTTP handler performs the following operations:\nValidates the incoming TRP request Parses the TRP Confirmation object Calls the handler’s OnConfirmation method Returns a 200 OK response if the error is nil otherwise returns the StatusError or a 500 Internal Server Error Setting up a Server There are many ways to setup an http.Server in Golang. Feel free to use a the plain vanilla server or a framework like Gin or an advanced muxer like HTTPRouter. The handlers defined in the openvasp package implement the http.HandlerFunc and return an http.Handler object and can be used in most Go frameworks.\nThe primary consideration is mapping URLs (e.g. multiplexing) and setting up TLS termination and mTLS authentication. TRISA recommends that you terminate TLS and mTLS at a reverse-proxy for effective load balancing. However, by way of example, here is a simple code snippet to demonstrate setting up mTLS in a Go server.\nfunc main() { // Assuming you have your mTLS certificate and keys stored in cert.pem and key.pem certs, err := os.ReadFile(\"cert.pem\") if err != nil { log.Fatal(err) } certPool := x509.NewCertPool() certPool.AppendCertsFromPem(certs) server := http.Server{ Addr: \":8080\", Handler: mux, TLSConfig: \u0026tls.Config{ ClientAuth: tls.RequireAndVerifyClientCert, CliantCAs: certPool, MinVersion: tls.VersionTLS13, }, }, if er := server.ListenAndServeTLS(\"cert.pem\", \"key.pem\"); err != nil { log.Fatal(err) } } For more robust mTLS setup, please see the trust package in TRISA.\nAPI Checks The openvasp.APIChecks middleware validates TRP requests and parses header information from the request. Both the TransferInquiry and the TransferConfirmation handlers implement this middleware.\nThe checks that are performed include:\nEnsure the HTTP Method is POST otherwise a 405 Method Not Allowed error is returned. Ensure the TRP API Version header is set and the version is compatible with the implemented TRP version otherwise a 400 Bad Request error is returned. Ensures that the currently implemented TRP API Version header is set on the outgoing response. Checks that there is a request identifier header on the request, otherwise a 400 Bad Request error is returned. Ensures that the request identifier is echoed back on the outgoing response. Enforces that the Content-Type header is specified and that the content type is application/json, otherwise a 415 Unsupported Media Type error is returned. ParseTRPInfo The openvasp.ParseTRPInfo function parses TRP-specific headers from the request and adds them to a openvasp.TRPInfo struct that can be used for TRP processing. A mapping of the headers to the parsed fields is as follows:\nField Header Type Description Address string The Travel Address, LNURL, or URL of the request APIVersion api-version string Defaults to the APIVersion of the package RequestIdentifier api-extensions string A unique identifier representing the specific transfer (used as the envelope ID) APIExtensions request-identifier []string The comma separated names of any extensions used in the request",
"description": "Integrating a TRP server into your TRISA node",
"tags": [],
"title": "TRP Bridge",
"uri": "/openvasp/bridge/index.html"
},
{
"breadcrumb": "TRISA Developer Documentation \u003e Global Directory Service \u003e Administration \u003e Configuration",
"content": "The GDS is a collection of three APIs and several background services backed by a global TrtlDB data store. A single GDS node implements the TRISA Directory gRPC API, the secure TRISA Members gRPC API, and the Admin REST API that powers the Admin UI. It also runs the CertMan process that issues and collects certificates from Sectigo. Its environment variables are all prefixed with the GDS_ tag. The primary configuration is as follows:\nEnvVar Type Default Description GDS_DIRECTORY_ID string vaspdirectory.net The network ID the GDS serves, either vaspdirectory.net or trisatest.net (or .dev). GDS_SECRET_KEY string A base64 encoded random 32 byte array that is used for salts and random seeds - required. GDS_MAINTENANCE bool false Sets the server to maintenance mode, which will respond to requests with Unavailable except for status requests. GDS_LOG_LEVEL string info The verbosity of logging, one of trace, debug, info, warn, error, fatal, or panic. GDS_CONSOLE_LOG bool false If true will print human readable logs instead of JSON logs for machine consumption. GDS API The primary GDS API (the gRPC TRISA Directory service) is configured as follows:\nEnvVar Type Default Description GDS_API_ENABLED bool true If false, disables the TRISA Directory service. GDS_BIND_ADDR string :4433 The IP address and port to bind the GDS gRPC server to. Note that the enabled flag is only respected if GDS_MAINTENANCE is false, otherwise maintenance mode supersedes service enabled flags.\nAdmin API The Admin API (a REST API that powers the Admin UI) is configured as follows:\nEnvVar Type Default Description GDS_ADMIN_ENABLED bool true If false, disables the Admin API service. GDS_ADMIN_BIND_ADDR string :4434 The IP address and port to bind the Admin API http server to. GDS_ADMIN_MODE string release Sets the Gin mode, one of debug, release, or test. GDS_ADMIN_ALLOW_ORIGINS []string http://localhost,http://localhost:3000 A list of allowed origins for the CORS middleware to accept. GDS_ADMIN_COOKIE_DOMAIN string The domain to set secure cookies for (particularly for CSRF and authentication). GDS_ADMIN_AUDIENCE string The audience to set and verify in JWT tokens issued by the Admin API. GDS_ADMIN_OAUTH_GOOGLE_AUDIENCE string The audience from the Google OAuth config to verify Google login tokens. GDS_ADMIN_OAUTH_AUTHORIZED_EMAIL_DOMAINS []string The list of authorized email domains to allow access to the admin UI (e.g. trisa.io). GDS_ADMIN_TOKEN_KEYS map[string]string A mapping of key id (ksuid/ulid) to the path to an RSA signing key in PEM format for JWT token signing. Note that the enabled flag is only respected if GDS_MAINTENANCE is false, otherwise maintenance mode supersedes service enabled flags.\nMembers API The Members API is a gRPC API that is secured by TRISA, verified by mTLS, and is configured as follows:\nEnvVar Type Default Description GDS_MEMBERS_ENABLED bool true If false, disables the Members API service. GDS_MEMBERS_BIND_ADDR string :4435 The IP address and port to bind the Members gRPC server to. GDS_MEMBERS_INSECURE bool false If set do not enable mTLS authentication. GDS_MEMBERS_CERTS string The path to the mTLS server-side certs for server auth. GDS_MEMBERS_CERT_POOL string The path to the mTLS public cert pools to accept incoming connections. Note that the enabled flag is only respected if GDS_MAINTENANCE is false, otherwise maintenance mode supersedes service enabled flags. If GDS_MEMBERS_INSECURE is false, then GDS_MEMBERS_CERTS and GDS_MEMBERS_CERT_POOL are required.\nDatabase The GDS makes use of a globally replicated key-value store for persistence. By default it uses the TrtlDB for this, but for testing or smaller deployments it can use a local LevelDB database instead. The database store is configured as follows:\nEnvVar Type Default Description GDS_DATABASE_URL string Required, the DSN to connect to the database on (see below for details). GDS_DATABASE_REINDEX_ON_BOOT bool false When the server starts, instead of loading indexes from disk, recreate and save them. GDS_DATABASE_INSECURE bool false If set do not connect to the TrtlDB with mTLS authentication. GDS_DATABASE_CERT_PATH string The path to the mTLS client-side certs for database auth. GDS_DATABASE_POOL_PATH string The path to the mTLS public cert pools to accept server connections. The GDS_DATABASE_URL is a standard DSN with a scheme, host, path, and query parameters. In the case of the GDS the scheme can be either trtl:// or leveldb://.\nWhen connecting to a TrtlDB, the host and port need to be specified with a trailing slash, e.g. trtl://localhost:4436/. Connecting via mTLS is only relevant when connecting to a TrtlDB. If GDS_DATABASE_INSECURE is false, then the GDS_DATABASE_CERT_PATH and GDS_DATABASE_POOL_PATH are required.\nWhen connecting to a LevelDB, the path to the directory on disk where the leveldb should be stored must be passed to the DSN. To specify a relative path, use three slashes: leveldb:///relpath/to/db, to specify an absolute path use four: leveldb:////abspath/to/db.\nEmail and SendGrid The GDS uses SendGrid to send email notifications and to enable communication workflows with users and admins. Configure GDS to use SendGrid as follows:\nEnvVar Type Default Description GDS_SERVICE_EMAIL string TRISA Directory Service [email protected] The email address used as the sender for all emails from the GDS system. GDS_ADMIN_EMAIL string TRISA Admins [email protected] The email address to send admin emails to from the server. SENDGRID_API_KEY string API Key to authenticate to SendGrid with. GDS_DIRECTORY_ID string vaspdirectory.net (Reused) The network ID the GDS serves, either vaspdirectory.net or trisatest.net (or .dev). GDS_VERIFY_CONTACT_URL string https://vaspdirectory.net/verify The base URL to include in emails for contact verification. GDS_ADMIN_REVIEW_URL string https://admin.vaspdirectory.net/vasps/ The base URL to include in emails to link to a new VASP registration. GDS_EMAIL_TESTING bool false Use email in testing mode rather than send live emails. GDS_EMAIL_STORAGE string \"\" Directory to store test emails for “mark one eyeball” review. SendGrid is considered enabled if the SendGrid API Key is set. The service and admin email addresses are required if SendGrid is enabled.\nCertMan The CertMan is a background process that runs on the GDS and manages certificate requests, interacts with Sectigo, and finalizes the VASP registration process. It is configured as follows:\nEnvVar Type Default Description GDS_CERTMAN_ENABLED bool true If false, disables the CertMan background process. GDS_CERTMAN_REQUEST_INTERVAL duration 10m The interval between certificate request processing runs. GDS_CERTMAN_REISSUANCE_INTERVAL duration 24h The interval between certificate reissuance processing runs. GDS_CERTMAN_STORAGE string The path to a directory on disk where CertMan temporarily downloads certificates (otherwise a tmp dir is used). GDS_DIRECTORY_ID string vaspdirectory.net (Reused) The network ID the GDS serves, either vaspdirectory.net or trisatest.net (or .dev). SECTIGO_USERNAME string The username to authenticate with the Sectigo API. SECTIGO_PASSWORD string The password to authenticate with the Sectigo API. SECTIGO_PROFILE string The certificate profile to use (see below for details). SECTIGO_ENDPOINT string The endpoint to connect to Sectigo on (leave blank for production). SECTIGO_TESTING bool If Sectigo is in testing mode it will not make actual Sectigo requests. Note that CertMan also needs valid email (SendGrid) and Google Secrets configurations if it is enabled.\nThe Sectigo username, password, and profile are required if the Sectigo config is not in testing mode. The profile must be a valid certificate profile, which can be either “CipherTrace EE” for the TestNet or “CipherTrace End Entity Certificate” for the MainNet. These profiles determine what parameters must be sent to Sectigo to make certificate requests, and what is populated on the certificate (including what intermediate authority is used) when it is generated.\nDo not set the SECTIGO_ENDPOINT unless you’re in testing, development, or staging mode and are pointing it to a local cathy server.\nBackups The Backup manager is only available when the GDS is using the LevelDB database store. It is a background process that clones the database into a zipped folder on disk that can be downloaded for backup purposes.\nEnvVar Type Default Description GDS_BACKUP_ENABLED bool false If true, enables the backup background process. GDS_BACKUP_INTERVAL duration 24h The interval between database backups. GDS_BACKUP_STORAGE string The path on disk to store database backups (required if enabled). GDS_BACKUP_KEEP int 1 The number of backups to keep before cleaning up old backups. Backups should not be enabled when using the TrtlDB database store! If the backups are enabled then the storage path is required.\nGoogle Secrets GDS uses Google Secret Manager to store certificates and PKCS12 passwords and other sensitive information to ensure that it is encrypted and secure. Access to Google Secret Manager is configured as follows:\nEnvVar Type Default Description GOOGLE_APPLICATION_CREDENTIALS string Path to the JSON credentials for the Google Service Account that has access to Google Secret Manager. GOOGLE_PROJECT_NAME string Name of the Google Project for API access to Google Secret Manager. GDS_SECRETS_TESTING bool false If set to true, uses a local in-memory “secret store” for testing and development. Note that the GOOGLE_APPLICATION_CREDENTIALS and GOOGLE_PROJECT_NAME are required if GDS_SECRETS_TESTING is false.\nSentry The GDS uses Sentry to assist with error monitoring and performance tracing. Configure GDS to use Sentry as follows:\nEnvVar Type Default Description GDS_SENTRY_DSN string The DSN for the Sentry project. If not set then Sentry is considered disabled. GDS_SENTRY_SERVER_NAME string Optional - a server name to tag Sentry events with. GDS_SENTRY_ENVIRONMENT string The environment to report (e.g. development, staging, production). Required if Sentry is enabled. GDS_SENTRY_RELEASE string {{version}} Specify the release version for Sentry tracking. By default this will be the package version. GDS_SENTRY_TRACK_PERFORMANCE bool false Enable performance tracing to Sentry with the specified sample rate. GDS_SENTRY_SAMPLE_RATE float64 0.85 The percentage of transactions to trace (0.0 to 1.0). GDS_SENTRY_REPORT_ERRORS bool false If true sends gRPC errors to Sentry as exceptions (useful for development or staging) GDS_SENTRY_DEBUG bool false Set Sentry to debug mode for testing. Sentry is considered enabled if a DSN is configured. Performance tracing is only enabled if Sentry is enabled and track performance is set to true. If Sentry is enabled, an environment is required, otherwise the configuration will be invalid.\nNote that the sentry.Config object has a field Repanic that should not be set by the user. This field is used to manage panics in chained interceptors.",
"description": "Configuring the GDS",
"tags": [],
"title": "GDS",
"uri": "/gds/admin/configuration/gds/index.html"
},
{
"breadcrumb": "TRISA Developer Documentation \u003e Global Directory Service \u003e Administration",
"content": "TRISA currently maintains two side-by-side networks that are deployed in Kubernetes clusters in North America, Germany, and Singapore. The “MainNet” (also referred to as the TRISA network) is the production TRISA service where peers exchange compliance information for real transactions. The “TestNet” is a mirror network that is setup to allow peers to develop their TRISA nodes and to ensure that they are configured correctly before engaging in production transactions. For more on using the TestNet, please see the Testing documentation.\nThe current network architecture is as follows:\nContainers and Images All TRISA related containers are hosted publicly on DockerHub. Containers are also pushed to GCR for rapid loading into our GKE kubernetes environment.\nThe primary container images are as follows:\ntrisa/gds: The primary GDS service that runs the TRISA Directory API, the TRISA Members API, the Admin API, and the Certificate Manager process. trisa/gds-user-ui: The primary GDS UI React application compiled for production and served using an nginx container. trisa/bff: The Backend for Frontend (BFF) that allows the GDS UI to access both the MainNet and TestNet GDS services. trisa/gds-admin-ui and trisa/gds-testnet-admin-ui: the Admin UI React application compiled for production and served using an nginx container. trisa/trtl and trisa/trtl-init: distributed TrtlDB containers optimized for TRISA cross-region deployment. Helper images that may be deployed for maintenance or development:\ntrisa/maintenance: a basic UI that presents a “down for maintenance” screen. trisa/placeholder: a basic UI that presents a placeholder image and some text. trisa/grpc-proxy: an envoy proxy configured for using grpc-web with the GDS. trisa/docs-redirect: a simple nginx redirect API for ensuring users are connected to the correct documentation site. TestNet images:\ntrisa/rvasp: the base image for all rVASPs that connect to a Postgres database. trisa/rvasp-migrate: a container job that migrates the rVASP Postgres database. trisa/trtlsim: a data generating utility that simulates TRISA usage for load testing the trtl database. Staging images (user interface images configured for a staging environment):\ntrisa/gds-staging-user-ui: GDS UI configured for vaspdirectory.dev trisa/gds-staging-testnet-admin-ui: GDS Admin UI configured for admin.trisatest.dev trisa/gds-staging-admin-ui: GDS Admin UI configured for admin.vaspdirectory.dev trisa/cathy: a fake certificate authority for integration testing and development without issuing real certificates. Deprecated images:\ntrisa/gds-ui: GDS v1.4.1 single GDS user interface. trisa/gds-testnet-ui: GDS v1.4.1 single GDS user interface configured for trisatest.net. trisa/rvasp-alice: the sqlite configured Alice rVASP. trisa/rvasp-bob: the sqlite configured Bob rVASP. trisa/rvasp-evil: the sqlite configured Evil rVASP.",
"description": "Deploying the GDS System",
"tags": [],
"title": "Deployment",
"uri": "/gds/admin/deployment/index.html"
},
{
"breadcrumb": "TRISA Developer Documentation \u003e Reference",
"content": "Long Term Data Storage TRISA recommends that Travel Rule information transfers be stored post-transfer as encrypted Secure Envelope protocol buffers. The unsealing keys for these envelopes should be stored separately, and should be deleted once the compliance period has ended, rendering the Envelopes un-openable. This is commonly referred to as “deletion by erasure”. Note that compliance periods differ by region and jurisdiction but are typically between 5 and 7 years.\nKey Management TRISA recommends that TRISA implementers use the Key Handler package for key management.\nThroughput Depending on the volume of Travel Rule transactions that your organization executes on a regular basis, you may wish to consider using the bidirectional streaming mode, TransferStream, which will support more throughput.\nDeployment For deployment, TRISA implementers should be prepared to install their Identity Certificates (which will need to be reissued and reinstalled on an annual basis) to support routine and possibly long-running mTLS connections.\nImplementers must also ensure that their existing databases are configured to support responding to routine Travel Rule information requests. Additional storage may be needed to store the results of these requests (e.g. encrypted Secure Envelopes).",
"description": "Best Practices for TRISA Implementers",
"tags": [],
"title": "Best Practices",
"uri": "/reference/best-practices/index.html"
},
{
"breadcrumb": "TRISA Developer Documentation \u003e Working with TRISA Data",
"content": "IVMS101 (the interVASP Messaging Standard) is an internationally recognized standard that helps with language encodings, numeric identification systems, phonetic name pronunciations, and standardized country codes (ISO 3166). This page describes how to convert between JSON and protocol buffer formatting for IVMS101 records. For general information about IVMS, please visit intervasp.org.\nMarshaling and Unmarshaling IVMS101 JSON data should be marshaled and unmarshaled using the encoding/json package to produce data mostly compatible with the ivmsvalidator.com tool produced by 21 Analytics.\nNote Fixtures that are unmarshaled using the protojson package are not compatible with the 21 Analytics validator tool. The only reason to use the protojson style is if you’re specifically working with protocol buffers and need a human-readable/editable format.\nUnless you are specifically developing against a Go code base with marshaled protocol buffer TRISA structs, we strongly recommend that you use encoding/json for IVMS 101 serialization and JSON exchange.\nThe ivms101 package in trisa is designed to provide convenient tools for marshaling and unmarshaling IVMS101 identity payloads (which contain many nested fields) to and from a file, as illustrated below.\nFor examples of fixtures that represent the JSON style, see the files from the trisa directory that end in the extension .json. For examples of protojson fixtures, see the files from the trisa directory that end in the extension .pb.json.\nIVMS101 JSON Use the encoding/json package as follows:\npackage ivms101_test import ( \"encoding/json\" \"io/ioutil\" \"github.com/trisacrypto/trisa/pkg/ivms101\" ) func LoadJSON(path string) (identity *ivms101.IdentityPayload, err error) { var data []byte if data, err = ioutil.ReadFile(path); err != nil { return nil, err } identity = \u0026ivms101.IdentityPayload{} if err = json.Unmarshal(data, identity); err != nil { return nil, err } return identity, nil } func DumpJSON(identity *ivms101.IdentityPayload, path string) (err error) { var data []byte if data, err = json.Marshal(identity); err != nil { return err } if err = ioutil.WriteFile(path, data, 0644); err != nil { return err } return nil } Note that when unmarshaling from protocol buffers to JSON, this package does not copy any nil fields from the protobuf to the JSON file.\nProtocol Buffers JSON Note Not recommended; in most cases, you will want to use IVMS101 JSON as described above.\nFor specific protocol buffer use cases, use the protojson file as follows:\npackage ivms101_test import ( \"io/ioutil\" \"github.com/trisacrypto/trisa/pkg/ivms101\" \"google.golang.org/protobuf/encoding/protojson\" ) func LoadPBJ(path string) (identity *ivms101.IdentityPayload, err error) { var data []byte if data, err = ioutil.ReadFile(path); err != nil { return nil, err } jsonpb := protojson.UnmarshalOptions{ AllowPartial: true, DiscardUnknown: true, } identity = \u0026ivms101.IdentityPayload{} if err = jsonpb.Unmarshal(data, identity); err != nil { return nil, err } return identity, nil } func DumpPBJ(identity *ivms101.IdentityPayload, path string) (err error) { jsonpb := protojson.MarshalOptions{ Multiline: true, Indent: \" \", AllowPartial: true, UseProtoNames: true, UseEnumNumbers: false, EmitUnpopulated: true, } var data []byte if data, err = jsonpb.Marshal(identity); err != nil { return err } if err = ioutil.WriteFile(path, data, 0644); err != nil { return err } return nil }",
"description": "Working with IVMS101 JSON and Protocol Buffers",
"tags": [],
"title": "Working with IVMS101",
"uri": "/data/ivms/index.html"
},
{
"breadcrumb": "TRISA Developer Documentation",
"content": "This portion of the documentation describes how to become a TRISA member so that you can receive Identity Certificates and use them to perform secure information transfers with other VASPs.\nTo join the TRISA network, you must register with the TRISA Global Directory Service (GDS).\nThe mechanics of registration include two important workflows:\nA KYV review process to ensure the network maintains trusted membership Certificate issuance for mTLS authentication in the network Next, learn more about the process of registration.",
"description": "Describes How to Join TRISA",
"tags": [],
"title": "Joining TRISA",
"uri": "/joining-trisa/index.html"
},
{
"breadcrumb": "TRISA Developer Documentation \u003e Testing and Deployment",
"content": "The TestNet hosts three convenience “robot VASPs” (rVASPs) services to facilitate integration and testing with the TRISA TestNet. These services are as follows:\nAlice (api.alice.vaspbot.net:443): the primary integration rVASP used to trigger and receive TRISA messages. Bob (api.bob.vaspbot.net:443): a demo rVASP to view exchanges with Alice. Evil (api.evil.vaspbot.net:443): an “evil” rVASP that is not a TRISA TestNet member, used to test non-authenticated interactions. Note: the rVASPs are currently primarily configured for demos. Work has begun on making them more robust for integration purposes; please check in with this documentation regularly for any changes. If you notice any bugs in the rVASP code or behavior, please open an issue.\nGetting Started with rVASPs There are two ways that you can use the rVASPs to develop your TRISA service:\nYou can trigger the rVASP to send a TRISA exchange message to your service. You can send a TRISA message to the rVASP with a valid (or invalid) rVASP customer. The rVASPs have a built-in database of fake customers with fake wallet addresses. Their response to TRISA messages or to a triggered transfer requires the originator/beneficiary customer to be valid for the rVASP. E.g. if the customer wallet address is a valid Alice address and Alice is the beneficiary, the rVASP will respond with the customer’s fake KYC data but if not, it will return an TRISA error code.\nThe following table of “customers” for Alice, Bob, and Evil can be used as a reference for interacting with each rVASP:\nVASP “Crypto Wallet” Email Originator Policy Beneficiary Policy api.bob.vaspbot.net moJuU1GjhJzUdUGukw13a4w6CWjfFsJ92q [email protected] SendPartial SyncRepair api.bob.vaspbot.net 18nxAxBktHZDrMoJ3N2fk9imLX8xNnYbNh [email protected] SendPartial SyncRepair api.bob.vaspbot.net n1CqdbqoPZ8Y11UzQG6KyapWj4vcN3owcs [email protected] SendFull SyncRequire api.bob.vaspbot.net 1LgtLYkpaXhHDu1Ngh7x9fcBs5KuThbSzw [email protected] SendFull SyncRequire api.bob.vaspbot.net mj2RQ7AcYs5sMQVJVTUn6ZZX7iMiMzn75o [email protected] SendFull AsyncRepair api.bob.vaspbot.net 14WU745djqecaJ1gmtWQGeMCFim1W5MNp3 [email protected] SendFull AsyncRepair api.bob.vaspbot.net mxWc29f1JHYSupfmveBYTHKMUYsnNcrJDV [email protected] SendError AsyncReject api.bob.vaspbot.net 1Hzej6a2VG7C8iCAD5DAdN72cZH5THSMt9 [email protected] SendError AsyncReject api.alice.vaspbot.net mpxi8gszWxQtayy3dztQZ1rheWRDFZ2QWp [email protected] SendPartial SyncRepair api.alice.vaspbot.net 1ASkqdo1hvydosVRvRv2j6eNnWpWLHucMX [email protected] SendPartial SyncRepair api.alice.vaspbot.net n1wAFyKnzpyPchDUUwRpgXsrJYdekV7KGR [email protected] SendFull SyncRequire api.alice.vaspbot.net 1MRCxvEpBoY8qajrmNTSrcfXSZ2wsrGeha [email protected] SendFull SyncRequire api.alice.vaspbot.net mioiUW2dR9y7PdAFs8gPPhthaZgmpHhgGd [email protected] SendFull AsyncRepair api.alice.vaspbot.net 14HmBSwec8XrcWge9Zi1ZngNia64u3Wd2v [email protected] SendFull AsyncRepair api.alice.vaspbot.net mpJCwniMFW9FXGeFejtksrpPunjLEmPZsu [email protected] SendError AsyncReject api.alice.vaspbot.net 19nFejdNSUhzkAAdwAvP3wc53o8dL326QQ [email protected] SendError AsyncReject api.evil.vaspbot.net n3mRAXVqEsN22rnXWEsnRMQMc9QmM47qUX [email protected] SendPartial SyncRepair api.evil.vaspbot.net 1PFTsUQrRqvmFkJunfuQbSC2k9p4RfxYLF [email protected] SendPartial SyncRepair api.evil.vaspbot.net mmYjRCpKYYm22RGKjVuruADHBR8c5dni68 [email protected] SendFull SyncRequire api.evil.vaspbot.net 172n89jLjXKmFJni1vwV5EzxKRXuAAoxUz [email protected] SendFull SyncRequire api.evil.vaspbot.net mfdz3J9kQ6skqRjrdkQyoSg95WZqmRXmBA [email protected] SendFull AsyncRepair api.evil.vaspbot.net 182kF4mb5SW4KGEvBSbyXTpDWy8rK1Dpu [email protected] SendFull AsyncRepair api.evil.vaspbot.net mqPCJiSRPYqFmA7MtxxCwwABFQ52nzC4gV [email protected] SendError AsyncReject api.evil.vaspbot.net 1AsF1fMSaXPzz3dkBPyq81wrPQUKtT2tiz [email protected] SendError AsyncReject Note that all rVASP data was generated using a Faker tool to produce realistic/consistent test data and fixtures; this data is completely fictional. For example, the records for Alice VASP (a fake US company) are primarily in North America, etc.\nIf you’re a Traveler customer, the bold addresses above have some attribution data associated with them, and are a good candidate for Traveler-based rVASP interactions.\nIn order to support multiple behaviors at once, such as synchronous and asynchronous responses, each wallet address is configured with an originator policy and a beneficiary policy. The originator policy defines how the rVASP will behave when initiating transfers to a remote VASP. The beneficiary policy defines how the rVASP will behave when responding to transfers from a remote VASP. These policies are described in depth below.\nThere are two wallets for each customer to support wallet addresses that look like either testnet or mainnet crypto addresses, however the rVASP behavior and data is exactly the same for each pair. Note that rVASPs don’t interact with any real chain; the wallet addresses are simply a mechanism to configure behavior as described below.\nPreliminaries This documentation assumes that you have a service that is running the latest TRISANetwork service and that this service has been registered in the TRISA TestNet and has TestNet certificates correctly installed. See TRISA Integration Overview for more information. WARNING: the rVASPs do not participate in the TRISA production network. They will only respond to verified TRISA TestNet mTLS connections.\nTo interact with the rVASP API, you may either:\nUse the rvasp CLI tool Use the rVASP protocol buffers and interact with the API directly To install the CLI tool, either download the rvasp executable for the appropriate architecture at the TestNet releases page, clone the TestNet repository and build the cmd/rvasp binary or install with go install as follows:\n$ go install github.com/trisacrypto/testnet/cmd/rvasp@latest To use the rVASP protocol buffers, clone or download them from the TestNet repository then compile them to your preferred language using protoc.\nTriggering an rVASP to send a message The rVASP admin endpoints are used to interact with the rVASP directly for development and integration purposes. Note that this endpoint is different than the TRISA endpoint, which was described above.\nAlice: admin.alice.vaspbot.net:443 Bob: admin.bob.vaspbot.net:443 Evil: admin.evil.vaspbot.net:443 To use the command line tool to trigger a message, run the following command:\n$ rvasp transfer -e admin.alice.vaspbot.net:443 \\ -a [email protected] \\ -d 0.3 \\ -B trisa.example.com \\ -b cryptowalletaddress \\ -E This message sends the Alice rVASP a message using the -e or --endpoint flag, and specifies that the originating account should be “[email protected]” using the -a or --account flag. The originating account is used to determine what IVMS101 data to send to the beneficiary. The -d or --amount flag specifies the amount of “AliceCoin” to send. Finally, the -b or --beneficiary flag specifies the crypto wallet address of the beneficiary you intend as the recipient.\nThe next two parts are critical. The -E or --external-demo flag tells the rVASP to trigger a request to your service rather than to perform a demo exchange with another rVASP. This flag is required! Finally, the -B or --beneficiary-vasp flag specifies where the rVASP will send the request. This field should be searchable in the TRISA TestNet directory service; e.g. it should be your common name or the name of your VASP if it is searchable.\nNote that you can set the $RVASP_ADDR and $RVASP_CLIENT_ACCOUNT environment variables to specify the -e and -a flags respectively.\nTo use the protocol buffers directly, use the TRISAIntegration service Transfer RPC with the following TransferRequest:\n{ \"account\": \"[email protected]\", \"amount\": 0.3, \"beneficiary\": \"cryptowalletaddress\", \"beneficiary_vasp\": \"trisa.example.com\", \"check_beneficiary\": false, \"external_demo\": true } These values have the same exact specification as the ones in the command line program.\nResponding to a TRISA message from an rVASP Envelopes received from rVASPs can be decrypted using the private unsealing key paired with the public key you exchanged with the rVASP. The payload that you receive from the rVASP will be determined by the originator policy associated with the originator address in the transaction payload.\nIt is then up to your TRISA node to determine how to handle the payload. Your options are:\nReject: return an error in the secure envelope without a payload Pending: return a trisa.data.generic.v1beta1.Pending in the transaction payload Accept: ensure the identity payload is complete and return payload with received_at The rVASP handles each type of response appropriately. If a reject message is returned, the rVASP fails the transaction; if accept it “executes” the transaction.\nThe pending message initiates an asynchronous transaction as defined in the TRISA whitepaper. The transaction is placed into an “await” state until the rVASP receives a follow-up reject or accept response with the same envelope id.\nOriginator Policies An originator policy determines how the rVASP constructs an outgoing payload and handles the response from the transfer. The originator policy is loaded when the rvasp command is used to instruct the rVASP to send an outgoing message either to another rVASP or to your own TRISA node. Originator policies are mapped to wallet addresses, and the rVASP identifies the originator address using the wallet address in the transaction payload. A description of the originator policies follow:\nSendPartial For the SendPartial policy, the rVASP sends an envelope containing a transaction payload and a partial identity payload containing a full originator identity and a partial beneficiary identity. For acceptance, the recipient must complete the identity payload by filling in the beneficiary identity.\nSendFull For the SendFull policy, the rVASP sends an envelope containing a transaction payload and a complete identity payload. For acceptance, the recipient must reseal and echo the envelope back with a received_at timestamp.\nSendError For the SendError policy, the rVASP will simply send an envelope containing a ComplianceCheckFail TRISA error. The rVASP expects the recipient to also return an envelope with an error in it, otherwise an error will be returned by the CLI to the user. This is useful for simulating synchronous rejections or cancellations from the rVASP.\nSending a TRISA message to an rVASP The rVASP expects a trisa.data.generic.v1beta1.Transaction as the transaction payload and an ivms101.IdentityPayload as the identity payload. The transaction payload must contain a beneficiary address that matches the rVASP beneficiaries from the table above; e.g. use:\n{ \"originator\": \"anydatahereisfine\", \"beneficiary\": \"1MRCxvEpBoY8qajrmNTSrcfXSZ2wsrGeha\", \"amount\": 0.3, \"network\": \"TestNet\" } You may specify any originator “wallet address” string. The network and asset_type fields can be ignored if you would like to simulate other transaction information.\nThe identity payload cannot be null and must be valid IVMS101, but may be partially or completely filled in depending on the corresponding beneficiary policy.\nPartial Identity: Contains only the originator and originating vasp identities Complete Identity: Contains the originator, beneficiary, and originating and beneficiary vasp identities Create a sealed envelope using either the directory service or direct key exchange to fetch the rVASP RSA public keys and use AES256-GCM and HMAC-SHA256 as the envelope cryptography. Then, use the TRISANetwork service Transfer RPC to send the sealed envelope to the rVASP.\nSee Secure Envelopes for more on how to compose a valid secure envelope for transfers and the TRISA CLI for more on how to use a command line application for sending transfers.\nBeneficiary Policies The beneficiary policy determines how an rVASP responds to an incoming TRISA transfer message to its TRISA endpoint. Beneficiary policies are mapped to wallet addresses found in the transaction payload, which the rVASP uses to identify the beneficiary address. A description of the beneficiary policies follow:\nSyncRepair For the SyncRepair policy, the identity payload does not have to include the beneficiary identity, although it must be not null. The rVASP will respond synchronously by sending an accept response containing a received_at timestamp and the complete beneficiary identity.\nSyncRequire For the SyncRequire policy, the identity payload must contain a complete beneficiary identity as defined in the TRISA whitepaper. The rVASP will respond synchronously by sending an accept response containing a received_at timestamp in the payload. If the beneficiary information is incomplete or incorrect, the rVASP will respond with a rejection error.\nAsyncRepair For the AsyncRepair policy, the identity payload does not have to include the beneficiary identity. In order to complete the transaction, the originator must:\nSend a Transfer request to the rVASP containing “partial” transaction and identity information. The transaction payload must contain a valid beneficiary address but the identity payload does not have to contain full beneficiary info. Receive a trisa.data.generic.v1beta1.Pending response from the rVASP containing reply_not_before and reply_not_after timestamps, specifiying the beginning of an asynchronous transaction. Be ready to receive an asynchronous callback from the rVASP within the time window. This can be done by caching the original pending message and waiting for a Transfer request from the rVASP with the same envelope Id and within the time window specified in the pending message. Respond to the callback RPC with a resealed envelope containing a received_at timestamp in the payload. Initiate a new Transfer request to the rVASP containing any final transaction details (txid, etc.). Receive another pending response from the rVASP which initiates a final asynchronous handshake. Receive a second Transfer callback request from the rVASP containing the full transaction payload and full identity payload along with a received_at timestamp. Finalize the transaction by echoing the envelope back to the rVASP. The entire AsyncRepair workflow between two rVASPs is displayed below, where Alice is acting as the originator and Bob is acting as the beneficiary.\nsequenceDiagram autonumber Alice-\u003e\u003eBob: Transfer() Partial Identity Info + Partial Transaction activate Bob Bob--\u003e\u003eAlice: Pending (5-10 min) activate Alice Bob-\u003e\u003eAlice: Transfer() Full Identity Info + received_at deactivate Bob Alice-\u003e\u003eBob: Echo Payload deactivate Alice Alice-\u003e\u003eBob: Transfer() Full Identity Info + Full Transaction activate Bob Bob--\u003e\u003eAlice: Pending (5-10 min) activate Alice Bob-\u003e\u003eAlice: Transfer() Full Identity Info + Full Transaction + received_at deactivate Bob Alice-\u003e\u003eBob: Echo Payload deactivate Alice AsyncReject The AsyncReject policy simulates a synchronous rejected transaction. In this policy, the identity payload does not have to include the beneficiary identity, and the rVASP will respond with a pending message as in the AsyncRepair policy. The difference is that the rVASP will send a callback Transfer within the time window containing an TRISA rejection error, indicating that the transaction has been rejected.",
"description": "Working with rVASPs for TestNet integration",
"tags": [],
"title": "Robot VASPs",
"uri": "/testing/rvasps/index.html"
},
{
"breadcrumb": "TRISA Developer Documentation",
"content": "Built to help compliance teams handle travel rule exchanges efficiently and economically, Envoy is an open source, secure, peer-to-peer messaging platform. Designed by TRISA engineers and compliance experts, Envoy offers a mechanism for Travel Rule compliance by providing IVMS101 data exchanges using the TRISA and TRP protocols.\nKey Benefits Intuitive UI: Send and receive TRISA \u0026 TRP messages with a user-friendly interface. Efficient Administration: Simplify setup and maintenance with our admin tools. Secure Decentralized Messaging: Protect customer privacy and IVMS101 data with encrypted peer-to-peer communication. Compliance-Friendly API: A straightforward JSON REST API for seamless TRISA \u0026 TRP interactions. Not Included It is important to understand what Envoy is, and also, what Envoy is not.\nEnvoy is strictly a secure messaging service designed to meet FATF requirements.\nEnvoy does not:\nInclude on chain analytics or automated KYC/AML checks. Future plug-ins may be available for on-chain analytics or KYC checks. Solve the Sunrise problem (nothing does yet). Implementation Options You have three options to deploy or manage your Envoy node:\nDIY: Envoy is open source (MIT License). You’re free to download, install, integrate, host and support your own node. You’re also free to fork and modify the node for your own use cases. Provided you have the technical capabilities and availability, you can have complete flexibility and control of your deployment! One-time Integration Service: For a one-time fee, the Envoy team will install and configure your Envoy node in your environment while you host, maintain, and support the node on an ongoing basis. The Envoy team will provide some training to get started with your node, and upgrade emails when it is time to update the Envoy version. Managed Service: If you’re looking to get something up and running now, The Envoy team will install, configure, host, maintain, and support an Envoy node for you. This documentation is focused on the DIY option. If you’d like more information on the one-time integration service or managed services, please schedule a demo with the Envoy team!\nData Storage and Security Because Envoy is intended to exchange and store compliance information that is by nature PII (Personally Identifiable Information), security and privacy is a top-of-mind concern. To that end, Envoy works to ensure data is stored in a secure and protected fashion.\nData Storage Nodes must store compliance data locally on disk in a backend store. Currently only sqlite3 is supported, but Postgres and other databases may be options in the future. When configuring an Envoy node, ensure:\nEnough disk is provisioned for long-term travel rule data storage. Ensure that the disk is independently secured and encrypted, particularly if you are hosting your Envoy service on a shared architecture or the cloud. If you’re using an external database, ensure it is not accessible from the public Internet. Security Envoy employs TRISA cryptographic security standards for data in-flight and at-rest. Data exchanges are secured by mTLS when conducted over the TRISA network and if available for a TRP exchange. All TRP exchanges require valid TLS certificates to establish a secure connection.\nTravel Rule PII is stored as secure envelopes with original TRISA cryptography. Even if the transfer occurs over TRP, a secure envelope is created to store the information on disk. Secure envelopes use multi-stage strong encryption, encrypting data symmetrically with AES-256, signing the data with HMAC-256, then encrypting the encryption keys and hmac secrets via asymmetric encryption using RSA-OAEP-256.\nOne you delete the private keys used to seal secure envelopes – the data encrypted with those keys is effectively deleted.\nSome indexing information is extracted for lookups and and search, but is not PII.\nKey Management Public key management is required for effective use of Envoy. Envoy can store key material locally on the same disk as its database, but this is not recommended. Instead we recommend the use of a key store or vault such as Google Secret Manager or Hashicorp Vault.\nAuthentication and Access We strongly recommend that the internal UI and API is restricted to specific IP addresses or accessed from within a VPN. This will prevent brute force attacks on your Envoy node.\nPasswords and API Key secrets are stored on the Envoy disk as Argon2 hashes that cannot be reversed. Argon2 is a password-hashing function that includes a time and memory cost to balance defense against cracking attacks. Even using Argon2, it is still recommended that passwords are routinely changed and that strong passwords are generated. API keys should also be revoked if not in use, or recycled on a routine basis.",
"description": "Using the TRISA Envoy self-hosted node",
"tags": [],
"title": "TRISA Envoy",
"uri": "/envoy/index.html"
},
{
"breadcrumb": "TRISA Developer Documentation",
"content": "This section of the documentation describes the TRISA Protocol and API.\nNavigating the Open Source TRISA Code The trisa repository contains a gRPC implementation of the TRISA protocol as described by the white paper, which leverages protocol buffers and Golang.\nThe proto folder contains the core RPC definitions, including:\nthe interVASP Messaging Standard (IVMS) message definitions, which serve as the basis for how two VASP peers should mutually describe entities involved in cryptographic transfers, including names, locations, and government identifiers. This is the spec that will allow originators to identify themselves to beneficiaries and to request information from those beneficiaries to meet the legal requirements of their regulators. the TRISA Network’s service definitions, essentially how the different parts of the API work — from the exchange of keys (to ensure both peers have the requisite details to exchange information) to the transfer of “secure envelopes” (cryptographically sealed protocol buffer messages that can only be decrypted by the intended recipient). The trisa subfolder also contains generic message types for transactions that are intended to provide maximum flexibility for a wide range of TRISA use cases. The pkg folder contains the reference implementation code, including compiled code generated from the protocol buffer definitions in the proto folder1.\nThe iso3166 folder contains language codes. The ivms101 folder extends the generated protobuf code with JSON loading utilities, validation helpers, short constants, etc. The trisa folder contains structs and methods for a range of TRISA-related tasks, such as performing cryptography and making mTLS connections. The lib folder is intended to showcase utility code similar to that in the pkg folder, but for languages other than Go. If you work in a language other than go, this would be a great place to start your contribution!\nAnother integral part of the TRISA protocol is the Global Directory Service, which serves as a look-up tool for TRISA members to identify peers with which they wish to exchange information. For RPC definitions and implementation code related to the Global Directory Service, visit the companion directory repository.\nNote that these compiled files are compiled for Golang; but this is certainly not the only option. Those interested in building implementation code in a different language should look to the lib folder, which currently contains placeholder folders but is intended to showcase such other implementations (including compiled protocol buffer code for these other languages). ↩︎",
"description": "Navigating the Open Source TRISA Code",
"tags": [],
"title": "TRISA Protocol and API",
"uri": "/api/index.html"
},
{
"breadcrumb": "TRISA Developer Documentation \u003e Testing and Deployment",
"content": "The TRISA command line client is a utility that assists TRISA integrators and developers testing their TRISA service. Advanced users may also use the TRISA client to execute TRISA requests for compliance purposes, although this is not recommended for extensive use. To install the latest version of the TRISA CLI, you must have Go installed on your computer. The following command will install the latest version of the CLI:\n$ go install github.com/trisacrypto/trisa/cmd/trisa@main Note We are currently working on a release mechanism that will automatically build the CLI for a variety of platforms so that in the future you will not need to have Go installed. Stay tuned!\nConfiguration Before you can start using the TRISA CLI, you must first configure your environment to ensure that you can successfully connect to a remote peer or the directory service.\nPrerequisites:\nThe trisa command installed and on your $PATH Your testnet certificates that include both the trust chain and private key. The TRISA CLI command is configured via flags specified for each command or by setting environment variables in your shell with the configuration. The CLI also supports the use of .env files in the current working directory for configuration. To see what CLI flags should be specified use trisa --help. An example .env configuration file is as follows:\n# The endpoint to the TRISA node that you'd like to connect to. The endpoint can be # found using the directory service lookup command. TRISA_ENDPOINT=example.com:443 # Directory service you'd like to connect to. You can specify a short name such as # \"testnet\" or \"mainnet\" or the endpoint of the directory service to connect to. The # configured directory is trisatest.net by default. TRISA_DIRECTORY=testnet # Path to your TRISA identity certificates that include the private key. This can be the # original .zip file sent by Sectigo or the unzipped .p12 file; in which case the # PKCS12 password must also be supplied. If you've decrypted it manually it should be in # PEM encoded format with the .pem or .crt extension. TRISA_CERTS=path/to/certs.pem # If you've split your certs into the public trust chain without private keys and a # private key file, then specify the path to the trust chain (optional). TRISA_TRUST_CHAIN=path/to/chain.pem # If the certs are PKCS12 encrypted then specify the password for decryption (optional). TRISA_CERTS_PASSWORD=supersecret The simplest way to get started with TRISA is to copy and paste the above snippet into a .env file in your current directory, then modifying the values as necessary.\nCreating Secure Envelopes The first step when using the TRISA CLI is to create some payload data that can be sealed inside of secure envelopes for TRISA envelopes. At a minimum, there are two JSON files that you need to create or provide for the payload:\nAn identity payload containing IVMS 101 data. A transaction payload containing a Transaction or Pending message. The identity payload is the compliance information required for the transfer and the transaction payload is used to identify the transaction on the chain and associate it with the identity information. For ease of data entry, these files may be specified as JSON files and the protocol buffer payload created using the trisa make command.\n$ trisa make -i identity.json -t transaction.json -o envelope.json With no other arguments, this command creates an unsealed envelope that has a random envelope ID, the current time as the sent at timestamp, and no received at timestamp in the payload. The documentation refers to this kind of secure envelope as a “payload template” in the rest of the documentation because it can be loaded by the trisa seal or trisa transfer commands to update the envelope ID, timestamps, before sealing the envelope with the public keys of the recipient.\nTo create a complete envelope or a fully sealed envelope, simply specify the public sealing key with the -seal flag as well as any additional metadata you’d like to supply on the envelope such as the envelope ID (see trisa make --help for more details).\nSealing To seal an envelope you must have the public keys of the recipient, see the key exchanges section for more detail on how to retrieve the public sealing key of a remote peer. Once you’ve exchanged keys and saved them to disk, you can seal an unsealed envelope with the following command:\n$ trisa seal -in unsealed_envelope.json -out sealed_evelope.json -seal public.pem Once the envelope has been sealed, only the recipient with the private key counterpart to the public key used to seal the envelope can open the secure envelope.\nWhile sealing the envelope you also have the opportunity to update the envelope, e.g. to mark the received at timestamp or set a different envelope ID to create a new transfer:\n$ trisa seal -in envelope.json -out sealed.json -seal public.pem -received-at now Another common workflow is to generate an error envelope with the same ID as an incoming envelope. Error envelopes do not require any cryptography, so the public key is not required:\n$ trisa seal -in envelope.json -error-code COMPLIANCE_CHECK_FAIL -error-message \"sanctioned entity\" Opening By default the trisa open command is used to unseal an envelope and save it as an unsealed envelope for further processing. This command can also be used to extract the payload or check if an incoming envelope has an error on it. To extract an unsealed envelope and save it to disk:\n$ trisa open -in envelope.json -out unsealed_envelope.json -key private.pem If you add the -payload flag, then the payload will be decrypted and saved to disk; adding the -error flag will extract an error and save it to disk. If the envelope.json is an unsealed envelope, then the -key flag can be omitted. If the -out flag is ommitted, the contents will be printed to disk. For example to simply view the payload of a sealed envelope:\n$ trisa open -in envelope.json -key private.pem -payload Or to view an error on the envelope:\n$ trisa open -in envelope.json -error Note that no private key is required for errors since errors are not encrypted.\nTip By default a key exchange will use your TRISA identity certs as the sealing key, however the trisa open command won’t automatically use your TRISA identity certs for unsealing the envelope. If you used the default key exchange then you can take advantage of the environment configuration to pass the path to your identity certs that contain your private key as follows:\n$ trisa open -in envelope.json -key $TRISA_CERTS Interacting with TRISA Peers The primary use of the trisa CLI is to execute TRISA RPC requests to a TRISA node. A general workflow is as follows:\nIdentify the peer endpoint using the Directory Service lookup or search functionality. Create a secure envelope or payload template to prepare to send to the remote peer. Perform a key exchange with the remote peer and save the sealing keys. Seal the secure envelope or payload template with the remote peer’s sealing keys. Execute a transfer and save the response envelope. This workflow generally mirrors the workflow of live TRISA compliance operations, though many of the steps are manual to facilitate integration and development.\nTransfers Send a secure envelope to the remote TRISA peer and receive a secure envelope in exchange. Transfers are the central compliance exchange mechanism in the TRISA protocol. If you have already created and sealed an envelope, saving it to outgoing.json you can transfer it as follows:\n$ trisa transfer -i outgoing.json -o response.json This will execute the TRISA transfer and save the response, including TRISA error envelopes, to disk at the specified path. If the extension of the output path is .json then the envelope is marshaled to .json format, if it is the .pb extension it will be saved as a raw protocol buffer. If the -o flag is not supplied, then the JSON response will be printed to the command line. If you would like the decrypted payload printed, then you must provide the private sealing key:\n$ trisa transfer -i outgoing.json -k private.pem If both an output path and the private key are provided then a JSON file is produced with the unsealed envelope that can be read using the open command or resent using the seal command.\nYou can also use a secure envelope payload template to seal and transfer an envelope in one step instead of using the intermediate seal command:\n$ trisa transfer -i outgoing.json -s public_sealing_key.pem See sealing secure envelopes for more information on the command line arguments that can be used to adapt secure envelopes before sending them.\nIf you would like to send an error-only secure envelope to the recipient, then you must supply the envelope ID, error code, and error message as follows:\n$ trisa transfer -I envelope-id-foo -C COMPLIANCE_CHECK_FAIL -E \"something went wrong\" Note that sending an error-only secure envelope is usually a response to an incoming message. This mechanism is used primarily to test a server’s handling of an asynchronous transfer workflow.\nNote The TRISA CLI command currently does not implement the TRISANetwork/TransferStream birdirectional streaming RPC and does not have plans to implement this in the CLI. If you would like an implementation of streaming from the command line, please open an issue on our GitHub repository.\nKey Exchanges Send a key exchange request to get the public sealing key of the node. Key management is a somewhat complex topic, and the TRISA CLI attempts to do the simplest possible thing to enable testing and development. A key exchange requires you to send your public sealing keys to the remote node, and they will return keys to you. Prior to a transfer, a key exchange must be completed so that you have the sealing keys to create a secure envelope and so that the remote has your public keys to send a response.\nBy default, the TRISA CLI will simply use your TRISA mTLS identity certificates as the keys for a key exchange. The simplest exchange is therefore:\n$ trisa exchange -o peer_sealing_keys.pem The -o flag saves the keys to disk at the specified path, so that you can use the keys later on to make secure envelopes or conduct transfers. If the -o flag is ommitted, the JSON data of the response, an SigningKey protocol buffer message will be printed to stdout. There are several formats that the keys can be saved in: a path with a .json or .pb extension will save the protocol buffer message to disk in the specified format; a path with a .pem or .crt extension will save the keys as PEM encoded public key.\nTo send alternative keys to the remote peer in a key exchange, you may use the -i flag to specify the path of keys to send. If the input path ends in .json or .pb it is parsed as a SigningKey protocol buffer message in JSON format or raw protobuf format respectively. If the input path ends in .pem or .crt it is parsed as a PEM encoded public key or x.509 certificate. Note that the PEM encoded format, the first PUBLIC KEY or CERTIFICATE block that is found is used for parsing.\nTo generate your own RSA keys to send to the remote server for key exchange, use the following commands:\n$ openssl genrsa -out private.pem 4096 $ openssl rsa -in private.pem -pubout -out public.pem This will create two files, private.pem that contains your private keys and public.pem which contains your public keys. Send the public key to the remote TRISA peer as follows:\n$ trisa exchange -i public.pem -o peer_sealing_keys.pem Ensure that you keep the private.pem file so that you can decrypt transfers that follow; it is likely that the remote TRISA node will use the key you just exchanged in sending outgoing transfers and preparing responses to your transfers. The only way to decrypt that data is with the private key!\nAddress Confirmation Warning Address confirmation has not yet been fully defined by the TRISA working group. The TRISA technical subcommittee is currently working on the Address Confirmation protocol, so stay tuned for more information!\nHealth Checks Send a health check request to check the status of the TRISA node.\nThe health check RPC is primariliy for the directory service to monitor if the TRISA network is online, however it is also useful for debugging or diagnosing connection issues (e.g. is the remote peer offline or are my certificates invalid). A simple health check request is as follows:\n$ trisa status Use the --insecure flag to connect without mTLS credentials, though not all TRISA peers will support an insecure status check.\nInteracting with the GDS The TRISA CLI supports some basic interactions with the TRISA Global Directory Service (GDS) based on your initial configuration.\nLookup Lookup a TRISA VASP by common name or VASP ID. The following requests will lookup Alice on the TestNet by both common name and ID:\n$ trisa lookup -n api.alice.vaspbot.net $ trisa lookup -i 7a96ca2c-2818-4106-932e-1bcfd743b04c Lookups also support the registered directory argument if looking up a VASP that is a member of the network but was issued certificates from a different directory service. If omitted, by default the directory service will lookup the VASP record as though it was the registered directory.\nSearch Search for a TRISA VASP by name or by website. You can specify multiple names and websites to expand your search. E.g. to search for “Alice” and “Bob” on the TestNet:\n$ trisa search -n alice -n bob If this returns too many results you may specify either category or country filters for the results. Country filters are inclusive and should be ISO Alpha-2 country codes:\n$ trisa search -n alice -n bob -c US -c SG Tip Categories are case sensitive and websites must be full URLs for the search to work. If you’re not getting any results for a website search, try adding the http:// prefix or removing any paths from the URL. If you’re not getting any results for the name, try using a prefix of the name that is greater than 3 characters.\nCategories that may be helpful in filtering:\nVASP Categories Business Categories Exchange PRIVATE_ORGANIZATION DEX GOVERNMENT_ENTITY P2P BUSINESS_ENTITY Kiosk NON_COMMERCIAL_ENTITY Custodian OTC Fund Project Gambling Miner Mixer Individual Other Guided Walkthrough This section contains a guided walkthrough of an interaction with the [Alice rVASP](% relref “rvasps.md” %}}) using the CLI. To complete this walkthrough you will need TRISA TestNet certificates issued by the TRISA Global Directory Service, the trisa CLI application installed and configured with those certs as discussed at the top of this guide. Ensure that the $TRISA_DIRECTORY environment variable is set to testnet.\nFirst, perform a TRISA Global Directory search for the Alice VASP:\n$ trisa search -n alice { \"error\": null, \"results\": [ { \"id\": \"7a96ca2c-2818-4106-932e-1bcfd743b04c\", \"registered_directory\": \"trisatest.net\", \"common_name\": \"api.alice.vaspbot.net\", \"endpoint\": \"api.alice.vaspbot.net:443\" } ] } To get more information about Alice VASP, lookup the record in the GDS:\n$ trisa lookup -cn api.alice.vaspbot.net { \"name\": \"AliceCoin\", \"country\": \"US\", [...] } The rest of the interactions will be with the Alice rVASP, so ensure that the $TRISA_ENDPOINT environment variable is set to api.alice.vaspbot.net:443 (or whatever endpoint was returned by the directory service).\nTip Managing the environment variables for configuring the trisa CLI can be done with a .env file in your current working directory.\nDownload a copy of the following data for the payload:\nidentity.json transaction.json This contains payload information as though we are sending Alice a compliance information transfer from a VASP named “MyVASP”.\nBuild the payload template:\n$ trisa make -i identity.json -t transaction.json -o unsealed_envelope.json This should create an unsealed envelope with the payload data, the sent at timestamp set to now and a random envelope ID. To view the payload in the unsealed envelope:\n$ trisa open -i unsealed_envelope.json -payload Conduct a key exchange with Alice to get Alice’s public keys to seal the envelope:\n$ trisa exchange -o alice.pem You can then seal the envelope so that only Alice can open it:\n$ trisa seal -i unsealed_envelope.json -s alice.pem -o outgoing.json You can now make the transfer to Alice:\n$ trisa transfer -i outgoing.json -o incoming.json View the payload from Alice using your private key to decrypt the message. Note that you’ll need to source the .env file for the following command to work if you’re using the .env file for configuration:\n$ source .env $ trisa open -i incoming.json -k $TRISA_CERTS -payload Warning If you receive the following error when running the above command:\nenvelope in unhandled state corrupted It means that the rVASP is running an older TRISA version. Please contact the TRISA admins if this is the rVASP running in TestNet or use the latest docker image if you’re running an rVASP in your local environment.",
"description": "Using the TRISA command line interface for development",
"tags": [],
"title": "TRISA CLI",
"uri": "/testing/trisa-cli/index.html"
},
{
"breadcrumb": "TRISA Developer Documentation \u003e TRISA Envoy",
"content": "A brief summary of a travel rule compliance exchange with Envoy is as follows:\nThe originating VASP identifies a counterparty either via a Travel Address (TRP) or by using the counterparties list (TRISA). Optionally, an address confirmation message is sent to the counterparty to confirm the counterparty controls the specified wallet address. The originating VASP creates a transaction then sends a secure envelope to the counterparty via TRISA or TRP (or email) so that they can review it. The counterparty VASP reviews the information then accepts it if it meets their compliance requirements or rejects it if it doesn’t. If accepted, the originating VASP completes the on-chain transaction, then sends a completion message back to the counterparty with the transaction ID. There are four basic workflows:\nAccepted and Completed Repairs Requested Rejected and/or Canceled Accepted and Completed sequenceDiagram autonumber participant Oc as Originator User participant O as Originator Envoy participant B as Beneficiary Envoy participant Bc as Beneficiary User rect rgb(236, 250, 220) note over Oc,Bc: Travel Rule Information Exchange Started Oc -\u003e\u003e O: Transaction Draft O -\u003e\u003e B: envelope started B -\u003e\u003e O: envelope pending O -\u003e\u003e Oc: Transaction Pending B -\u003e\u003e Bc: Transaction Review end critical Bc -\u003e\u003e Bc: KYC and Sanctions Checks end rect rgb(27, 206, 159 ) note over Oc,Bc: Accept IVMS101 with or without Modifications Bc -\u003e\u003e B: Accept Transaction B -\u003e\u003e O: envelope accepted O -\u003e\u003e B: echo envelope accepted B -\u003e\u003e Bc: Transaction Accepted O -\u003e\u003e Oc: Transaction Accepted end critical Oc -\u003e\u003e Oc: Perform on chain transaction end rect rgb(236, 250, 220) note over Oc,Bc: Complete the On-Chain Transaction Oc -\u003e\u003e O: Complete Transaction O -\u003e\u003e B: envelope completed B -\u003e\u003e O: echo envelope completed O -\u003e\u003e Oc: Transaction Completed B -\u003e\u003e Bc: Transaction Completed end Repairs Requested sequenceDiagram autonumber participant Oc as Originator User participant O as Originator Envoy participant B as Beneficiary Envoy participant Bc as Beneficiary User rect rgb(236, 250, 220) note over Oc,Bc: Travel Rule Information Exchange Started Oc -\u003e\u003e O: Transaction Draft O -\u003e\u003e B: envelope started B -\u003e\u003e O: envelope pending O -\u003e\u003e Oc: Transaction Pending B -\u003e\u003e Bc: Transaction Review end critical Bc -\u003e\u003e Bc: KYC and Sanctions Checks end rect rgb(240,186,200) note over Oc,Bc: Originator did not Provide Sufficient Information for Jursidiction Bc -\u003e\u003e B: Reject with retry B -\u003e\u003e O: envelope repair O -\u003e\u003e B: envelope pending B -\u003e\u003e Bc: Transaction Pending O -\u003e\u003e Oc: Transaction Repair end critical Oc -\u003e\u003e Oc: Required KYC and Repair end rect rgb(236, 250, 220) note over Oc,Bc: Originator Repairs Payload with Requested Information Oc -\u003e\u003e O: Transaction Repaired O -\u003e\u003e B: envelope review B -\u003e\u003e O: envelope pending O -\u003e\u003e Oc: Transaction Pending B -\u003e\u003e Bc: Transaction Review end critical Bc-\u003e\u003e Bc: Validate fixes meet requirements end rect rgb(27, 206, 159 ) note over Oc,Bc: Repair now meets Jurisdictional Requirements Bc -\u003e\u003e B: Accept Transaction B -\u003e\u003e O: envelope accepted O -\u003e\u003e B: echo envelope accepted B -\u003e\u003e Bc: Transaction Accepted O -\u003e\u003e Oc: Transaction Accepted end critical Oc -\u003e\u003e Oc: Perform on chain transaction end rect rgb(236, 250, 220) note over Oc,Bc: Complete the On-Chain Transaction Oc -\u003e\u003e O: Complete Transaction O -\u003e\u003e B: envelope ompleted B -\u003e\u003e O: echo envelope completed O -\u003e\u003e Oc: Transaction Completed B -\u003e\u003e Bc: Transaction Completed end Transaction Rejected and/or Canceled sequenceDiagram autonumber participant Oc as Originator User participant O as Originator Envoy participant B as Beneficiary Envoy participant Bc as Beneficiary User rect rgb(236, 250, 220) note over Oc,Bc: Travel Rule Information Exchange Started Oc -\u003e\u003e O: Transaction Draft O -\u003e\u003e B: envelope started B -\u003e\u003e O: envelope pending O -\u003e\u003e Oc: Transaction Pending B -\u003e\u003e Bc: Transaction Review end critical Bc -\u003e\u003e Bc: KYC and Sanctions Checks end rect rgb(240,186,200) note over Oc,Bc: The On-Chain Transaction is not Possible after Compliance Checks Bc -\u003e\u003e B: Reject Transaction (no retry/repair) B -\u003e\u003e O: envelope reject O -\u003e\u003e B: echo envelope reject B -\u003e\u003e Bc: Transaction Rejected O -\u003e\u003e Oc: Transaction Rejected end critical Oc -\u003e\u003e Oc: Stop on chain transaction end Transaction States and Actions A transaction may be in one of the following states:\nStatus Description Unspecified The transfer state is unknown or purposefully not specified (zero value) Draft The transaction has been created but no secure envelopes have been sent yet Pending Awaiting a response from the counterparty Review Requires review by a compliance officer and some action taken Repair An error has been sent back from the counterparty requesting a change Accepted The TRISA exchange has been accepted by the counterparty; awaiting the on-chain transaction Completed The TRISA exchange and the on-chain transaction have been completed Rejected The TRISA exchange is rejected and no on-chain transaction should proceed Canceled The TRISA exchange is canceled before it was completed When a transaction is in one of the following states, a compliance officer or auto review policy must take one of the following actions:\nDraft: Start an information exchange by sending a secure envelope to the counterparty. This will cause the transaction to move to the Pending state. Pending: When awaiting a response from the counterparty, the only action that can be taken is to cancel the information exchange, sending a Rejection envelope with the CANCELED code to the reviewing counterparty. Review: Either accept or reject the transaction, triggering a message to be sent to the counterparty with the decision. If the transaction is accpeted it will move to the Accepted state; if the rejection reqires a repair (retry) then it moves into the Pending state, otherwise it moves into the Rejected state. Repair: Repair the issue and send a new secure envelope to the counterparty so that they can either accept or reject it. Alternatively if the requested information is not available, reject the requested changes. Accepted: Complete the transaction by sending the on-chain transaction ID to the counterparty so they can identify the transaction record. Completed: At this point the transaction is complete, so you can archive the transaction to long term storage without viewing it in the dashboard or API calls. Rejected: The transaction is also complete in a rejected state, so you can archive the transaction to long term storage. Canceled: Similar to Completed and Rejected, this is a final state, so the only action you might have is to archive the transaction to long term storage. A summary of the actions that can be taken are below:\nAction In Status(es) Description Send Draft Send a TRISA exchange message to the counterparty initiating the travel rule Transfer. Accept Review Accept the state of the TRISA exchange as having enough required compliance information for the on-chain transaction to continue. Reject Review, Repair Require the counterparty to include more information for the TRISA exchange or stop the on-chain transaction. Repair Repair Fix any deficiencies required by the counterparty and send a new message for review. Complete Accepted Once accepted, send the on-chain transaction ID and transaction details to the counterparty. Archive Completed Archive the completed transaction for the specified compliance period. Cancel Pending Send a message to the counterparty stopping the review process. Technically this can be sent at any time, but is most relevant when waiting for review.",
"description": "How Travel Rule information exchanges work in the Envoy UI and API",
"tags": [],
"title": "Envoy Workflows",
"uri": "/envoy/workflows/index.html"
},
{
"breadcrumb": "TRISA Developer Documentation \u003e OpenVASP/TRP Integration",
"content": "TRISA provides an openvasp.Client to make communicating with counterparty VASPs simpler and ensure that the TRP protocol is being completed successfully. To create a client:\nclient := openvasp.NewClient() Note Client options such as mTLS configuration are coming soon!\nInquiries To send a Travel Rule inquiry, use the client.Inquiry() method.\nThe client parses the routing for the Inquiry using the Inquiry.TRP field; at the very least, the Address and RequestIdentifier fields must be specified:\ntype TRPInfo struct { Address string // Address can be a Travel Rule Address, LNURL, or URL APIVersion string // Defaults to the APIVersion of the package RequestIdentifier string // A unique identifier representing the specific transfer APIExtensions []string // The names of any extensions uses in the request } The APIVersion field is automatically populated with the default version, and any extensions are populated from the Inquiry itself, so these can be ignored.\nThe Address field can be one of:\nLNURL Travel Address Plain HTTPS URL Note that the TRISA library has packages for creating and parsing LNURLs and Travel Addresses so that you do not have to import additional dependencies for your code.\nThe client returns a TravelRuleResponse, which you can use as though it were a regular http.Response object, including use cases like checking the http.StatusCode. However, you can also parse the InquiryResolution response as follows:\nfunc main() { client := openvasp.NewClient() inquiry := \u0026openvasp.Inquiry{ TRP: \u0026openvasp.TRP{ Address: \"ta2W2HPKfHxgSgrzY178knqXHg1H3jfeQrwQ9JrKBs9wv\", RequestIdentifier: \"129f6013-9125-4beb-9e86-bb20c440e164\" }, Asset: \u0026openvasp.Asset{}, Amount: 0.001, Callback: \"https://originator.com/confirm?t=i\", IVMS101: \u0026ivms101.IdentityPayload{}, } rep, err := client.Inquiry(inquiry) if err != nil { log.Fatal(err) } if rep.StatusCode == http.StatusOK { resolution, err := rep.InquiryResolution() if err != nil { log.Fatal(err) } fmt.Println(resolution) } else { log.Fatal(rep.Status) } } Confirmation To send a Transfer Confirmation, use the client.Confirmation() method.\nThe client parses the routing for the Confirmation using the Confirmation.TRP field; at the very least, the Address and RequestIdentifier fields must be specified:\ntype TRPInfo struct { Address string // Address can be a Travel Rule Address, LNURL, or URL APIVersion string // Defaults to the APIVersion of the package RequestIdentifier string // A unique identifier representing the specific transfer APIExtensions []string // The names of any extensions uses in the request } The APIVersion field is automatically populated with the default version, and any extensions are populated from the Confirmation itself, so these can be ignored.\nThe client returns a TravelRuleResponse however, a simple 204 No Content response is expected for a confirmation, so there is no JSON body to parse.\nfunc main() { client := openvasp.NewClient() confirm := \u0026openvasp.Confirmation{ TRP: \u0026openvasp.TRP{ Address: \"https://beneficiary.com/confirm?t=i\", RequestIdentifier: \"129f6013-9125-4beb-9e86-bb20c440e164\", }, Canceled: \"the transaction could not be completed\", } rep, err := client.Confirmation(inquiry) if err != nil { log.Fatal(err) } if rep.StatusCode == http.StatusNoContent { fmt.Println(\"success!\") } else { log.Fatal(rep.Status) } }",
"description": "Making requests to other TRP nodes",
"tags": [],
"title": "TRP Client",
"uri": "/openvasp/client/index.html"
},
{
"breadcrumb": "TRISA Developer Documentation \u003e Global Directory Service \u003e Administration \u003e Configuration",
"content": "The BFF (backend for frontend) is the backend API that powers the GDS UI at vaspdirectory.net. The GDS UI is intended to give users a single access portal to both the MainNet and TestNet as well as to support non-GDS features like collaborators and TRISA Service Providers. Because of this it sits in the middle of multiple services, including both the MainNet and TestNet GDS services and multiple data sources. Its environment variables are all prefixed with the GDS_BFF_ tag. The primary configuration is as follows:\nEnvVar Type Default Description GDS_BFF_MAINTENANCE bool false Sets the server to maintenance mode, which will respond to requests with Unavailable except for status requests. GDS_BFF_BIND_ADDR string :4437 The IP address and port to bind the BFF http server on. GDS_BFF_MODE string release Sets the Gin mode, one of debug, release, or test. GDS_BFF_LOG_LEVEL string info The verbosity of logging, one of trace, debug, info, warn, error, fatal, or panic. GDS_BFF_CONSOLE_LOG bool false If true will print human readable logs instead of JSON logs for machine consumption. GDS_BFF_ALLOW_ORIGINS []string http://localhost:3000 A list of allowed origins for the CORS middleware to accept. GDS_BFF_REGISTER_URL string The base URL to direct users to for registration signup (no trailing slash) - used in email templates. GDS_BFF_LOGIN_URL string The base URL to direct users to for login (no trailing slash) - used in email templates. GDS_BFF_COOKIE_DOMAIN string The domain to set secure cookies for (particularly for CSRF and authentication). GDS_BFF_SERVE_DOCS bool false If true, OpenAPI documentation is compiled and served alongside the BFF API. User Cache Config The BFF interacts with Auth0 to fetch data about users. To reduce the number of Auth0 network lookups an expiring LRU cache is used to store user information for a fixed amount of time while bounding the amount of space used by the cache. The configuration for the user cache is as follows:\nEnvVar Type Default Description GDS_BFF_USER_CACHE_ENABLED bool false Enable user caching to reduce lookups with the Auth0 API. GDS_BFF_USER_CACHE_SIZE uint 16384 The size in bytes to limit the LRU cache to. GDS_BFF_USER_CACHE_EXPIRATION duration 8h How long to keep records in the cache before forcing a new lookup. Auth0 Config The BFF uses Auth0 for authentication and authorization and must connect to the Auth0 Management API in order to manage users. The Auth0 client is configured as follows:\nEnvVar Type Default Description GDS_BFF_AUTH0_DOMAIN string The tenant domain provided by the Auth0 application or API (domain only, no scheme or path). GDS_BFF_AUTH0_ISSUER string Set to the custom domain if enabled in Auth0 (ensuring the trailing slash is set if required by the Auth0 configuration) - this will confirm the issuer from the Auth0 JWT tokens. GDS_BFF_AUTH0_AUDIENCE string The audience to verify for the Auth0 API configuration (usually the unique name of the API). GDS_BFF_AUTH0_PROVIDER_CACHE duration 5m Configures the JWKS caching provider to fetch public keys from Auth0 for JWT token validation. GDS_BFF_AUTH0_CLIENT_ID string The Client ID for the management API specified by Auth0. GDS_BFF_AUTH0_CLIENT_SECRET string The Client Secret for the management API specified by Auth0. GDS_BFF_AUTH0_TESTING bool false If true a mock authenticator is used for testing purposes. Network Configuration The network configuration enables the BFF to connect to the GDS Database, Directory API, and Members API for both the MainNet and TestNet networks. The required configuration and configuration values is the same for both networks but the environment variables are prefixed with GDS_BFF_TESTNET_ and GDS_BFF_MAINNET_ respectively.\nThe configuration without the prefixes is specified below, at the end of each section, we will provide an exhaustive list of environment variables that are required to fully configure the BFF for connecting to both the TestNet and MainNet GDS services.\nGDS Database Connection The GDS Database connection is a store connection that is similar to the BFF Database connection described in the following section. Configuration for the TestNet and MainNet database connections is as follows:\nEnvVar Type Default Description DATABASE_URL string Required, the DSN to connect to the database on (see below for details). DATABASE_REINDEX_ON_BOOT bool false When the server starts, instead of loading indexes from disk, recreate and save them. DATABASE_INSECURE bool false If set do not connect to the TrtlDB with mTLS authentication. DATABASE_CERT_PATH string The path to the mTLS client-side certs for database auth. DATABASE_POOL_PATH string The path to the mTLS public cert pools to accept server connections. Note that only a trtl:// database url should be used for network database connections and that DATABASE_REINDEX_ON_BOOT should always be false for the BFF.\nList of environment variables:\nGDS_BFF_TESTNET_DATABASE_URL GDS_BFF_TESTNET_DATABASE_INSECURE GDS_BFF_TESTNET_DATABASE_CERT_PATH GDS_BFF_TESTNET_DATABASE_POOL_PATH GDS_BFF_MAINNET_DATABASE_URL GDS_BFF_MAINNET_DATABASE_INSECURE GDS_BFF_MAINNET_DATABASE_CERT_PATH GDS_BFF_MAINNET_DATABASE_POOL_PATH GDS Directory API Configuration The BFF connects to the GDS TRISA Directory API to perform operations like registration submission, contact verification, and verification status lookups. The configuration for the directory API clients is as follows:\nEnvVar Type Default Description DIRECTORY_INSECURE bool false If false does not connect to the directory API using TLS. DIRECTORY_ENDPOINT string The endpoint (host:port) to connect to the directory API on. DIRECTORY_TIMEOUT duration 10s The connection timeout for directory API request and dial contexts. List of environment variables:\nGDS_BFF_TESTNET_DIRECTORY_INSECURE GDS_BFF_TESTNET_DIRECTORY_ENDPOINT GDS_BFF_TESTNET_DIRECTORY_TIMEOUT GDS_BFF_MAINNET_DIRECTORY_INSECURE GDS_BFF_MAINNET_DIRECTORY_ENDPOINT GDS_BFF_MAINNET_DIRECTORY_TIMEOUT GDS Members API Configuration The BFF connects to the secure GDS Members API to give logged in users access to the complete directory including listing verified members and updating their member record. The configuration for the members API client is as follows:\nEnvVar Type Default Description MEMBERS_ENDPOINT string The endpoint (host:port) to connect to the members API on. MEMBERS_TIMEOUT duration 10s The connection timeout for members API request and dial contexts. MEMBERS_MTLS_INSECURE bool false If false does not connect to the members API using mTLS. MEMBERS_MTLS_CERT_PATH string The path to the mTLS client-side certs for members API auth. MEMBERS_MTLS_POOL_PATH string The path to the mTLS public cert pools to accept server connections. List of environment variables:\nGDS_BFF_TESTNET_MEMBERS_ENDPOINT GDS_BFF_TESTNET_MEMBERS_TIMEOUT GDS_BFF_TESTNET_MEMBERS_MTLS_INSECURE GDS_BFF_TESTNET_MEMBERS_MTLS_CERT_PATH GDS_BFF_TESTNET_MEMBERS_MTLS_POOL_PATH GDS_BFF_MAINNET_MEMBERS_ENDPOINT GDS_BFF_MAINNET_MEMBERS_TIMEOUT GDS_BFF_MAINNET_MEMBERS_MTLS_INSECURE GDS_BFF_MAINNET_MEMBERS_MTLS_CERT_PATH GDS_BFF_MAINNET_MEMBERS_MTLS_POOL_PATH Database The BFF makes use of a globally replicated key-value store for persistence of BFF-specific data structures such as organizations and announcements. By default it uses the TrtlDB for this, but for testing or smaller deployments it can use a local LevelDB database instead.\nGenerally speaking, the BFF uses the same TrtlDB as the GDS MainNet instance, and we’ve ensured there are no namespace conflicts to prevent this. The BFF primary store can also be independent of the GDS stores if necessary.\nThe primary database store is configured as follows:\nEnvVar Type Default Description GDS_BFF_DATABASE_URL string Required, the DSN to connect to the database on (see below for details). GDS_BFF_DATABASE_REINDEX_ON_BOOT bool false When the server starts, instead of loading indexes from disk, recreate and save them. GDS_BFF_DATABASE_INSECURE bool false If set do not connect to the TrtlDB with mTLS authentication. GDS_BFF_DATABASE_CERT_PATH string The path to the mTLS client-side certs for database auth. GDS_BFF_DATABASE_POOL_PATH string The path to the mTLS public cert pools to accept server connections. The GDS_BFF_DATABASE_URL is a standard DSN with a scheme, host, path, and query parameters. In the case of the BFF the scheme can be either trtl:// or leveldb://.\nWhen connecting to a TrtlDB, the host and port need to be specified with a trailing slash, e.g. trtl://localhost:4436/. Connecting via mTLS is only relevant when connecting to a TrtlDB. If GDS_BFF_DATABASE_INSECURE is false, then the GDS_BFF_DATABASE_CERT_PATH and GDS_BFF_DATABASE_POOL_PATH are required.\nWhen connecting to a LevelDB, the path to the directory on disk where the leveldb should be stored must be passed to the DSN. To specify a relative path, use three slashes: leveldb:///relpath/to/db, to specify an absolute path use four: leveldb:////abspath/to/db.\nEmail and SendGrid The BFF uses SendGrid to send email notifications and to enable communication workflows with users and admins. Configure BFF to use SendGrid as follows:\nEnvVar Type Default Description GDS_BFF_SERVICE_EMAIL string TRISA Directory Service [email protected] The email address used as the sender for all emails from the BFF system. SENDGRID_API_KEY string API Key to authenticate to SendGrid with. GDS_BFF_EMAIL_TESTING bool false Use email in testing mode rather than send live emails. GDS_BFF_EMAIL_STORAGE string \"\" Directory to store test emails for “mark one eyeball” review. SendGrid is considered enabled if the SendGrid API Key is set. The service and admin email addresses are required if SendGrid is enabled.\nSentry The BFF uses Sentry to assist with error monitoring and performance tracing. Configure BFF to use Sentry as follows:\nEnvVar Type Default Description GDS_BFF_SENTRY_DSN string The DSN for the Sentry project. If not set then Sentry is considered disabled. GDS_BFF_SENTRY_SERVER_NAME string Optional - a server name to tag Sentry events with. GDS_BFF_SENTRY_ENVIRONMENT string The environment to report (e.g. development, staging, production). Required if Sentry is enabled. GDS_BFF_SENTRY_RELEASE string {{version}} Specify the release version for Sentry tracking. By default this will be the package version. GDS_BFF_SENTRY_TRACK_PERFORMANCE bool false Enable performance tracing to Sentry with the specified sample rate. GDS_BFF_SENTRY_SAMPLE_RATE float64 0.85 The percentage of transactions to trace (0.0 to 1.0). GDS_BFF_SENTRY_REPORT_ERRORS bool false If true sends gRPC errors to Sentry as exceptions (useful for development or staging) GDS_BFF_SENTRY_DEBUG bool false Set Sentry to debug mode for testing. Sentry is considered enabled if a DSN is configured. Performance tracing is only enabled if Sentry is enabled and track performance is set to true. If Sentry is enabled, an environment is required, otherwise the configuration will be invalid.\nNote that the sentry.Config object has a field Repanic that should not be set by the user. This field is used to manage panics in chained interceptors.",
"description": "Configuring the BFF for vaspdirectory.net",
"tags": [],
"title": "BFF",
"uri": "/gds/admin/configuration/bff/index.html"
},
{
"breadcrumb": "TRISA Developer Documentation \u003e Global Directory Service \u003e Administration",
"content": "TRISA GDS and TestNet services are primarily configured using environment variables and will respect dotenv files in the current working directory. The canonical reference of the configuration for a GDS service is the config package of that service (described below). This documentation enumerates the most important configuration variables, their default values, and any hints or warnings about how to use them.\nRequired Configuration\nIf a configuration parameter does not have a default value that means it is required and must be specified by the user! If the configuration parameter does have a default value then that environment variable does not have to be set.\nConfiguration Documentation GDS Node Configuration BFF Service Configuration React Apps Configuration TrtlDB Configuration",
"description": "Configuration Guide for GDS Services",
"tags": [],
"title": "Configuration",
"uri": "/gds/admin/configuration/index.html"
},
{
"breadcrumb": "TRISA Developer Documentation",
"content": "This section of the documentation contains resources for developers who are working with TRISA data, such as:\nIVMS101: TRISA uses the IVMS101 standard to describe participants in cryptographic transactions. Learn more in our documentation about working with IVMS101.\nSecureEnvelopes: The primary data structure for a TRISA exchange is the SecureEnvelope, a wrapper for compliance payload data that facilitates peer-to-peer trust in compliance information exchanges. Learn more in our documentation about creating and parsing Secure Envelopes.\nData Payloads: A TRISA Payload contains information to be securely exchanged for Travel Rule compliance. The payload is serialized and encrypted to be sent in a SecureEnvelope. Learn more in our documentation about different types of Payloads in TRISA.\nSigning and Sealing Keys: Your TRISA node will need to handle keys in a variety of formats, such as x.509 certificates on disk or marshaled data when sending keys in TRISA key exchanges. The Key Handler package provides helpful utilities for managing public/private key pairs used for sealing and unsealing SecureEnvelopes. Learn more in our documentation about the Key Handler package.",
"description": "Working with Data in TRISA",
"tags": [],
"title": "Working with TRISA Data",
"uri": "/data/index.html"
},
{
"breadcrumb": "TRISA Developer Documentation \u003e Global Directory Service",
"content": "The TRISADirectory service, defined in the proto/trisa/gds protocol buffers, specifies how TRISA clients should interact with the directory service to facilitate peer-to-peer transfers.\nThis service includes four types of RPCs:\nRPCs designed to support interactions with the Global Directory Service during a TRISA information transfer: Lookup and Search (Note: These are the primary Directory Service interactions.) RPCs designed to support the Directory Service registration and verification processes: Register and VerifyContact RPCs designed to supply the entity review and TRISA verification status of a given VASP: Verification RPCs designed to enable routine health check and status requests: Status (Note: these mirror the TRISAHealth service) service TRISADirectory { rpc Lookup(LookupRequest) returns (LookupReply) {} rpc Search(SearchRequest) returns (SearchReply) {} rpc Register(RegisterRequest) returns (RegisterReply) {} rpc VerifyContact(VerifyContactRequest) returns (VerifyContactReply) {} rpc Verification(VerificationRequest) returns (VerificationReply) {} rpc Status(HealthCheck) returns (ServiceState) {} } Lookup The Lookup RPC is designed to provide VASP certification information. Note that only verified VASPs are returned using the Lookup RPC.\nThis RPC expects a LookupRequest message, which provides either the VASP’s unique ID in the Global Directory Service, or the domain of their TRISA implementation endpoint (Note: this should be the common name of their certificate). If both id and common_name are supplied, the id field will be prioritized.\nThe registered_directory field is the URL of the directory that registered the VASP (e.g. either \"trisatest.net\" or \"vaspdirectory.net\"). If omitted, this value defaults to the directory currently being queried.\nmessage LookupRequest { string id = 1; string registered_directory = 2; string common_name = 3; } Note To use other name fields such as the legal business name, you must use the Search RPC.\nA LookupRequest returns a LookupReply message, which contains summary information intended to facilitate peer-to-peer verification and public key exchange.\nmessage LookupReply { // If no error is specified, the lookup was successful Error error = 1; // The uniquely identifying components of the VASP in the directory service string id = 2; string registered_directory = 3; string common_name = 4; // The endpoint to connect to for the TRISA P2P protocol (addr:port) string endpoint = 5; // Certificate information if the VASP is available and verified. The identity // certificate is used to establish mTLS connections, the signing certificate is // used on a per-transaction basis. trisa.gds.models.v1beta1.Certificate identity_certificate = 6; trisa.gds.models.v1beta1.Certificate signing_certificate = 7; // Other VASP information to facilitates P2P exchanges string name = 8; string country = 9; string verified_on = 10; } Search The Search RPC allows more flexible search to identify member VASPs. These requests are primarily used to locate a beneficiary VASP in order to begin the TRISA peer-to-peer protocol. Note that only verified VASPs are returned using the Search RPC.\nThe Search RPC expects a SearchRequest and returns a SearchReply. The SearchRequest message enables searching by (case insensitive) name and website (using OR logic). The name field can be the legal, short, or DBA name of the VASP. It could also be the common name of the certificate issued to that VASP, though in this case, it is recommended to use the Lookup RPC instead. The website must be a parseable URL.\nThe remaining fields are search filters on which to condition the search. Only VASPs in the specified country or category (both of which can be a single value or multiple values) will be returned.\nmessage SearchRequest { repeated string name = 1; repeated string website = 2; repeated string country = 7; repeated trisa.gds.models.v1beta1.BusinessCategory business_category = 8; repeated string vasp_category = 9; } A SearchRequest returns a SearchReply message containing potentially multiple Result messages. Note: if no error is returned, the search was successful, even if no results were returned.\nmessage SearchReply { message Result { // The uniquely identifying components of the VASP in the directory service string id = 1; string registered_directory = 2; string common_name = 3; // Address to connect to the remote VASP on to perform a TRISA request string endpoint = 4; } Error error = 1; repeated Result results = 2; } Verification The Verification RPC enables VASPs to check on the status of a VASP, including its verification status. If the queried TRISA directory service performs health check monitoring, this RPC will also perform a health check and return the service status.\nThe Verification RPC expects as input a VerificationRequest message, which provides either the VASP’s unique ID in the Global Directory Service, or the domain of their TRISA implementation endpoint (*Note: this should be the commone name of their certificate). If both id and common_name are supplied, the id field will be prioritized.\nThe registered_directory field is the URL of the directory that registered the VASP (e.g. either \"trisatest.net\" or \"vaspdirectory.net\"). If omitted, this value defaults to the directory currently being queried.\nmessage VerificationRequest { string id = 1; string registered_directory = 2; string common_name = 3; } Note While VerificationRequest expects the same parameters as the LookupRequest message described earlier in this page, a TRISA directory service may refuse to return all or part of the status request.\nA VerificationRequest returns a VerificationReply message:\nmessage VerificationReply { // Status information trisa.gds.models.v1beta1.VerificationState verification_status = 1; trisa.gds.models.v1beta1.ServiceState service_status = 2; string verified_on = 3; // Should be an RFC 3339 Timestamp string first_listed = 4; // Should be an RFC 3339 Timestamp string last_updated = 5; // Should be an RFC 3339 Timestamp string revoked_on = 6; // Should be an RFC 3339 Timestamp } Status The Status RPC is designed to enable routine health checks to verify the health of the Directory Service.\nThis RPC expects a HealthCheck message and returns a ServiceState message. The system is obliged to respond with the closest matching status in a best-effort fashion. Alerts will be triggered on service status changes if the system does not respond and the previous system state was not UNKNOWN.:\nmessage HealthCheck { // The number of failed health checks that proceeded the current check. uint32 attempts = 1; // The timestamp of the last health check, successful or otherwise. string last_checked_at = 2; } message ServiceState { enum Status { UNKNOWN = 0; HEALTHY = 1; UNHEALTHY = 2; DANGER = 3; OFFLINE = 4; MAINTENANCE = 5; } // Current service status as defined by the receiving system. Status status = 1; // Suggest to the directory service when to check the health status again. string not_before = 2; string not_after = 3; } Programmatic Registration Two of the TRISADirectory are designed to support programatic registration for third party service providers that would like to use the GDS to issue certs: Register and VerifyContact.\nRegister Registration requests submitted via the Register RPC are validated to ensure they contain correct information and then are sent through the verification process, creating or updating a VASP as needed.\nThe Register RPC expects a RegisterRequest message containing:\nThe LegalPerson IVMS 101 entity to enable VASP KYC information exchange. This is the IVMS 101 data that should be exchanged in the TRISA P2P protocol as the Originator, Intermediate, or Beneficiary VASP fields. A complete and valid identity record with country of registration is required. Technical, legal, billing, and administrative contacts for the VASP. The Travel Rule implementation trisa_endpoint where other TRISA peers should connect. This should be an addr:port combination, (e.g. trisa.vaspbot.net:443). The VASP’s common_name, which should be the domain name to issue certificates for and should match the domain in the trisa_endpoint. If this field is omitted, the common_name is inferred from the trisa_endpoint. Business information including website, business_category, vasp_categories, and the company’s established_on date (in YYYY-MM-DD format). The VASP’s trixo questionnaire data. For more information, see the TRIXO documentation. message RegisterRequest { ivms101.LegalPerson entity = 1; trisa.gds.models.v1beta1.Contacts contacts = 2; string trisa_endpoint = 3; string common_name = 4; string website = 5; trisa.gds.models.v1beta1.BusinessCategory business_category = 6; repeated string vasp_categories = 7; string established_on = 8; trisa.gds.models.v1beta1.TRIXOQuestionnaire trixo = 9; } A RegisterRequest returns a RegisterReply message containing verification metadata as well as a pkcs12password that must be used to decrypt the emailed certifications. For more information, see the PKCS12 password documentation. Do not lose or share this password!\nmessage RegisterReply { // If the registration was successful, no error will be returned Error error = 1; // Unique identifiers for the VASP created by the registration. // Use these identifiers for status lookup requests and any follow-on interactions. string id = 2; string registered_directory = 3; string common_name = 4; // The verification status of the VASP entity. trisa.gds.models.v1beta1.VerificationState status = 5; string message = 6; // Used to decrypt the emailed certificates in PKCS12 format string pkcs12password = 7; } VerifyContact The VerifyContact RPC expects a VerifyContactRequest contains the VASP’s unique ID in the Directory Service. The RPC returns as VerifyContactReply with the verification status of the queried VASP.\nmessage VerifyContactRequest { string id = 1; string token = 2; } message VerifyContactReply { // If no error is specified, the verification request was successful. Error error = 1; // The verification status of the VASP entity. trisa.gds.models.v1beta1.VerificationState status = 2; string message = 3; }",
"description": "How to use the GDS API as a client",
"tags": [],
"title": "Using the GDS API",
"uri": "/gds/api/index.html"
},
{
"breadcrumb": "TRISA Developer Documentation \u003e TRISA Protocol and API",
"content": "The TRISA Network Protocol implementation exposes several RPCs needed to build TRISA into your organization’s application, which are defined within the protocol buffers. All TRISA members must implement both services described by the TRISA protocol (the TRISANetwork service and the TRISAHealth service) to ensure that exchanges are conducted correctly and securely.\nThe protocol buffers can be compiled into the language of your choice. This section describes the protocol buffers for the TRISANetwork endpoint and the protocol buffer API in Go.\nNote You will need to download and install the protocol buffer compiler if you have not already.\nThe TRISANetwork Service The TRISANetwork service defines the peer-to-peer interactions between Virtual Asset Providers (VASPs) necessary to conduct compliance information exchanges.\nThe TRISANetwork Service has two primary RPCs, Transfer and TransferStream. Transfer and TransferStream allow VASPs to exchange compliance information before conducting a virtual asset transaction. KeyExchange allows public keys to exchange so that transaction envelopes can be encrypted and signed.\nservice TRISANetwork { rpc Transfer(SecureEnvelope) returns (SecureEnvelope) {} rpc TransferStream(stream SecureEnvelope) returns (stream SecureEnvelope) {} rpc ConfirmAddress(Address) returns (AddressConfirmation) {} rpc KeyExchange(SigningKey) returns (SigningKey) {} } Note The ConfirmAddress RPC is not currently implemented.\nTransfer and TransferStream RPCs The Transfer and TransferStream RPCs conduct the information exchange before a virtual asset transaction. The RPCs enable an originating VASP to send an encrypted transaction envelope to the beneficiary VASP containing a unique ID for the transaction, the encrypted transaction bundle, and metadata associated with the transaction cipher. In response, the beneficiary can validate the transaction request, then return the beneficiary’s transaction information using the same unique transaction ID.\nThe Transfer RPC is a unary RPC for simple, single transactions. The TransferStream RPC is a bidirectional streaming RPC for high throughput transaction workloads.\nSecureEnvelope A SecureEnvelope is the encrypted transaction envelope that is the outer layer of the TRISA information exchange protocol and facilitates the secure storage of Know Your Client (KYC) data in a transaction. The envelope specifies a unique id to reference the transaction out-of-band (e.g., in the blockchain layer). It provides the necessary information so only the originator and the beneficiary can decrypt the transaction data. For more information about Secure Envelopes, this section of the documentation further describes this primary data structure for the TRISA exchange.\nA SecureEnvelope message contains different types of metadata. The Anatomy of Secure Envelope section of this documentation further describes the envelope metadata, cryptographic metadata, and an encrypted payload and HMAC signature within the SecureEnvelope.\nmessage SecureEnvelope { string id = 1; bytes payload = 2; bytes encryption_key = 3; string encryption_algorithm = 4; bytes hmac = 5; bytes hmac_secret = 6; string hmac_algorithm = 7; Error error = 9; string timestamp = 10; bool sealed = 11; string public_key_signature = 12; TransferState transfer_state = 13; New in v1.1: the TransferState describes the condition of the transfer the sending party feels the Transfer of Travel Rule data is in. This can be optionally used to signal to the counterparty the intent of a transfer message. See TRISA Workflows for more information on how the transfer state works.\nenum TransferState { UNSPECIFIED = 0; // the transfer state is unknown or not specified STARTED = 1; // this is the first message in the TRISA workflow PENDING = 2; // action is required by the sending party REVIEW = 3; // action is required by the receiving party (rarely used) REPAIR = 4; // some state of the travel rule exchange requires repair ACCEPTED = 5; // the travel rule exchange is accepted and awaiting the transaction COMPLETED = 6; // the travel rule and on-chain transaction have been completed REJECTED = 7; // the travel rule exchange is rejected and should not proceed } ConfirmAddress RPC Note Address confirmation was initially described in the TRISA whitepaper as a mechanism to allow an originator VASP to establish that a beneficiary VASP has control of a crypto wallet address before sending transaction information with sensitive PII data.\nCurrently, there are three proposed address confirmation methods being tested: simple, key/token, and on-chain. Simple involves a simple yes/no check with the counterparty. Key/Token requires the counterparty to decrypt a token encrypted with the crypto address public keys, and on-chain implements a simple Satoshi test.\nAll three methods are available in the protocol buffers, but note that these are still being tested and developed, and may change at any time. No backward compatibility is guaranteed for these message types, nor is there any guarantee that any TRISA VASP will implement any of these confirmation methods.\nKeyExchange RPC The KeyExchange RPC allows VASPs to exchange public signing keys to facilitate transaction signatures if they have not already obtained them from the directory service.\nSigningKey SigningKey provides metadata for decoding a PEM encoded PKIX public key for RSA encryption and transaction signing. The SigningKey is a lightweight version of the certificate information stored in the Directory Service.\nmessage SigningKey { // x.509 metadata for reference without parsing the key int64 version = 1; bytes signature = 2; string signature_algorithm = 3; string public_key_algorithm = 4; // Validity information string not_before = 8; string not_after = 9; bool revoked = 10; // The serialized public key to PKIX, ASN.1 DER form. bytes data = 11; } The TRISAHealth Service and Status RPC The TRISAHealth service contains the Status RPC, which is optional but highly recommended for VASP members to implement. The Status endpoint allows TRISA members and the TRISA Directory Service to perform health checks with a VASP’s TRISA Node and report the service conditions of the TRISA network. Because a down TRISA node will prevent travel rule compliant virtual asset transactions, the health service is intended to quickly identify network problems and notify members as quickly as possible.\nNote The TRISAHealth service must also be behind mTLS so that the health check service can verify the identity certificates used for the TRISANetwork service.\nservice TRISAHealth { rpc Status(HealthCheck) returns (ServiceState) {} } HealthCheck HealthCheck specifies attempts, which is the number of failed health checks that proceeded the current check, and last_checked, which is the timestamp of the last health check, successful or otherwise.\nmessage HealthCheck { uint32 attempts = 1; string last_checked_at = 2; } ServiceState ServiceState returns the status, which is the Current service status as defined by the receiving system. The system must respond with the closest matching status in a best-effort fashion. Alerts will be triggered on service status changes if the system does not respond and the previous system state was not unknown. not_before and not_after are also returned; they suggest to the directory service when to recheck the health status.\nmessage ServiceState { enum Status { UNKNOWN = 0; HEALTHY = 1; UNHEALTHY = 2; DANGER = 3; OFFLINE = 4; MAINTENANCE = 5; } Status status = 1; // When to check the health status again. string not_before = 2; string not_after = 3; } TRISA API in Go The implementation of the TRISA Protocol Buffers in Go is compiled using protoc when go generate ./... is executed in the root of the repository. The compiled files in the TRISA repository contain the TRISA Network Protocol implemented in Go.\nThe TRISANetworkServer is the server API for TRISANetwork, while the TRISANetworkClient is the client API for the TRISANetwork service. Both contain the Transfer, TransferStream, ConfirmAddress, and KeyExchange methods described above as RPCs under the TRISANetwork service.\ntype TRISANetworkClient interface { Transfer(ctx context.Context, in *SecureEnvelope, opts ...grpc.CallOption) (*SecureEnvelope, error) TransferStream(ctx context.Context, opts ...grpc.CallOption) (TRISANetwork_TransferStreamClient, error) ConfirmAddress(ctx context.Context, in *Address, opts ...grpc.CallOption) (*AddressConfirmation, error) KeyExchange(ctx context.Context, in *SigningKey, opts ...grpc.CallOption) (*SigningKey, error) } type TRISANetworkServer interface { Transfer(context.Context, *SecureEnvelope) (*SecureEnvelope, error) TransferStream(TRISANetwork_TransferStreamServer) error ConfirmAddress(context.Context, *Address) (*AddressConfirmation, error) KeyExchange(context.Context, *SigningKey) (*SigningKey, error) } For further information, a reference implementation of the TRISA Network protocol is available in Go in the TRISA TestNet Repository,",
"description": "Describing the TRISA API",
"tags": [],
"title": "TRISA API",
"uri": "/api/api/index.html"
},
{
"breadcrumb": "TRISA Developer Documentation \u003e Working with TRISA Data",
"content": "The primary data structure for a TRISA exchange is the SecureEnvelope – a wrapper for compliance payload data that facilitates peer-to-peer trust in compliance information exchanges. The design of TRISA secure envelopes had the following requirements:\nPrivacy: only the recipient of the secure envelope should be able to open the secure envelope, even outside of the context of an RPC that is secured by transport layer encryption. Non-repudiation: the secure envelope should cryptographically guarantee that the compliance payload is valid and has not been modified or tampered with since the original exchange. Long-term data storage: the secure envelope should be encrypted at rest and can be “erased” by deleting its associated private keys when the compliance statute is over (usually 5-7 years). Security: secure envelopes should prevent statistical attacks on the encrypted payload data while using public-key cryptography for ease of key management. These requirements are essential to understanding how to successfully engage with TRISA peers, therefore understanding the SecureEnvelope is the first step to being able to implement the TRISA protocol.\nWorking with Secure Envelopes There are two basic workflows for secure envelopes: creating and sealing an envelope to send to a counterparty, or unsealing and parsing a received secure envelope.\nCreating a Secure Envelope Prerequisites:\nYou should have constructed an appropriate TRISA Payload that contains an identity (an IVMS 101 IdentityPayload), a transaction (a TRISA generic transaction) and a sent_at timestamp (RFC-3339 formatted). You should have the public sealing key of the receipient. You can obtain this key either via the KeyExchange RPC or by requesting the key from the directory service. Steps:\nCreate a new envelope with a uuid4 envelope ID and the current timestamp Marshal the Payload protocol buffers into an array of bytes. Generate an encryption key and encrypt the payload bytes. Generate an hmac secret and sign the encrypted payload Use the public sealing key of the recipient to encrypt the encryption key and hmac secret. Mark the envelope as sealed and populate all required metadata. Opening a Secure Envelope Use the public_key_signature to identify the private key required to decrypt the encryption key and hmac secret. Use your private sealing key to decrypt the encryption key and HMAC secret. Use the hmac secret and hmac algorithm to verify the encrypted payload has not been tampered with by ensuring the hmac you generate is identical to the hmac on the envelope. Use the encryption key and encryption algorithm to decrypt the payload. Unmarshal the payload into a TRISA Payload object. Unmarshal the identity and transaction payloads and verify that you can parse them into data structures you can use for your compliance workflow. Envelope States As you can see from the above workflows, envelopes can be in one of three states:\nSealed: the encryption key and hmac secret on the envelope are encrypted with the public key of the recipient. Only the recipient can open the envelope in this state. Unsealed: the encryption key and hmac secret are in the clear and can be used to decrypt the payload and verify the HMAC. Clear: the payload has been decrypted and can be unmarshaled into a TRISA Payload protocol buffer. Generally speaking, when working with secure envelopes, “sealing” an envelope moves it through the following states:\nPayload --\u003e Clear --\u003e Unsealed --\u003e Sealed Conversely opening an envelope moves it through the following states:\nSealed --\u003e Unsealed --\u003e Clear --\u003e Payload Maintaining envelopes in these various states can be useful to different applications. For example, an unsealed or clear envelope can be used to move data inside of an application while maintaining associated TRISA metdata. A sealed envelope can be used for long-term storage and with proper key-management, ensure erasure of the envelope simply by deleting the keys.\nThe Anatomy of a Secure Envelope A SecureEnvelope contains envelope metadata, cryptographic metadata, and an encrypted payload and HMAC signature. There are two types of complete envelope:\nAn error envelope containing complete envelope metadata and a TRISA error. This envelope is sent as a rejection or transfer control message back to the sender from the recipient. A payload envelope that has complete envelope and cryptographic metadata, as well as an encrypted payload and HMAC signature, but without an error. Payload envelopes can be either “sealed” or “unsealed” as described above. Envelope Metadata Field Definition id also referred to as the “envelope id” - this is a unique ID generated by the originator and must be identical on all envelopes referring to the same virtual asset transaction. The originator usually generates this ID as a UUID4. timestamp a nanosecond resolution RFC-3339 formatted timestamp (e.g. RFC3339Nano) that is used to order messages with the same ID. error a TRISA-specific error that is intended to help facilitate compliance exchanges. TRISA error codes are used to reject compliance data or to request a fix and retry in a follow-on secure envelope. Cryptographic Metadata Field Definition encryption_key the key used to encrypt the compliance payload. Keys are generated by the originator using a crypto random method. To prevent statistical attacks, a new key is generated for every transfer (e.g. at the same time as the envelope ID). If the envelope is sealed the encryption_key is encrypted using the public sealing key of the recipient. encryption_algorithm a string that describes the algorithm used to encrypt the compliance payload. This string should provide enough information for the recipient to be able to decrypt the payload. The default in the reference implementation is \"AES256-GCM\" which describes the use of AES Galois Counter Mode with a 32 byte key. hmac_secret the secret used to calculate the HMAC signature. This secret is generated by the originator using a crypto random method, and is generated for every transfer. If the envelope is sealed then the hmac_secret is encrypted using the public sealing key of the recipient. hmac_algorithm a string that describes the algorithm used to compute the HMAC signature. The default in the reference implementation is \"HMAC-SHA256\" which describes the use of the HMAC algorithm with a SHA-256 secure hashing function. sealed a boolean that describes the state of the envelope. If true, this means that the encryption_key and hmac_secret have been encrypted using the public sealing key of the recipient. public_key_signature the signature of the public key used to seal the envelope, a helper for the recipient to identify the private key required to unseal the envelope. Payload Field Definition payload the Payload protocol buffer marshaled to bytes and encrypted using the encryption_key. hmac the HMAC signature computed from the encrypted payload bytes and the hmac_secret. The Payload protocol buffer has the following fields:\nField Definition identity a protobuf any that contains the compliance identity information of the originator and the beneficiary. Although this can be any message type, it should be an IVMS101 Identity Payload . transaction a protobuf any that contains information used to identify the associated transaction on the blockchain or to send control flow messages and handling-specific instructions. Use one of the TRISA defined generic transaction data structures. sent_at The RFC-3339 formatted timestamp that the originator sent the first compliance message to the beneficiary. This timestamp is part of the compliance payload for non-repudiation purposes. received_at The RFC-3339 formatted timestamp when the beneficiary accepted the compliance message and returned the completed payload to the originator. This timestamp is part of the compliance payload for non-repudiation purposes.",
"description": "Working with Secure Envelopes and cryptography in the TRISA protocol.",
"tags": [],
"title": "Secure Envelopes",
"uri": "/data/envelopes/index.html"
},
{
"breadcrumb": "TRISA Developer Documentation \u003e Joining TRISA",
"content": "Before you can integrate the TRISA protocol into your VASP software, you must register with the TRISA Global Directory Service (GDS).\nThe TRISA Global Directory Service (GDS) provides public key and TRISA remote peer connection information for registered VASPs. For more detailed information about the directory, see the documentation on the GDS.\nOnce you have registered and been verified, you will receive Identity Certificates. The public key in these certificates will be made available to other VASPs via the GDS.\nWhen registering with the GDS, you will need to provide the address:port endpoint where your VASP implements the TRISA Network service. This address will be registered with the GDS and utilized by other VASPs when your VASP is identified as the beneficiary VASP.\nFor integration purposes, when you register with the GDS, you can opt for either MainNet or TestNet Certificates, or both. The TestNet instance is designed for testing, and the registration process is streamlined in the TestNet to facilitate quick integration. The MainNet is design for production Travel Rule implementations. It is recommended to register for both MainNet and TestNet, specifying different endpoints to reduce confusion for your VASP counterparties.\nDirectory Service Registration To start your registration, visit https://vaspdirectory.net/. You will first need to create an account, and then log in using that account to start the registration process. Note that you can use this website to enter your registration details on a field-by-field basis, or to upload a JSON document containing your registration details.\nOne of the key pieces of information you’ll need is your TRIXO Form. Below is an excerpt of some of the key fields in the TRIXO form, which provides information about transaction thresholds, currency types, and applicable regulators. Frequently, several people at an organization (e.g. legal, technical, administrative points-of-contact) need to collaborate to complete the needed information. To see the TRIXO form in full, see the TRIXO documentation.\n\"trixo\": { \"primary_national_jurisdiction\": \"USA\", \"primary_regulator\": \"FinCEN\", \"other_jurisdictions\": [], \"financial_transfers_permitted\": \"no\", \"has_required_regulatory_program\": \"yes\", \"conducts_customer_kyc\": true, \"kyc_threshold\": \"1.00\", \"kyc_threshold_currency\": \"USD\", \"must_comply_travel_rule\": true, \"applicable_regulations\": [ \"FATF Recommendation 16\" ], \"compliance_threshold\": \"3000.00\", \"compliance_threshold_currency\": \"USD\", \"must_safeguard_pii\": true, \"safeguards_pii\": true } The final step of registration will be a pkcs12 password, which you must keep to decrypt the Identity Certificates that will be sent via email.\nThis registration will result in an email being sent to all the technical contacts specified through the webform or in the JSON file. The emails will guide you through the remainder of the registration process. Once you’ve completed the registration steps, TRISA administrators will receive your registration for review.\nOnce the administrators have reviewed and approved the registration, you will receive pkcs12 password-protected, compressed Identity Certificate via email and your VASP will be publicly visible in the GDS.\nCertificate Issuance There are currently two mechanisms to receive mTLS certificates from the GDS when your registration has been reviewed and approved.\nEmailed PKCS12 Encrypted Certificates Certificate Signing Request (CSR) You must select one of these options when you submit your registration; after your registration is submitted you will not be able to switch between options.\nPKCS12 Encrypted Email Attachment The first mechanism is the easiest — simply select the email option during registration and omit the CSR fields. If the registration form is valid, the GDS will return a PKCS12 password. Do not lose this password, it is the only time it is made available during the certificate issuance process.\nUpon review approval, the GDS CA will generate a complete certificate including private keys and encrypt it using the PKCS12 password. After registering the public keys in the directory service, the GDS will then email the encrypted certificate as a ZIP file to the technical contact, or first available contact on the registration form.\nAfter unzipping the email attachment, you should find a file named \u003ccommon_name\u003e.p12; you can decrypt this file to extract the certificates as follows:\n$ openssl pkcs12 -in \u003ccommon_name\u003e.p12 -out \u003ccommon_name\u003e.pem -nodes You can also directly use the .zip file without decrypting or extracting it via the github.com/trisacrypto/trisa/pkg/trust module.\nCertificate Signing Requests An alternative to certificate creation is to upload a certificate signing request (CSR). This mechanism is often preferable because it means that no private key material has to be transmitted accross the network and the private key can remain on secure hardware.\nTo generate a CSR using openssl on the command line, first create a configuration file named trisa.conf in your current working directory, replacing example.com with the domain you plan to host your TRISA endpoint on:\n[req] distinguished_name = dn_req req_extensions = v3ext_req prompt = no default_bits = 4096 [dn_req] CN = example.com O = [Organization] L = [City] ST = [State or Province (fully spelled out, no abbreviations)] C = [2 digit country code] [v3ext_req] basicConstraints = CA:FALSE keyUsage = digitalSignature, keyEncipherment, nonRepudiation extendedKeyUsage = clientAuth, serverAuth subjectAltName = @alt_names [alt_names] DNS.1 = example.com Please carefully fill out the configuration for your certificate, this information must be correct and cannot be changed without reissuing the certificate. Also make sure that there are no spaces after the entries in the configuration!\nThen run the following command, replacing example.com with the domain name you will be using as your TRISA endpoint:\n$ openssl req -new -newkey rsa:4096 -nodes -sha384 -config trisa.conf \\ -keyout example.com.key -out example.com.csr Your private key is now stored in example.com.key — keep this private key safe — it is required for mTLS connections in your mTLS service and establishes trust on the TRISA network.\nThe example.com.csr file contains your certificate signing request. Copy and paste the contents of this file including the -----BEGIN CERTIFICATE REQUEST----- and -----END CERTIFICATE REQUEST----- into your registration request.",
"description": "Registering a VASP with the Directory Service",
"tags": [],
"title": "Registration",
"uri": "/joining-trisa/registration/index.html"
},
{
"breadcrumb": "TRISA Developer Documentation \u003e Reference",
"content": "What does the “TRISA” acronym mean? TRISA stands for Travel Rule Information Sharing Architecture.\nWhat is TRISA? TRISA is a peer-to-peer network that enables compliance with the Financial Action Task Force (FATF) and the Financial Crimes Enforcement Network (FinCEN) Travel Rule for transaction identity information.\nTRISA is also a protocol that enables the secure exchange of PII between members.\nRead more about TRISA in the TRISA whitepaper.\nHow does TRISA work? TRISA creates a mechanism for VASPs to exchange Travel Rule data packets by performing remote procedure calls using gRPC via mTLS connection. VASPs format the data as protocol buffers that contain details such as IVMS101 identity and transaction payload data.\nTRISA maintains open source Github repositories available to VASPs as they build, test, and deploy their TRISA node into production.\nWhat is the Global Directory Service? The Global Directory Service (GDS) is a geo-distributed store of VASP endpoint and certificate details. VASPs participating in the TRISA protocol use the GDS to look up the TRISA endpoint of their intended counterparty.\nInstructions for working with the Global Directory Service can be found in the documentation of the GDS.\nHow is TRISA decentralized? TRISA is a peer-to-peer network. The TRISA protocol enables VASPs to communicate directly with each other and not through a centralized hub. Peers in the TRISA network are responsible for coordinating their own information exchanges using the TRISA protocol and the Global Directory Service.\nTRISA centralizes a small component of the protocol by acting as a certificate authority. This allows VASPs to establish trust with verified counterparties and understand their compliance requirements.\nHow does TRISA safeguard PII? TRISA safeguards Personally Identifiable Information (PII) in flight and at rest.\nIn flight, secure envelopes are exchanged over an mTLS encrypted channel created using the identity certificates issued by the TRISA network. TRISA members can use each other’s public key addresses to open a secure line of communication to transmit users’ PII.\nTRISA uses a trusted Certified Authority (CA) model, and only verified VASPs are granted certificates from the CA. Certificate authorities offer a root of trust to anchor identities to a chain of trusted entities. The CA model safeguards against a single point of failure, provides protection from attacks, and is scalable to accommodate the growing crypto landscape.\nUsing the TRISA protocol, VASPs exchange secure envelopes formatted as protocol buffer messages. These messages use a combination of asymmetric (public/private key cryptography using TRISA issued or peer-to-peer exchanged signing keys) and symmetric cryptography so that the VASPs can securely store the envelope at rest in a backend of their choice while maintaining full repudiation of the exchange.\nWho’s in TRISA? TRISA is open to organizations that offer virtual asset or digital asset services. Organizations must have a legitimate business purpose to join TRISA. Member organizations may be:\nVirtual Asset Service Providers (VASPs) Crypto Asset Service Providers (CASPs) Money Service Businesses (MSBs) Traditional financial services institutions Regulatory bodies For more information about joining TRISA, please review TRISA’s VASP Verification Process.\nHow can I look up TRISA members? If you are a member, you can look up TRISA members using the Members Endpoint.\nIf you know a VASP’s TRISA Endpoint or Common Name, you can look it up in TRISA’s Global Directory via https://vaspdirectory.net.\nWhy does my common name have to match my endpoint? The Common Name typically matches the Endpoint (e.g. trisa.myvasp.com:443), without the port number at the end (e.g. trisa.myvasp.com) and is used to identify the subject in the X.509 certificate.\nWhat are secure envelopes? Secure Envelopes wrap the identity and blockchain transaction payloads, applying additional encryption and digital signatures for verification.\n.\nThe Secure Envelope documentation discusses its implementation further.\nHow does mTLS work? Mutual Transport Layer Security (mTLS) is a mechanism for mutual authentication between services or servers. Also known as two-way authentication, it ensures that the parties at each end of a connection are who they claim to be.\nWhat is IVMS 101? The interVASP Messaging Standard (IVMS 101) is an internationally recognized standard that helps with language encodings, numeric identification systems, phonetic name pronunciations, and standardized country codes (ISO 3166).\nTRISA uses the interVASP Messaging Standard (IVMS101) standard to describe Originators and Beneficiaries in terms of Natural Persons (human users) and Legal Persons ( organizations or legal entities), as well as necessary information about parties such as geographic addresses.\nDepending on your business details, specific fields may be required. For more information on IVMS 101, please see the documentation at intervasp.org.\nThere is an IVMS 101 Validator which can be used to double check the formatting of an IVMS101 message to ensure it is correct.\nFor help marshaling and unmarshaling IVMS101 identity payloads, see the documentation about the ivms101 package in trisa.\nHow do I figure out where to connect to the counterparty? How do I get counterparty IVMS 101 info? As part of the protocol, the Originator can use the Global Directory Service to lookup the counterpoint endpoint, and sends a secure envelope providing their IVMS101 details. The Beneficiary can then verify and store the counterparty PII information needed for compliance. Next the Beneficiary can return a new secure envelope with their IVMS101 details so that the Originator can store the information for compliance.\nWhy gRPC? The gRPC library is an open-source Remote Procedure Call (RPC) framework that can run in any environment and can establish a secure communication.\ngRPC includes a bidirectional streaming mode that allows long running connections with high throughput messaging between nodes. This mode is optional in TRISA but can be used to support batch messaging and increase the performance of TRISA messaging.\nThe use of gRPC also facilitates convenient encryption at rest to ensure that PII is safeguarded.\nWhat’s the difference between TestNet and MainNet? The TestNet is a sandbox environment that allows VASPs to test securely sharing the cryptocurrency transaction details required to meet the FATF Travel Rule requirements. The TestNet includes “robot” VASPs that give users the ability to interact with the TestNet by simulating transactions to see how secure transactions are conducted. Once a VASP completes testing, the VASP can switch to MainNet, where live transactions take place.\nIt’s important to note that the reason that there are two networks is because those networks are issued from different intermediate certificate authorities. A VASP that has been issued a TestNet certificate cannot connect to a node that is running on MainNet and vice versa. In other words, the MainNet certificate authority will not recognize TestNet certificates. When you submit a request for TRISA certificates, you may simultaneously request certificates for TestNet and MainNet.",
"description": "Frequently asked questions",
"tags": [],
"title": "FAQ",
"uri": "/reference/faq/index.html"
},
{
"breadcrumb": "TRISA Developer Documentation \u003e Joining TRISA",
"content": "The purpose of the TRIXO questionnaire is to provide responses to a common set of questions VASPs might ask each other before exchanging Travel Rule information.\nWhen registering for TRISA membership, applicants must submit their TRIXO questionnaire in JSON form (shown below) as part of their application. After a VASP has been issued certificates, these TRIXO details are logged in the TRISA Global Directory Service to facilitate member lookups and mutual verification ahead of information exchanges.\nJSON Formatting Below is a sample TRIXO form, containing all of the fields required during registration for the TRISA network.\n{ \"entity\": { \"name\": { \"name_identifiers\": [{ \"legal_person_name\": \"AliceCoin, Inc.\", \"legal_person_name_identifier_type\": 0 }, { \"legal_person_name\": \"Alice VASP\", \"legal_person_name_identifier_type\": 2 }, { \"legal_person_name\": \"Alice\", \"legal_person_name_identifier_type\": 1 } ], \"local_name_identifiers\": [], \"phonetic_name_identifiers\": [] }, \"geographic_addresses\": [{ \"address_type\": 1, \"address_line\": [ \"23 Roosevelt Place\", \"\", \"Boston, MA 02151\" ], \"country\": \"USA\" }], \"customer_number\": \"\", \"national_identification\": { \"national_identifier\": \"5493004YBI24IF4TIP92\", \"national_identifier_type\": 8, \"country_of_issue\": \"USA\", \"registration_authority\": \"RA000744\" }, \"country_of_registration\": \"USA\" }, \"contacts\": { \"technical\": { \"name\": \"Horace Tisdale\", \"email\": \"[email protected]\", \"phone\": \"+1-123-555-5555\" }, \"legal\": { \"name\": \"Mickey Deville\", \"email\": \"[email protected]\", \"phone\": \"+1-123-555-5553\" }, \"administrative\": { \"name\": \"Jenelle Frida\", \"email\": \"[email protected]\", \"phone\": \"+1-310-123-5555\" }, \"billing\": { \"name\": \"Godfried Moneybags\", \"email\": \"[email protected]\", \"phone\": \"+1-555-555-5555\" } }, \"trisa_endpoint\": \"api.alice.vaspbot.net:443\", \"common_name\": \"api.alice.vaspbot.net\", \"website\": \"https://alice.vaspbot.net/\", \"business_category\": 3, \"vasp_categories\": [ \"Exchange\", \"Individual\", \"Other\" ], \"established_on\": \"2021-01-21\", \"trixo\": { \"primary_national_jurisdiction\": \"USA\", \"primary_regulator\": \"FinCEN\", \"other_jurisdictions\": [], \"financial_transfers_permitted\": \"no\", \"has_required_regulatory_program\": \"yes\", \"conducts_customer_kyc\": true, \"kyc_threshold\": \"1.00\", \"kyc_threshold_currency\": \"USD\", \"must_comply_travel_rule\": true, \"applicable_regulations\": [ \"FATF Recommendation 16\" ], \"compliance_threshold\": \"3000.00\", \"compliance_threshold_currency\": \"USD\", \"must_safeguard_pii\": true, \"safeguards_pii\": true } } Table View The JSON format above is adapted from the table-based questionnaire that appears in the TRISA whitepaper shown below, which was derived from the draft “Wolfsberg-style Questionnaire for VASPs”.\nVASP TRAVEL RULE INFORMATION EXCHANGE (TRIXO) QUESTIONNAIRE No # Question SECTION 1. ENTITY DETAILS 1a. Full Legal Name 1b. Doing Business As (DBA) name 1c. Full Legal (Registered) Address 1d. Full Primary Business Address (if different from Registered Address above) 1e. Date of Entity Incorporation / Establishment 1f. Incorporation Number 1g. Entity Identifier (e.g. Legal Entity Identifier, Employer Indentification Number), if available SECTION 2. REGULATOR \u0026 LICENSING 2a. Name of the Entity’s primary financial regulator / supervisory authority 2b. Please provide a list of national jurisdictions, other than your primary national jurisdiction, where you have been granted licenses or other approvals or have registered as required to operate, and the name of the regulator / supervisory authority 2c. Entity’s License / Registration Number(s) for each jurisdiction it operates in 2d. Is the Entity permitted to send and/or receive transfers of virtual assets in the jurisdictions in which it operates? SECTION 3. CDD \u0026 TRAVEL RULE POLICIES 3a. Does the Entity have a programme that sets minimum AML, CFT, KYC / CDD and Sanctions standards per the requirements of the jurisdiction(s) regulatory regimes where it is licensed/approved/registered? 3b. Does the Entity conduct KYC / CDD before permitting its customers to send/receive virtual asset transfers? 3c. If Yes, at what threshold does the Entity conduct KYC before permitting the customer to send/receive virtual asset transfers? 3d. Is the Entity required to comply with the application of the Travel Rule standards (FATF Recommendation 16) in the jurisdiction(s) where it is licensed / approved / registered? 3e. If Yes, please specify the applicable regulation(s) 3f. What is the minimum threshold above which the entity is required to collect/send Travel Rule information? SECTION 4. DATA PROTECTION 4a. Is the Entity required by law to safeguard PII? 4b. Does the Entity secure and protect PII, including PII received from other VASPs under the Travel Rule? SECTION 5. TRAVEL RULE IMPLEMENTATION 5a. Which technical solution(s) does the Entity support for sharing Travel Rule information? 5b. Please provide the technical details (IDs, endpoints, URLs, etc.) required to send Travel Rule information to the Entity for each solution the Entity supports. 5c. Name, email and phone number of travel rule contact",
"description": "Shows full TRIXO forms in JSON \u0026 Spreadsheet format",
"tags": [],
"title": "TRIXO Form",
"uri": "/joining-trisa/trixo/index.html"
},
{
"breadcrumb": "TRISA Developer Documentation",
"content": "The TRISA organization hosts the TRISA Global Directory Service (GDS) on behalf of the TRISA network. The TRISA protocol specifies interactions with GDS. GDS facilitates peer-to-peer exchanges between TRISA members as follows:\nBy issuing mTLS certificates to verify exchanges By providing discovery services for finding TRISA endpoints By providing certificate and KYCV (Know Your Counterparty VASP) information for verification It is important to note that TRISA is a peer-to-peer network with no centralized authority for collecting or exchanging Travel Rule data.\nGDS serves as a Certificate Authority for TRISA exchanges. After VASPs submit required information and are verified, GDS issues them Identity Certificates which VASPs can use to establish mTLS connections with counterparties, thereby securing communications that contain private Originator and Beneficiary data. These certificates are issued after extended validation and prove that the VASP is a trusted member of the TRISA network. In this way, GDS does not control the exchange; rather it helps to confirm the identities of parties involved in Travel Rule information exchanges.\nGDS also serves as a decentralized store of member information, including member node (aka endpoint) addresses, TRIXO form details, and public keys. TRISA members can access the directory listing of other verified members, search, and lookup VASP counterparties. In this way, GDS helps members to make informed compliance decisions before sending or receiving large sums of virtual assets.\nGDS is replicated across multiple continents. The servers hosting GDS are in three regions: US, EU, and Singapore. The servers are decentralized and geo-replicated to ensure that the GDS is consistent, available, and fault-tolerant. TRISA plans to expand to more regions in the future.\nGDS also manages the certificate revocation list (CRL) to maintain the network over time. The directory issues sealing keys and manages revocation and reissuance of certificates.\nThis documentation describes the TRISA implementation of the directory service and TRISA-specific interactions with it. For details about working with the GDS API, visit the API documentation.\nNetworks TRISA currently operates two directory services: a TestNet (trisatest.net) and the MainNet (vaspdirectory.net). The TestNet is intended to facilitate development and integration and should not be used for actual compliance exchanges. The MainNet is separated from the TestNet with a completely different certificate authority, and certificates issued to TestNet nodes cannot be used to connect to MainNet nodes and vice-versa.\nConnect to the GDS and register for certificates with the following endpoints/urls:\nDirectory Network Website gRPC Endpoint trisatest.net TestNet https://trisatest.net api.trisatest.net:443 vaspdirectory.net MainNet https://vaspdirectory.net api.vaspdirectory.net:443 Registered Directories TRISA supports the idea of different directory services that can interoperate by exchanging VASP records with each other. A directory service by definition is a system that has an intermediate certificate authority under one of the TRISA root authority networks (e.g. TestNet or MainNet) and can issue leaf certificates via the intermediate authority. Directory services exchange records with each other to facilitate lookups.\nCurrently the only registered directories are the TRISA hosted directory services.",
"description": "The Global TRISA Directory Service (GDS)",
"tags": [],
"title": "Global Directory Service",
"uri": "/gds/index.html"
},
{
"breadcrumb": "TRISA Developer Documentation \u003e Global Directory Service \u003e Administration \u003e Configuration",
"content": "The GDS user interfaces that power our user and administrative web applications are built and deployed using React and webpack. Because webpack compiles the app into a bundle of HTML, JavaScript, and CSS – any configuration must be available at build time (e.g. when containers are compiled). This makes configuring our React apps and user interfaces slightly more complicated.\nRight now, we use a continuous integration and deployment service to build our containers (e.g. GitHub Actions). During the container build process, environment variables are injected into the container via build args, which are in turn processed by the node build script. All environment variables and build args must be prefixed by REACT_APP_.\nNote that front-end applications should not have any secret configurations. There are, however, sensitive configurations (such as Google Analytics tags, Sentry DSNs, etc.). Any sensitive configurations should be stored securely (e.g. using GitHub Secrets).\nGDS User UI The build arguments for the GDS User Interface (vaspdirectory.net) are as follows:\nEnvVar Type Default Description REACT_APP_TRISA_BASE_URL string The base URL of the BFF API endpoint, e.g. https://bff.vaspdirectory.net/v1/. REACT_APP_VERSION_NUMBER string The semvar build version of the app (usually parsed from the git tag). REACT_APP_GIT_REVISION string The seven-digit prefix of the git hash of the commit being built. REACT_APP_ANALYTICS_ID string The Google Analytics tag (e.g. G-XXXXXXXXXX). REACT_APP_SENTRY_DSN string The DSN for configuring React to send errors to Sentry. REACT_APP_SENTRY_ENVIRONMENT string $NODE_ENV The environment for Sentry logging (not required except for staging or development). The GDS User Interface uses Auth0 for authentication. Front-end Auth0 configuration is as follows:\nEnvVar Type Default Description REACT_APP_AUTH0_DOMAIN string The domain (or custom domain) to connect to Auth0 on (e.g. auth.vaspdirectory.net). REACT_APP_AUTH0_CLIENT_ID string The ClientID of the Auth0 app as configured in the Auth0 dashboard. REACT_APP_AUTH0_REDIRECT_URI string The callback URI for the application to receive Auth0 redirects after authentication. REACT_APP_AUTH0_SCOPE string The required Auth0 scope (usually ‘openid profile email’) REACT_APP_AUTH0_AUDIENCE string The audience of the tokens, usually the ID of the API (e.g. https://bff.vaspdirectory.net) GDS Admin UI The build arguments for the GDS Admin UI (admin.vaspdirectory.net and admin.trisatest.net) are as follows:\nEnvVar Type Default Description REACT_APP_GDS_API_ENDPOINT string The base URL of the Admin API endpoint, e.g. https://api.admin.vaspdirectory.net/v2. REACT_APP_GDS_IS_TESTNET bool false True if the Admin UI is managing the TestNet, false if MainNet. REACT_APP_VERSION_NUMBER string The semvar build version of the app (usually parsed from the git tag). REACT_APP_GOOGLE_CLIENT_ID string The Google Client ID for Google OAuth2 authentication. REACT_APP_GIT_REVISION string The seven-digit prefix of the git hash of the commit being built. REACT_APP_ANALYTICS_ID string The Google Analytics tag (e.g. G-XXXXXXXXXX). REACT_APP_SENTRY_DSN string The DSN for configuring React to send errors to Sentry. REACT_APP_SENTRY_ENVIRONMENT string $NODE_ENV The environment for Sentry logging (not required except for staging or development).",
"description": "Configuring the React Apps",
"tags": [],
"title": "User Interfaces",
"uri": "/gds/admin/configuration/ui/index.html"
},
{
"breadcrumb": "TRISA Developer Documentation \u003e Working with TRISA Data",
"content": "A Payload contains information to be securely exchanged for Travel Rule compliance, including (1) identity details, (2) transaction information for both counterparties to uniquely identify the transaction on the chain, and (3) timestamps for use in regulatory non-repudiation. The payload is serialized and encrypted to be sent in a SecureEnvelope. Payloads are digitally signed to ensure that they have not been tampered with in transmission.\nThe formal definition of a Payload is described on this page and available in the form of protocol buffers in the trisa code repository.\nAs shown below, the internal message types of the Payload are purposefully generic to allow flexibility with the data needs for different exchanges:\nmessage Payload { google.protobuf.Any identity = 1; google.protobuf.Any transaction = 2; string sent_at = 3; string received_at = 4; } Identity Payload The identity field in a TRISA Payload is a protobuf message intended to contain compliance identity information of the Originator and the Beneficiary. It is defined as an any; this means that technically, it can be any message type. However, to encourage maximum compatibility between yourself and fellow TRISA members, we strongly recommend the use of IVMS101.\nFor help marshaling and unmarshaling IVMS101 identity payloads, see the documentation about the ivms101 package in trisa.\nYou can use the online IVMS101 Validator produced by 21 Analytics to ensure your message is properly structured IVMS101.\nExamples of identity payloads, described both as protocol buffer messages and as JSON, are available in the trisa reference implementation.\nTransaction Payloads The transaction field in a TRISA Payload is a protobuf message intended to contain information to identify the associated transaction on the blockchain. It may also be used to send control flow messages and handling-specific instructions. As with the identity payload, a transaction is defined as an any; meaning that technically, it can be any message type.\nTo ensure compatibility with fellow TRISA members and convenient message parsing, use one of the TRISA defined generic transaction data structures described below:\nA Transaction Message A Transaction is a generic message for TRISA transaction payloads. The goal of this payload is to provide enough information to link Travel Rule compliance information in the identity payload with a transaction on the blockchain or network.\nmessage Transaction { string txid = 1; // Transaction ID or hash unique to chain // Used to notify beneficiary VASP of the transaction // sent by the originating VASP. string originator = 2; // Crypto address of originator string beneficiary = 3; // Crypto address of beneficiary double amount = 4; // Amount of transaction string network = 5; // Chain of transaction/network ticker (e.g.: ETH, BTC) string timestamp = 6; // Transaction timestamp (RFC 3339) string extra_json = 7; // Extra data (JSON-formatted) string asset_type = 8; // Token ticker, for identifying the token on chain. // For native tokens, set to the same as network ticker // (e.g.: ETH, BTC, USDT, etc) string tag = 9; // Optional address memo/destination-tag } Below are some examples of how the Transaction message might be used in the context of different types of transactions and chains.\nBlockchain without smart contract (e.g.: BTC)\n{ \"txid\": \"05d9dc3fcbf48771c8ee9e95200877ef08e2766a780d4e44eee397633eb164d0\", \"originator\": \"14HmBSwec8XrcWge9Zi1ZngNia64u3Wd2v\", \"beneficiary\": \"14WU745djqecaJ1gmtWQGeMCFim1W5MNp3\", \"amount\": 0.00206412, \"network\": \"BTC\", \"timestamp\": \"2022-01-30T16:14:00Z\", \"extra_json\": \"{\\\"value_when_transacted\\\": \\\"USD $77.86\\\"}\", \"asset_type\": \"BTC\", \"tag\": \"\" } Blockchain supporting a smart contract (e.g.: ETH)\nNative token\n{ \"txid\": \"0x3e23a5165fd5c1c0f95cfc85c1419959a21e3a1a057040328fe9d3ffd7f2f991\", \"originator\": \"0x829bd824b016326a401d083b33d092293333a830\", \"beneficiary\": \"0x3d9d22647690d9b2b4d95ed6e527628746153323\", \"amount\": 0.2008, \"network\": \"ETH\", \"timestamp\": \"2022-06-30T03:16:58Z\", \"extra_json\": \"{\\\"value_when_transacted\\\": \\\"USD $218.872\\\"}\", \"asset_type\": \"ETH\", \"tag\": \"\" } Custom token (e.g.: ERC20)\n{ \"txid\": \"0x6286b5688bcc789c2d681c01beb3e49ac870de15461cb5a90d14b8a161e84236\", \"originator\": \"0xea0b5f97c3843175ee67ddb237e294a9144c0a68\", \"beneficiary\": \"0xdAC17F958D2ee523a2206206994597C13D831ec7\", \"amount\": 255, \"network\": \"ETH\", \"timestamp\": \"2022-06-30T03:38:34Z\", \"extra_json\": \"{\\\"value_when_transacted\\\": \\\"USD $255\\\"}\", \"asset_type\": \"USDT\", \"tag\": \"\" } Blockchain supporting destination tags (e.g.: XRP)\n{ \"txid\": \"BFD895E1D93FB6E25A3BE38A2E62B6D88753F502B4C6E55F297981538538A2F2\", \"originator\": \"rKKB4S7jysrevAd1BBqbAwE7mitXY59Zsc\", \"beneficiary\": \"rEb8TK3gBgk5auZkwc6sHnwrGVJH8DuaLh\", \"amount\": 100, \"network\": \"XRP\", \"timestamp\": \"2022-01-29T16:14:00Z\", \"extra_json\": \"{\\\"value_when_transacted\\\": \\\"USD $32.53\\\"}\", \"asset_type\": \"XRP\", \"tag\": \"311041419\" } An example Transaction message can be found in the trisa reference implementation.\nA Pending Message A Pending message is a control flow message to support asynchronous TRISA transfers. Pending messages can be returned as an intermediate response during a compliance transfer if further processing is required before a response can be sent. The Pending message should provide information to the originator about when they can expect a response via the reply_not_before and reply_not_after timestamps. The Pending message should also provide collation information such as the envelope_id and original transaction so that the response message can be matched to the original request.\nmessage Pending { string envelope_id = 1; // TRISA envelope ID string received_by = 2; // recipient or recipient VASP name string received_at = 3; // when request was received (RFC3339) string message = 4; // optional message for counterparty string reply_not_after = 5; // when response will be returned (RFC3339) string reply_not_before = 6; // response will not be sent before (RFC3339) string extra_json = 7; // extra data (JSON-formatted) Transaction transaction = 15; // original transaction for reference } An example Pending message can be found in the trisa reference implementation.\nTimestamps The sent_at and received_at timestamps are RFC-3339 formatted timestamps intended for use in regulatory non-repudiation.\nThe sent_at timestamp marks the time the Originator sent the first compliance message to the Beneficiary.\nThe received_at timestamp when the Beneficiary accepted the compliance message and returned the completed payload to the Originator.",
"description": "Preparing and formatting data for payloads.",
"tags": [],
"title": "Data Payloads",
"uri": "/data/payloads/index.html"
},
{
"breadcrumb": "TRISA Developer Documentation \u003e Reference",
"content": "General Terminology Originator: The initiator of a blockchain transaction and therefore also the initiator of a TRISA transfer. The “originator” can refer to the originating VASP, the originating customer of the VASP or both.\nBeneficiary: The recipient of a blockchain transaction and therefore also the recipient of a TRISA transfer. The “beneficiary” can refer to the beneficiary VASP, the beneficiary customer of the VASP or both.\nNatural Person: A “Natural Person” is a human user. Originating and beneficiary customers are considered Natural Persons in accordance with the IVMS101 specification.\nLegal Person: A “Legal Person” is an organization or legal entity. Originating and beneficiary VASPs are considered Legal Persons in accordance with the IVMS101 specification.\nLocal vs Remote VASP: A reference to the source of peer-to-peer traffic in an information exchange. The “local VASP” usually refers to the service you are running, while the “remote VASP” usually refers to some other VASP in the TRISA network. Local vs. Remote is often used interchangeably with originator vs. beneficiary. If you are initiating the transaction then the local VASP is the originator and the remote VASP is the beneficiary. If you are receiving a transaction then the local VASP is the beneficiary and the remote VASP is the originator.\nTravel Rule: Record-keeping rules for transfers between financial institutions that allow law enforcement agencies to prevent illicit finance (e.g. money laundering or the financing of terrorism).\nVASP: Virtual Asset Service Provider. A legal entity (usually a business) that manages and transfers virtual assets and are required by the Travel Rule to conduct information exchanges. Compliance exchanges in the TRISA network are between VASPs.\nKYC: Know Your Customer (or “KYC”) is a due diligence practice used by VASPs to verify the identities and potential risks of their clients, users, and other counterparties. KYC procedures are intended to help banks and other financial institutions combat money laundering and other financial crimes.\nAML: Anti-Money Laundering (or “AML”) refers to laws and regulations intended to stop criminals from disguising illegally obtained funds as legitimate income.\nCryptographic Terminology mTLS: Mutual Transport Layer Security is an encryption protocol that authenticates both the client and the server in a network connection and encrypts communications between the parties so that data cannot be read in flight. mTLS is an extention of TLS (formerly SSL) that requires both sides of a network connection to have a certificate that establishes their identity and which can be used to encrypt packets sent on the channel.\nSymmetric Cryptography: Both encryption and decryption of data are performed using a single secret key that must be shared by the sender and the recipient. Shared secrets introduce the problem of how to share the secret key, however symmetric cryptographic algorithms are usually faster and better for bulk encryption of larger amounts of data. Generally, secrets are shared by asymmetric-key encryption and data encrypted using symmetric encryption.\nSecret Key Cryptography: See symmetric cryptography.\nPublic Key Cryptography: A cryptographic method that uses a pair of related keys. Each pair consists of a public key, which can be shared with others, and a private key, which must not be shared with anyone but the owner. In practice, data can be encrypted with a public key but only decrypted with the private key.\nAsymmetric Cryptography: See public key cryptography.\nDigital Signature: A mathematical method that produces a signature of data, e.g. some other piece of data that summarizes or describes the original data, usually via a hashing method. If the original data changes, its digital signature will change, therefore digital signatures are generally used as proof that the original data has not been tampered with, particularly if the signature has been generated cryptographically. For example, if a certificate has a signature that is signed with the private key of the certificate authority, anyone with the CA’s public key can verify the signature of the certificate, ensuring it was the certificate produced by the CA.\nHMAC: Hash Message Authentication Code. A secure method of producing a digital signature for data that uses a cryptographic hash function and a secret key. HMACs are used to verify that data has not been modified or changed, see also digital signature.\nCertificate: Usually a reference to an X.509 certificate, a standard format for public key infrastructure. An X.509 certificate is a digital document that securely associates cryptographic key pairs with identities. Certificates are signed by a certificate authority to guarantee their provenance and contain subject information and other metadata concerning , the keypair, and its usage. Generally a reference to a certificate refers to the public key – the part of the certificate that is shared for authentication purposes. However when certificates are issued, they are issued as a public/private key pair.\nIdentity Certificate: a TRISA specific term that refers to the certificate issued by the TRISA CA to a VASP entity that they should use to connect to other VASPs in the TRISA network via mTLS.\nSealing Certificate (or keys): a TRISA specific term that refers to a key pair that is used to seal secure envelopes in the TRISA protocol. Sealing keys may be certificates issued by the TRISA CA, or they may be keys generated by the VASP and exchanged during the TRISA protocol.\nCertificate Authority: an entity that issues and revokes certificates and whose public keys are used to establish trust in the identities its issued certificates provide. Certificate authorities usually control cryptographic hardware and the “root of trust” – a digital key pair that is used to generate and sign intermediate and leaf certificates for public key infrastructure.",
"description": "TRISA Glossary and Terminology",
"tags": [],
"title": "Glossary",
"uri": "/reference/glossary/index.html"
},
{
"breadcrumb": "TRISA Developer Documentation",
"content": "The TRISA TestNet has been established to provide a demonstration of the TRISA peer-to-peer protocol, host “robot VASP” services to facilitate TRISA integration, and facilitate public key exchange and peer discovery via TRISA’s Global Directory Service (GDS). The TestNet instance is designed for testing, and the registration process is streamlined in the TestNet to facilitate quick integration. The Testnet enables you to test and validate transactions that share sensitive information safely and securely.\nFor reference, the TRISA Protocol documentation provides additional information on enabling the peer-to-peer exchange of compliance information.\nThe TRISA TestNet is comprised of several services, including:\nA TestNet Certificate Authority that issues TestNet Identity Certificates (note that these are distinct from MainNet certificates and not interchangeable). TRISA Directory Service - a user interface to explore the TRISA Global Directory Service and register to become a TRISA member TestNet Demo - a demo site to show TRISA interactions between “robot” VASPs that run in the TestNet The TestNet also hosts three “robot VASPs” (rVASPs) that have been implemented as a convenience for TRISA members to integrate their TRISA services and validate the compliance solution safely. The primary rVASP is Alice, a secondary for demo purposes is Bob, and an “evil” rVASP to test interactions with non-verified TRISA members.\nThe TestNet also provides a command line utility for interacting with the API for administrative and debugging purposes, using the testnet certificates.\nJoining the TestNet The following steps are required to join the TestNet:\nRegister with the GDS to create your TRISA Account with your VASP email address, where you can opt-in for TestNet Certificates. During registration, you can add collaborators within your organization.\nComplete the VASP Verification form and due diligence process. Once approved, you will gain access to the TestNet.\nSet up your TRISA node and implement the TRISA API.",
"description": "Describing the Integration and Development with TestNet",
"tags": [],
"title": "Testing and Deployment",
"uri": "/testing/index.html"
},
{
"breadcrumb": "TRISA Developer Documentation \u003e Global Directory Service \u003e Administration \u003e Configuration",
"content": "TrtlDb is a globally replicated key-value store that uses anti-entropy for eventually consistent replication that minimizes egress costs, maximizes availability, and is partition tolerant. It exposes unary and streaming APIs for data access and is secured via mTLS connections. Its environment variables are prefixed with the TRTL_ tag. The primary configuration is as follows:\nEnvVar Type Default Description TRTL_MAINTENANCE bool false Sets the server to maintenance mode, which will respond to requests with Unavailable except for status requests. TRTL_BIND_ADDR string :4436 The IP address and port to bind the trtl grpc server to. TRTL_METRICS_ADDR string :7777 The IP address and port to bind the prometheus metrics http server to. TRTL_METRICS_ENABLED bool true If false, disables the prometheus metrics http server. TRTL_LOG_LEVEL string info The verbosity of logging, one of trace, debug, info, warn, error, fatal, or panic. TRTL_CONSOLE_LOG bool false If true, will print human readable logs instead of JSON logs for machine consumption. Database Internally, trtl uses a log-structured merge tree embedded database such as LevelDB to store its pages on disk. This embedded database is configured as follows:\nEnvVar Type Default Description TRTL_DATABASE_URL string Required, the DSN to connect to the database on (see below for details). TRTL_DATABASE_REINDEX_ON_BOOT bool false When the server starts, instead of loading indexes from disk, recreate and save them. The TRTL_DATABASE_URL is a standard DSN with a scheme, host, path, and query parameters. Trtl should always have access to a locally embedded database such as LevelDB. When connecting to a LevelDB, the path to the directory on disk where the leveldb should be stored must be passed to the DSN. To specify a relative path, use three slashes: leveldb:///relpath/to/db, to specify an absolute path use four: leveldb:////abspath/to/db.\nReplica Config TrtlDB is a globally replicated database and the replica config provides metadata about the TrtlDB instance for replication purposes while also setting parameters for replication. Replication is configured as follows:\nEnvVar Type Default Description TRTL_REPLICA_ENABLED bool true If false, disables replication so that the trtldb acts as a single node. TRTL_REPLICA_PID uint64 The precedence ID of the node (must be unique in the system) - lower IDs have precedence in consistency tie breakers. TRTL_REPLICA_REGION string The region that the replica is assigned to for provenance and geographic compliance. TRTL_REPLICA_NAME string A unique name that identifies the replica name across peers. TRTL_REPLICA_GOSSIP_INTERVAL duration 1m The mean interval between gossip (synchronization) sessions between trtl peers. TRTL_REPLICA_GOSSIP_SIGMA duration 5s The standard deviation of the jittered interval between gossip sessions. If TRTL_REPLICA_ENABLED is true then TRTL_REPLICA_PID, TRTL_REPLICA_REGION, and TRTL_REPLICA_NAME are required to identify the unique replica in the system.\nReplication occurs with bilateral anti-entropy, meaning that after a jittered interval, each replica randomly selects a peer to synchronize with. This is also referred to as a gossip protocol. The TRTL_REPLICA_GOSSIP_INTERVAL and TRTL_REPLICA_GOSSIP_SIGMA describe a normal distribution of randomly selected synchronization intervals, providing jitter so that the network is not bursty.\nReplica Identification Strategy When deployed in a kubernetes cluster, a trtl process running in a container in a pod must identify itself to determine what replica it is so that it can configure itself correctly (particularly if the replica is part of a stateful set). The replica strategy configuration defines how a trtl process bootstraps itself as follows:\nEnvVar Type Default Description TRTL_REPLICA_STRATEGY_HOSTNAME_PID bool false Set to true to use the hostname PID strategy (will be the first strategy tried). TRTL_REPLICA_HOSTNAME string Set the hostname of the process from the environment for the hostname-pid strategy. TRTL_REPLICA_STRATEGY_FILE_PID string Set to the path of a PID file, if not empty uses the file PID strategy (second strategy after hostname-pid). TRTL_REPLICA_STRATEGY_JSON_CONFIG string Set to the path of a JSON configuration file, if not empty uses the JSON config strategy (third strategy after file-pid). The strategies allow the process to identify its PID - either by processing a hostname (e.g. trtl-10) or by reading the pid from a file. The remainder of the replica can then be configured from the JSON file rather than directly from the environment.\nMTLS Config Connections to the TrtlDB are secured and authenticated using mTLS. The mTLS configuration is as follows:\nEnvVar Type Default Description TRTL_INSECURE bool false If true, the server will start without mTLS configured. TRTL_MTLS_CHAIN_PATH string The path to the pool file with valid certificate authorities to authenticate clients for. TRTL_MTLS_CERT_PATH string The path to the certificates with the private key for the trtl server. If TRTL_INSECURE is false then the TRTL_MTLS_CHAIN_PATH and the TRTL_MTLS_CERT_PATH are both required.\nBackups The Backup manager is a background process that clones the embedded database pages into a zipped folder on disk that can be downloaded for backup purposes. Backups run periodically and can be run without interupting database processing since the backup takes a live snapshot of the database. Backups are configured as follows:\nEnvVar Type Default Description TRTL_BACKUP_ENABLED bool false If true, enables the backup background process. TRTL_BACKUP_INTERVAL duration 24h The interval between database backups. TRTL_BACKUP_STORAGE string The path on disk to store database backups (required if enabled). TRTL_BACKUP_KEEP int 1 The number of backups to keep before cleaning up old backups. Sentry TrtlDB uses Sentry to assist with error monitoring and performance tracing. Configure TrtlDB to use Sentry as follows:\nEnvVar Type Default Description TRTL_SENTRY_DSN string The DSN for the Sentry project. If not set then Sentry is considered disabled. TRTL_SENTRY_SERVER_NAME string Optional - a server name to tag Sentry events with. TRTL_SENTRY_ENVIRONMENT string The environment to report (e.g. development, staging, production). Required if Sentry is enabled. TRTL_SENTRY_RELEASE string {{version}} Specify the release version for Sentry tracking. By default this will be the package version. TRTL_SENTRY_TRACK_PERFORMANCE bool false Enable performance tracing to Sentry with the specified sample rate. TRTL_SENTRY_SAMPLE_RATE float64 0.85 The percentage of transactions to trace (0.0 to 1.0). TRTL_SENTRY_REPORT_ERRORS bool false If true sends gRPC errors to Sentry as exceptions (useful for development or staging) TRTL_SENTRY_DEBUG bool false Set Sentry to debug mode for testing. Sentry is considered enabled if a DSN is configured. Performance tracing is only enabled if Sentry is enabled and track performance is set to true. If Sentry is enabled, an environment is required, otherwise the configuration will be invalid.\nNote that the sentry.Config object has a field Repanic that should not be set by the user. This field is used to manage panics in chained interceptors.",
"description": "Configuring the Trtl Database",
"tags": [],
"title": "TrtlDB",
"uri": "/gds/admin/configuration/trtl/index.html"
},
{
"breadcrumb": "TRISA Developer Documentation \u003e Reference",
"content": "TRISA is an open source project and welcomes contributions!\nThe TRISA Protocol implementation is hosted on GitHub at https://github.com/trisacrypto/trisa.\nThe codebase for the Global Directory Service is hosted on GitHub at https://github.com/trisacrypto/directory.\nThe codebase for the TRISA TestNet is hosted on GitHub at https://github.com/trisacrypto/testnet.\nSetting up GitHub for Contributing Set up git signing.\nCreate GPG (GNU Privacy Guard) keys to enable git signing to enable verified commits. Install the GPG command line tools.\nGenerate a GPG key pair, and the GPG key must use RSA with a key size of 4096 bits. (At the prompt, specify the kind of key you want, or press Enter to accept the default RSA and RSA.)\n$ gpg --full-generate-key View your generated key as follows:\n$ gpg --list-secret-keys --keyid-format=long Get your full key as follows:\n$ gpg --armor --export \u003cyour key\u003e Copy your GPG key, which looks like the following:\n-----BEGIN PGP PUBLIC KEY BLOCK----- .................................... -----END PGP PUBLIC KEY BLOCK----- Add the GPG key in Github by accessing Accounts Settings. And in the sidebar, under Access, click SSH and GPG Keys. Then click New GPG key, and paste your copied GPG key here in the Key field.\nAfter your GPG key has been added, copy the Key ID and set up automatic commit signing.\n$ git config --global commit.gpgsign true $ git config --global user.signingkey \u003cKey ID\u003e Clone the target repository locally and create a feature branch to hold changes.\n$ git clone https://github.com/trisacrypto/trisa.git $ cd trisa $ git checkout -b feature-branch-name After making changes and pushing commits to your feature branch in the target remote repository, open a Pull Request (PR) and request a review from a maintainer.\nContributing to the Documentation To contribute to the documentation, you need to install hugo. On a Mac, we recommend using Homebrew as follows:\n$ brew install hugo You can check the version of Hugo as follows:\n$ hugo version Ensure the installed version of Hugo matches the deployed Hugo version, which can be found here.\nAfter making changes to the documentation, review changes by running a local server while in the docs subdirectory. The -D renders content marked as draft.\n$ hugo serve -D Navigate to http://localhost:1313/ to view the rendered website with your changes. The website will be re-rendered every time you make changes by refreshing the page.\nCommon Issues While Contributing Failing to sign commits\nWhile trying to commit changes, you receive this error below:\ngpg failed to sign the data fatal: failed to write commit object Likely Solution: There may have been another gpg key associated with your GitHub account, and the system still recognizes that previous key. Therefore, you may need to stop the gpg-agent by doing the following:\n$ gpgconf --kill gpg-agent Error building site due to new commits with shortcode\nWhile trying to run hugo serve -D after making changes to the TRISA documentation, you receive this error below:\nError: Error building site: \".../trisa/docs/content/...\": failed to extract shortcode: template for shortcode \"shortcode_name\" not found Likely Solution: You may need to register submodules and submodules within. This can be done with the following:\ngit submodule update --init --recursive",
"description": "How to Contribute",
"tags": [],
"title": "How to Contribute",
"uri": "/reference/how-to-contribute/index.html"
},
{
"breadcrumb": "TRISA Developer Documentation",
"content": "The OpenVASP Association implements an open protocol for travel rule called TRP that is similar to TRISA but puts more focus on ease of information sharing and human-in-the-loop review than on verified counterparties and cryptography. TRISA and OpenVASP have worked together over the past several months to create a “bridge” that will allow partial compatibility between the two protocols. This page describes how implementers of TRISA nodes might integrate the bridge in their node to respond to TRP requests.\nFor more information on the TRP protocol, please refer to the TRP Documentation.\nTRP Workflow The TRP workflow uses HTTPS POST requests with JSON payloads to facilitate information exchange. The initial request endpoint is defined with an LNURL or Travel Address endpoint that the beneficiary must request from their VASP and send to the originator. Subsequent request endpoints are defined with callback URLs in the request itself. HTTP error codes and JSON payloads are used to communicate success or failure back to the counterparty.\nIn principle, then, a TRISA node must add an HTTP service to its node to accept and respond to these POST requests. TRISA has implemented handlers and middleware in the trisacrypto/trisa go package to make it easier to add a service to your TRISA node and to translate TRISA data structures into TRP data structures.\nNext Steps: Integrating a TRP Bridge Handler into your TRISA node Making Outgoing TRP Requests Considerations As a TRISA node implementer, you have registered for mTLS certificates with TRISA’s Global Directory Service and went through a rigorous KYC process to be verified as a VASP that must exchange PII information to comply with the Travel Rule. You are probably used to using the GDS to lookup counterparty endpoints and you’ve probably experienced significant time and effort implementing key management for the cryptographic requirements that TRISA uses for non-repudiation and secure storage. Counterparties that implement TRP do not have these same requirements.\nTherefore, as you implement your TRP integration, you need to consider the following policies and integration standards.\nmTLS is a core part of TRP, however, TRP does not specify a Certificate Authority. Your implementation must consider whether it wants to perform TRP only with TRISA issued certificates or if it is willing to allow other public CAs such as Verisign or Google. There is no directory of TRP VASPs, TRP discovery is facilitated by Travel Addresses. TRP uses Travel Addresses to solve counterparty identification. The TRISA bridge is able to parse both LNURLs and the newer Travel Address format, however for complete TRP integration, you will have to supply your accounts with Travel Addresses so that other TRP implementers can reach you as a beneficiary counterparty. TRP only supports transport-level cryptography, not payload-level cryptography. There are three levels of cryptography supported by the TRISA bridge: no-cryptography, partial, insecure TRISA envelopes (encrypted but not sealed), and full TRISA compatibility. The first level is plain-vanilla TRP and the second two levels are implemented using TRP Extensions. For TRP Implementers Welcome, thank you for checking out TRISA! The best thing you can do for integration is to register for TRISA mTLS certificates on vaspdirectory.net. If you perform mTLS with TRISA VASPs using TRISA certificates, that will help a lot in establishing trust and verification for consideration #1 above.\nIf you’re interested in implementing the extensions for key exchange and parsing secure envelopes, you’re more than welcome to use the Golang code in this library to get you started! If you’re implementation is in another language, please let us know so that we can create library code to help you implement secure PII transfers.\nPlease see the Getting Started Guide for more on how to implement TRISA-specific protocol details using the extensions.\nPolicies Given the above considerations, TRISA implementers will have to consider the following policies before TRP integration:\nAllow certificate authorities other than the TRISA authority for mTLS? Allow native TRP transfers without signatures or payload cryptography? Allow TRP message signing for non-repudiation? Require either TRISA or TRP message signing for non-repudiation? Require public key exchange and secure envelope extension? The answer to these policies considerations will determine how permissive your node is to accepting different types of transfers, but at the same time create more transfer cases that need to be handled by your node.\nProtocol Comparison Feature TRISA OpenVASP TRP Governance Delaware non-profit and technical working group Swiss non-profit and technical working group Non Repudiation Signed Envelopes Signed JSON Data at Rest Secure Envelopes Transport Encryption mTLS 1.3 mTLS 1.3 Exceptions/Errors Error codes HTTP protocol errors Message Protocol Buffers JSON Data Types IVMS101, PayString, Generic IVMS101 Authentication X.509 KYV Certs Transport Protocol gRPC HTTPS Addressing VASP/Account VASP/Account Travel Address (LNURL) Discovery Sender provided, receiver verified, blockchain analytics, round robin Sender provided Onboarding TRIXO Questionnaire/GDS",
"description": "Documentation on how to integrate TRISA with the OpenVASP/TRP Protocol",
"tags": [],
"title": "OpenVASP/TRP Integration",
"uri": "/openvasp/index.html"
},
{
"breadcrumb": "TRISA Developer Documentation \u003e Working with TRISA Data",
"content": "The Key Handler package provides interfaces and handlers for managing public/private key pairs used for sealing and unsealing secure envelopes (often referred to as sealing or signing keys). TRISA nodes must handle keys in a variety of formats, such as x.509 certificates on disk or marshaled data when sending keys in TRISA key exchanges. The key management package makes PKS simpler by standardizing how keys (both private and public keys) are managed, serialized, and stored.\nGodoc Package Reference: github.com/trisacrypto/trisa/pkg/trisa/keys\nTRISA strongly recommends that sealing/unsealing keys be distinct from identity certificates for improved security and to support differing retirement criteria. Some organizations may choose to use unique sealing/unsealing keys with each unique counterparty. Others may choose to issue new sealing/unsealing keys every month, deleting keys after the compliance window is over to “erase” private information (which cannot be decrypted without the keys). Either way, when multiple keys are involved, some key management system is needed. The handlers in this package ensure that keys are managed consistently for long-running systems.\nNote The key handler package is not intended to help or handle the symmetric keys that are used to encrypt payloads. For more information on symmetric cryptography, please see the github.com/trisacrypto/trisa/pkg/trisa/crypto package.\nKey Interface The Key interface is a generic interface to either a private key pair or to a public key that has been shared in a TRISA key-exchange. The primary use of this top-level interface is serializing and deserializing keys with the marshaler interface and creating a unified mechanism to manage keys on disk.\ntype Key interface { PublicKey PrivateKey KeyMarshaler IsPrivate() bool } The PublicKey interface provides access and management of a public key, either as part of a key pair or a stand-alone public key. Critically, this interface allows you to identify the key type using a signature-based identifier of the public key for the key management. This identifier should be added to secure envelopes to ensure the envelope cryptography can be matched with the correct keys.\nPublic keys are used to seal envelopes, typically using the RSA public key algorithm. When part of a private key pair, public keys should be serialized to send to counterparties during key exchange into a trisa.api.v1beta.SigningKey message. The SigningKey message provides metadata for decoding a PEM encoded PKIX public key for RSA encryption and transaction signing.\ntype PublicKey interface { KeyIdentifier SealingKey() (interface{}, error) Proto() (*api.SigningKey, error) } The PrivateKey interface provides access to the private key object that can be used to unseal an envelope, typically an RSA Private Key. While all keys managed by a TRISA node have a public key component, not all keys managed by a TRISA node will have the private component. Private key pairs belong to the node itself and TRISA recommends slightly different key management for these keys, ensuring robustness and security of storage, using a key manager such as Vault, KMS, Kubernetes Secrets, etc.\ntype PrivateKey interface { UnsealingKey() (interface{}, error) } The KeyMarshaler interface provides mechanisms for marshaling and unmarshaling keys either from disk or during key exchange. Key storage and management is discussed further in the next section.\ntype KeyMarshaler interface { Marshal() ([]byte, error) Unmarshal(data []byte) error } Key Management Currently, the keys package wraps two types of objects:\nAn x.509 Certificate either as a key pair or a stand alone certificate. These types of certificates and private keys are what the TRISA GDS issues to users. A trisa.api.v1beta1.SigningKey protocol buffer message sent during a key exchange and containing only public key information. Keys can be instantiated from objects using one of the following methods:\nFromCertificate: use when your key manager returns certificates directly. FromGDSLookup: used to load public sealing keys from the GDS. FromProvider: providers handle compression and PKCS12 encrypted keys. FromSigningKey: used to load a public sealing key after a key exchange. FromX509KeyPair: used to load a key pair directly from a KMS. Alternatively, they can be parsed from raw data using the ParseKeyExchangedata function, which tries a variety of parsing techniques from PEM encoded data to raw certificate material, to protocol buffer unmarshaling.\nWhen storing private key pairs on disk, TRISA recommends using the Marshal and Unmarshal functions of the Certificate object, which creates PEM encoded keys. Private key pairs should be stored securely, using a dedicated key management system or encrypted disk.\nTo handle PKCS12 encrypted certificates sent from the GDS via email, use the TRISA trust Serializer to decrypt a trust Provider which can then be used to collect the Certificate object. At this point, the certificates are decrypted and can be marshaled and unmarshaled into secure storage.\nPublic Exchange keys received from counterparties should be cached in memory for a short duration, and key exchanges should be conducted routinely to ensure the correct keys are used. TRISA recommends caching public keys from counterparties for at most 1 hour or for the duration of a TransferStream RPC. When creating secure envelopes in batch, if the counterparty is unreachable for a key exchange, you may request the sealing certificate of the counterparty from the GDS using the Lookup RPC.",
"description": "Describing Key Handler Package",
"tags": [],
"title": "Key Handler Package",
"uri": "/data/keys/index.html"
},
{
"breadcrumb": "TRISA Developer Documentation \u003e Joining TRISA",
"content": "When your registration has been reviewed and approved, you will receive mTLS certificates from the Global Directory Service (GDS). These will be sent via an email containing PKCS12 password protected certificates.\nWhat to expect after registration and during certificate issuance:\nIf the registration form is valid: GDS will return a PKCS12 password. This is the password you will use to decrypt your certificates. Note This is the only time the PKCS12 password is made available during the certificate issuance process.\nOnce approved, TRISA Certificate Authority (CA) will generate a complete certificate including private keys and encrypt it using the PKCS12 password. After registration of the public keys in the directory service, GDS will then email the encrypted certificate as a ZIP file to the technical contact, or first available contact on the registration form. The content of that ZIP file is the PKCS12 file. Anatomy of the PKCS12 file A PKCS12 file is a binary format for storing a certificate chain and a private key in a single encryptable file. The PKCS12 is one of the family of standards called Public-Key Cryptography Standards (PKCS). The PKCS12 contains the X.509 digital certificate that carries a copy of the public key of the subject (i.e. the VASP or entity being issued the certificate), as well as other standard fields.\nThese certificates issued by the TRISA CA are used to identify and verify originating VASPs and beneficiary VASPs. The PKCS12 may include 2 certificates: the client’s certificate and one or more issuer (CAs) certificates. In this case, it will include the VASP’s certificate and the TRISA CA certificate.\nThe PKCS12 file below contains the X.509 Certificate chain between the client (the VASP) and the issuer (TRISA CA).\nThe client certificate also includes additional information about the VASP: the Bag Attribute and LocalKeyId (which is associated with an X.509 Public Key Certificate and its matching asymmetric private key in this PKCS12 file), and the subject and issuer fields. The subject and issuer fields are information from the certificate itself and is extracted by openssl and may include Country (C), State (S), Locality (L), Street Address (street), Postal Code (postal_code), O (Organization), and Common Name (CN) of both subject and issuer.\nSimilarly, the TRISA CA certificate also includes the subject and issuer fields, for the TRISA CA, the entities are the same.\nThe Private Key also contains the Bag Attribute and LocalKeyId.\nAccessing and Saving the Certificates The ZIP file contains a PKCS12 file (e.g. \u003ccommon_name\u003e.p12) and can be unzipped as follows:\n$ unzip \u003ccommon_name\u003e.zip The PKCS12 file can be decrypted and viewed on screen in PEM format using openssl. The -info flag provides information about the PKCS12 structure, the -in flag specifies the input filename, and the -nodes flag ensures private keys are not encrypted. You will then be prompted to enter the PKCS12 password provided during registration.\n$ openssl pkcs12 -info -in \u003ccommon_name\u003e.p12 -nodes You can save the contents of the PKCS12 file (e.g. a .pem file), using a similar command mentioned above by using the -out flag to specify an output file. Where necessary, excluding the -nodes flag will encrypt the output file.\n$ openssl pkcs12 -info -in \u003ccommon_name\u003e.p12 -out \u003ccommon_name\u003e.pem -nodes You can also save the certificates or the private keys separately, using the -nocerts flag or the -nokeys flag, respectively.\n$ openssl pkcs12 -info -in \u003ccommon_name\u003e.p12 -out \u003ccommon_name\u003e.key -nodes -nocerts $ openssl pkcs12 -info -in \u003ccommon_name\u003e.p12 -out \u003ccommon_name\u003e.crt -nodes -nokeys Or only save the client certificates or CA certificates, using the -clcerts flag or the -cacerts flag, respectively.\n$ openssl pkcs12 -info -in \u003ccommon_name\u003e.p12 -nodes -clcerts $ openssl pkcs12 -info -in \u003ccommon_name\u003e.p12 -nodes -cacerts Further Reading\nOpenSSL documentation TRISA White Paper",
"description": "Anatomy of a PKCS12 file",
"tags": [],
"title": "Anatomy of a PKCS12 file",
"uri": "/joining-trisa/pkcs12/index.html"
},
{
"breadcrumb": "TRISA Developer Documentation",
"content": "Where to look for more information and assistance: Submit your registration to join the TRISA Network: TRISA Global Directory Service\nCreate an account and complete the certificate registration form: Certificate Registration\nConnect with other VASPs, regulators, and engineers working on Travel Rule compliance: TRISA Slack\nLearn the basics about TRISA and how it helps VASPs with Travel Rule compliance: Getting Started with TRISA Video Series\nCheck to see if your data is compatible with the IVMS 101-standard: IVMS 101 Validator\nGeneral information and more links: trisa.io\nGuide of frequently asked questions that regulators have about TRISA: Regulator’s Guide\nDetails about IVMS 101 and internationally compatible data formats: intervasp.org\nDocumentation and resources for developers and technical teams: trisa.dev\nTRISA Go Package: Go Reference\nRemote Procedure Call (RPC) framework: gRPC Docs\nThe TRISA Whitepaper",
"description": "TRISA Reference",
"tags": [],
"title": "Reference",
"uri": "/reference/index.html"
},
{
"breadcrumb": "TRISA Developer Documentation \u003e Reference",
"content": "The MIT License\nCopyright (c) 2022 TRISA https://trisa.io\nPermission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the “Software”), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:\nThe above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.\nTHE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.",
"description": "Open Source License",
"tags": [],
"title": "License",
"uri": "/reference/license/index.html"
},
{
"breadcrumb": "TRISA Developer Documentation \u003e Joining TRISA",
"content": "TRISA is unique amongst open source Travel Rule protocols in that it is a trusted network, meaning that all communications are protected. TRISA uses mTLS (mutual transport layer security) to protect communications between peers. In addition to helping protect against malicious API requests, mTLS can prevent spoofing and phishing, as well as brute force and on-path attacks.\nmTLS requires that both peers in an interaction have Identity Certificates with a mutually-recognized root Certificate Authority (CA). This root CA is necessary to enhance trust and ensure that private client data is being sent to the correct party.\nImagine two VASPs that wish to exchange Travel Rule data, Alice and Bob. When Alice registers for TRISA, it receives Identity Certificates, which serve as proof to Bob that Alice is who it says it is, and vice versa:\nFirst, Alice looks Bob up in the Global Directory Serice to retrieve its endpoint and public key. Alice then presents it’s own Identity Certificates to Bob’s endpoint via an mTLS connection. Bob can then verify that Alice’s certs are signed by the TRISA root Certificate Authority. Bob looks up Alice and verifies its certificates and endpoint details in the Global Directory Service. Bob presents it’s Identity Certificates to Alice’s endpoint via mTLS. Alice can then verify that Bob’s certs are signed by the TRISA root Certificate Authority. Alice confirms that Bob’s certificate details match those in the Global Directory Service. Now that both parties are satisfied that they can trust each other with private customer data, they proceed with a Travel Rule information exchange. The Sectigo CA API Warning This portion of the documentation is targeted at TRISA developers rather than TRISA implementers. For the most part, the mechanics of certificate issuance will be fully abstracted away from TRISA implementers, who are encouraged to register for certificates using vaspdirectory.net.\nThe TRISA Directory Service currently issues certificates using the Sectigo Certificate Authority via its IoT Portal. Because the directory service must collect public key material in order to facilitate an initial trusted handshake for mTLS, it uses the Sectigo IoT Manager API as part of the VASP registration and verification process. The github.com/trisacrypto/directory/pkg/sectigo package is a Go library for interacting with the API, implementing the endpoints and methods required by the directory service. The TestNet also provides a command line utility for interacting with the API for administrative and debugging purposes.\nThis documentation describes the command line utility, which also gives an overview of how to use the API directly to issue and revoke certificates.\nReference material:\nPackage Documentation IoT Manager API Documentation IoT Manager Portal Getting Started To install the sectigo CLI utility, either download a pre-compiled binary from the releases on GitHub or install locally using:\n$ go get github.com/trisacrypto/directory/cmd/sectigo This will add the sectigo command to your $PATH.\nAuthentication The first step is authentication, you should set your username and password in the $SECTIGO_USERNAME and $SECTIGO_PASSWORD environment variables (alternatively you can pass them as parameters on the command line). To verify your authentication status you can use:\n$ sectigo auth The API authenticates by username and password then returns acess and refresh tokens which are stored in a local cache file. To see where your cache is stored:\n$ sectigo auth --cache If you’d like to check your credentials state, e.g. if the access tokens are valid, refreshable, or expired, use:\n$ sectigo auth --debug Authorities and Profiles To begin to interact with certificates you need to list the authorities and profiles that your user account has access to.\n$ sectigo authorities [ { \"id\": 1, \"ecosystemId\": 100, \"signerCertificateId\": 0, \"ecosystemName\": \"TRISA\", \"balance\": 10, \"enabled\": true, \"profileId\": 42, \"profileName\": \"TRISA Profile\" } ] The authority displays the methods and profiles that certificates are created under. Here the profileId field is very important for use in subsequent calls. You can also view how many licenses have been ordered/issued across all authorities as follows:\n$ sectigo licenses { \"ordered\": 2, \"issued\": 2 } To get detail information for a profile, use the profile ID with the following command:\n$ sectigo profiles -i 42 This will return the raw profile configuration. Before creating certificates with the authority, you’ll need to know the required profile parameters:\n$ sectigo profile -i 42 --params Creating Certificates You can request a certificate to be created with the commonName and pkcs12Password params as follows (note for profiles that require other params, you’ll have to use the code base directly and implement your own method):\n$ sectigo create -a 42 -d example.com -p secrtpasswrd -b \"example.com certs\" { \"batchId\": 24, \"orderNumber\": 1024, \"creationDate\": \"2020-12-10T16:35:32.805+0000\", \"profile\": \"TRISA Profile\", \"size\": 1, \"status\": \"CREATED\", \"active\": false, \"batchName\": \"example.com certs\", \"rejectReason\": \"\", \"generatorParametersValues\": null, \"userId\": 10, \"downloadable\": true, \"rejectable\": true } The -a flag specifies the authority, but should be a profile id. The domain must be a valid domain. If you don’t specify a password, one is generated for you and printed on the CLI before exit. The -b flag gives a human readable name for the batch creation. The return data shows detail about the batch certificate job that was created; you can fetch the data to keep checking on the status as follows:\n$ sectigo batches -i 24 You can also get processing information for the batch:\n$ sectigo batches -i 24 --status Once the batch is created, it’s time to download the certificates in a ZIP file:\n$ sectigo download -i 24 -o certs/ This will download the batch file (usually batchId.zip, 24.zip in this case) to the certs/ directory. Unzip the certs then decrypt the .pem file as follows:\n$ unzip certs/24.zip $ openssl pkcs12 -in certs/example.com.p12 -out certs/example.com.pem -nodes For more on working with the PKCS12 file, see Export Certificates and Private Key from a PKCS#12 File with OpenSSL.\nUploading a CSR An alternative to certificate creation is to upload a certificate signing request (CSR). This mechanism is often preferable because it means that no private key material has to be transmitted accross the network and the private key can remain on secure hardware.\nTo generate a CSR using openssl on the command line, first create a configuration file named trisa.conf in your current working directory, replacing example.com with the domain you plan to host your TRISA endpoint on:\n[req] distinguished_name = dn_req req_extensions = v3ext_req prompt = no default_bits = 4096 [dn_req] CN = example.com O = [Organization] L = [City] ST = [State or Province (fully spelled out, no abbreviations)] C = [2 digit country code] [v3ext_req] basicConstraints = CA:FALSE keyUsage = digitalSignature, keyEncipherment, nonRepudiation extendedKeyUsage = clientAuth, serverAuth subjectAltName = @alt_names [alt_names] DNS.1 = example.com Please carefully fill out the configuration for your certificate, this information must be correct and cannot be changed without reissuing the certificate. Also make sure that there are no spaces after the entries in the configuration!\nThen run the following command, replacing example.com with the domain name you will be using as your TRISA endpoint:\n$ openssl req -new -newkey rsa:4096 -nodes -sha384 -config trisa.conf \\ -keyout example.com.key -out example.com.csr You can then upload the CSR using the CLI program as follows:\n$ sectigo upload -p 42 \u003ccommon_name\u003e.csr { \"batchId\": 24, \"orderNumber\": 1024, \"creationDate\": \"2020-12-10T16:35:32.805+0000\", \"profile\": \"TRISA Profile\", \"size\": 1, \"status\": \"CREATED\", \"active\": false, \"batchName\": \"example.com certs\", \"rejectReason\": \"\", \"generatorParametersValues\": null, \"userId\": 10, \"downloadable\": true, \"rejectable\": true } The -p flag specifies the profile to use the CSR batch request with and must be a valid profileId. The uploaded CSRs can be a single text file with multiple CSRs in PEM form using standard BEGIN/END separators.\nManaging Certificates You can search for a certificate by name or serial number, but mostly commonly you search by the domain or common name to get the serial number:\n$ sectigo find -n example.com Once you’ve obtained the serial number you can revoke the certificate as follows:\n$ sectigo revoke -p 42 -r \"cessation of operation\" -s 12345 This command expects the profile id that issued the certificate with the -p flag, an RFC 5280 reason code passed via the -r flag (unspecified by default), and the serial number of the certificate using the -s flag. If this command doesn’t error, then the certificate has been successfully revoked.\nThe RFC 5280 reasons are:\n“unspecified” “keycompromise” “ca compromise” “affiliation changed” “superseded” “cessation of operation” “certificate hold” “remove from crl” “privilege withdrawn” “aa compromise” Note that the reason is whitespace and case insensitive.",
"description": "The TRISA PKI Infrastructure",
"tags": [],
"title": "Certificate Authority",
"uri": "/joining-trisa/ca/index.html"
},
{
"breadcrumb": "TRISA Developer Documentation \u003e TRISA Envoy",
"content": "For the latest and most up to date description of the Envoy configuration, ask Envoy directly! You can do this using the Envoy docker image as follows:\n$ docker run trisa/envoy:latest envoy config This will print out a table of the configuration options, default values, and descriptions. If you’d prefer it in list form, run:\n$ docker run trisa/envoy:latest envoy config --list Configuration Values Envoy is configured via the environment and for local development, also supports using .env files in the working directory for loading environment variables. We recommend configuring Envoy using the deployment mechanism of your choice. For example, if you’re running the binary using systemd, then the environment should be defined in your .service using Environment or an EnvironmentFile. If you’re using Kubernetes or Docker, then the environment variables should be added to the manifest of your deployment.\nA list of the primary environment variables and their configuration are as follows:\nEnvVar Type Default Description TRISA_MAINTENANCE bool false If true, the node will start in maintenance mode and will respond Unavailable to requests TRISA_ORGANIZATION string Envoy Specify the display name of the organization using the Envoy node for the web UI and interactive docs TRISA_MODE string release Specify the mode of the API/UI server (release, debug, or testing) TRISA_LOG_LEVEL string info Specify the verbosity of logging (trace, debug, info, warn, error, fatal, panic) TRISA_CONSOLE_LOG bool false If true, logs colorized human readable output instead of json TRISA_DATABASE_URL string sqlite3:///trisa.db DSN containing the backend database configuration TRISA_WEBHOOK_URL string Specify a callback webhook so that incoming travel rule messages can be handled by a different system TRISA_ENDPOINT string The endpoint of the TRISA node as defined by the mTLS certificates (to create travel addresses) TRISA_TRP_ENDPOINT string If enabled, the endpoint of the TRP node as assigned by the mTLS certificates (to create travel addresses) Web UI/API Configuration These configuration values influence the behavior of the internal web UI and API.\nEnvVar Type Default Description TRISA_WEB_ENABLED bool true If false, both the web UI and API are disabled TRISA_WEB_API_ENABLED bool true If false, the API will return unavailable when accessed TRISA_WEB_UI_ENABLED bool true If false, the web UI will return unavailable when accessed TRISA_WEB_BIND_ADDR string :8000 The IP address and port to bind the web server on TRISA_WEB_ORIGIN string http://localhost:8000 The origin (url) of the web UI for creating API endpoints TRISA_WEB_DOCS_NAME string The display name for the API docs server in the Swagger app (by default the organization name) TRISA_WEB_AUTH_KEYS map Optional static RSA key configuration for signing access and refresh tokens. Should be a comma separated map of keyID:path. TRISA_WEB_AUTH_AUDIENCE string http://localhost:8000 The value for the aud (audience) claim in JWT tokens issued by the API TRISA_WEB_AUTH_ISSUER string http://localhost:8000 The value for the iss (issuer) claim in JWT tokens issued by the API TRISA_WEB_AUTH_COOKIE_DOMAIN string localhost Limit cookies for the UI to the specified domain (exclude any port information) TRISA_WEB_AUTH_ACCESS_TOKEN_TTL duration 1h The amount of time before an access token expires TRISA_WEB_AUTH_REFRESH_TOKEN_TTL duration 2h The amount of time before refresh tokens expire TRISA_WEB_AUTH_TOKEN_OVERLAP duration -15m The amount of overlap between the access and refresh tokens, the more negative the duration the more the overlap TRISA Node Configuration Configuration values for the public facing TRISA node.\nEnvVar Type Default Description TRISA_NODE_ENABLED bool true If false, the TRISA node server will not be run TRISA_NODE_BIND_ADDR string :8100 The ip address and port to bind the TRISA node server on TRISA_NODE_POOL path The path to TRISA x509 certificate pool; this allows you to define what certificate authorities you’re willing to accept using mTLS (optional) TRISA_NODE_CERTS path The path to your TRISA identify certificates and private key for establishing mTLS connections to TRISA peer counterparties TRISA_NODE_KEY_EXCHANGE_CACHE_TTL duration 24h The duration to cache public keys exchanged with remote TRISA nodes before performing another key exchange TRISA Directory Configuration The following configuration influences how the Envoy node connects to the TRISA Global Directory Service.\nIf you’re running a TestNet node, then ensure the values point to trisatest.net (e.g. api.trisatest.net:443), if you’re running a MainNet node, then ensure the values point to vaspdirectory.net (the default values).\nEnvVar Type Default Description TRISA_NODE_DIRECTORY_INSECURE bool false If true, do not connect to the directory using TLS (only useful for local development) TRISA_NODE_DIRECTORY_ENDPOINT string api.vaspdirectory.net:443 The endpoint of the public GDS service TRISA_NODE_DIRECTORY_MEMBERS_ENDPOINT string members.vaspdirectory.net:443 The endpoint of the private members GDS service TRISA_DIRECTORY_SYNC_ENABLED bool true If false, then the background directory sync service will not run TRISA_DIRECTORY_SYNC_INTERVAL duration 6h The interval that the node will synchronize counterparties with the GDS TRP Node Configuration Configuration values for the publically facing TRP server.\nEnvVar Type Default Description TRISA_TRP_ENABLED bool true If false, the TRP node server will not be run TRISA_TRP_BIND_ADDR string :8200 The ip address and port to bind the TRISA node server on TRISA_TRP_USE_MTLS bool true If true, the TRP server will require mTLS authentication TRISA_TRP_POOL path The path to TRP x509 certificate pool; this allows you to define what certificate authorities you’re willing to accept using mTLS (optional) TRISA_TRP_CERTS path The path to your TRP identify certificates and private key for establishing mTLS connections to TRISA peer counterparties Region Info Envoy nodes support some provenance features when deployed in a geographically replicated fashion. If you would like to configure your node with hosting information (even just for debugging using the about page on the node), you may set the following environment variables:\nEnvVar Type Default Description REGION_INFO_ID int32 the 7 digit region identifier code REGION_INFO_NAME string the name of the region REGION_INFO_COUNTRY string the alpha-2 country code of the region REGION_INFO_CLOUD string the cloud service provider REGION_INFO_CLUSTER string the name of the cluster the node is hosted in",
"description": "Configuring Envoy",
"tags": [],
"title": "Configuration",
"uri": "/envoy/configuration/index.html"
},
{
"breadcrumb": "TRISA Developer Documentation \u003e Joining TRISA",
"content": "The TRISA Certificate Authority issues x509 certificates for mTLS authentication in its peer-to-peer network. These certificates are dependent on the verified ownership of a domain name that is used both in the common name of the certificate (CN) as well as the subject alternative name (SAN) extension of the certificate. Your TRISA node must be hosted at a domain name that is in the SAN field of the certificate otherwise mTLS connections will fail.\nNote The domain that you host your TRISA node, e.g. trisa.example.com must be the common name of your TRISA Identity Certificates and must match the endpoint of your TRISA directory record, e.g. trisa.example.com:443. If not, TRISA peers will be unable to connect to your TRISA node using mTLS. If you are using multiple domain names, please contact TRISA support for assistance.\nBecause the domain names assigned to the certificate are part of the secure handshake in mTLS; you must prove that you own the specified domain name before certificates may be issued. This prevents bad actors from attempting to pose as another entity in the TRISA network. There are two methods of domain verification: email verification (the default) and DNS verification.\nEmail Verification By default, when you register for a TRISA account a secure token is sent to your email address with a link to validate the email. When you click on the link the token is verified in the directory service; proving that you do have control over the email account specified in the registration. Multiple verification emails may be sent - please click on them all!\nIf the domain of your email address matches the common name requested for the TRISA certificates, then this validation process also proves that you have control of the domain.\nIf your email address domain does not match the domain of the common name; then you may contact TRISA support in order to change your email address to one that does. A verification email will be resent and you can complete the domain verification with the new email address.\nDNS Verification If you do not have an email address with a domain that matches the common name you have requested for the TRISA certificates; then please get in touch with TRISA support to perform manual DNS verification. Note that this process can be challenging and you will need access to your registrar or DNS host and the permissions to add DNS records for the specified domain.\nAfter contacting support, you will receive a whisper link that contains a verification code that will likely look something like:\nTRISA-DOMAIN-VERIFICATION-XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX Once you’ve obtained the verification code, perform the following steps:\nLog into your registrar or your DNS management utility Edit the DNS records for the domain you wish to verify Create a new TXT record for the TRISA domain whose value is the verification code Contact TRISA support and let them know they can verify the DNS record Consider the example where you wish to create a verification record for trisa.example.com. In this example, example.com is the root domain whose DNS records you need to edit. Create a TXT record for the name trisa.example.com (note there will likely be a field called Host, Hostname, or Alias where you will enter trisa). There are many types of records that you can create, e.g. A records or CNAME records, but it is important that you create a TXT record for verification. Make sure you copy the complete verification code without any spaces before or after the code into the value field (which may be called Data, Answer, or Destination).\nNote that this process will soon be automated in the future to make it easier for TRISA members to verify the domains that they control.",
"description": "Domain Verification",
"tags": [],
"title": "Domain Verification",
"uri": "/joining-trisa/verification/index.html"
},
{
"breadcrumb": "TRISA Developer Documentation \u003e Global Directory Service",
"content": "The TRISAMembers service is an experimental service that provides extra, secure access to the directory service for verified TRISA members. Only members of the TRISA network (e.g. members who have been issued valid identity certificates) can access detailed directory service data about the network using this service. Note: Once validated, this service will be moved into the official TRISA specification.\nThe TRISAMembers Service This section describes the protocol buffers for the TRISAMembers endpoint, which can be found here. This file can be compiled into the language of your choice (example for Go). Note: You will need to download and install the protocol buffer compiler if you have not already.\nCurrently, the TRISAMembers service is comprised of three RPCs — the List, Summary, and Details RPCs. Other experimental, secure RPCs may be made available in the future.\nservice TRISAMembers { // List all verified VASP members in the Directory Service. rpc List(ListRequest) returns (ListReply) {}; // Get a short summary of the verified VASP members in the Directory Service. rpc Summary(SummaryRequest) returns (SummaryReply) {}; // Get details for a VASP member in the Directory Service. rpc Details(DetailsRequest) returns (MemberDetails) {}; } Listing Verified Members The List RPC returns a paginated list of all verified TRISA members to facilitate TRISA peer lookups. The RPC expects as input a ListRequest and returns a ListReply.\nListRequest A ListRequest can be used to manage pagination for the VASP list request. If there are more results than the specified page size, the ListReply will return a page token that can be used to fetch the next page (so long as the parameters of the original request are not modified, e.g. any filters or pagination parameters).\nThe page_size specifies the number of results per page and cannot change between page requests; it’s default value is 100. The page_token specifies the page token to fetch the next page of results.\nmessage ListRequest { int32 page_size = 1; string page_token = 2; } ListReply A ListReply returns an abbreviated listing of VASP details intended to facilitate peer-to-peer key exchanges or more detailed lookups against the Directory Service.\nThe vasps are a list of VASPs (see definition of VASPMember below), and the next_page_token, if specified, is notification that another page of results exists.\nmessage ListReply { repeated VASPMember vasps = 1; string next_page_token = 2; } VASPMember A VASPMember contains enough information to facilitate peer-to-peer exchanges or more detailed lookups against the Directory Service. The ListReply will contain a list of none, one, or multiple VASPMembers.\nmessage VASPMember { // The uniquely identifying components of the VASP in the directory service string id = 1; string registered_directory = 2; string common_name = 3; // Address to connect to the remote VASP on to perform a TRISA request string endpoint = 4; // Extra details used to facilitate searches and matching string name = 5; string website = 6; string country = 7; trisa.gds.models.v1beta1.BusinessCategory business_category = 8; repeated string vasp_categories = 9; string verified_on = 10; } Summarizing Verified VASP Members in the Directory Service The Summary RPC returns a brief summary of information about verified VASP members in the Directory Service. The RPC expects as input a SummaryRequest and returns a SummaryReply.\nSummaryRequest A SummaryRequest allows the caller to request VASP summary information from the Global Directory Service (GDS). If desired, the caller can indicate a start date to return a count of how many new members have been added since a previous query. The caller can also include a VASP ID to return that VASP’s record in the summary.\nmessage SummaryRequest { // The start date for determining how many members are new - optional string since = 1; // Include your VASP ID to return details about your VASP record in the summary - optional string member_id = 2; } SummaryReply A SummaryReply returns summary info about the members in the Directory Service. This information includes a count of registered VASPs and certificates issued within the Directory Service. SummaryReply also provides a count of new members and details about a particular member VASP, if requested.\nmessage SummaryReply { // Counts of VASPs and certificates int32 vasps = 1; int32 certificates_issued = 2; int32 new_members = 3; // Details for the requested VASP VASPMember member_info = 4; } Getting TRIXO and IVMS101 LegalPerson Details The Details RPC returns a detailed record for the requested VASP, including the VASPMember details described earlier in this page, as well as the TRIXO form and IVMS101 record for the VASP. The RPC expects as input a DetailsRequest and returns a MemberDetails message.\nDetailsRequest A DetailsRequest allows the caller to specify the VASP member to retrieve details for from the Global Directory Service (GDS). The member_id is expected to be the VASP’s TRISA member ID, a unique identifier to the GDS.\nmessage DetailsRequest { string member_id = 1; } MemberDetails A MemberDetails message provides details about the requested VASP member, which includes not only their high level VASPMember summary, but also the IVMS101 legal person record and responses to the TRIXO questionnaire (both of which are a required component of all TRISA certificate requests).\nmessage MemberDetails { // Summary information about the VASP member VASPMember member_summary = 1; // The IVMS101 legal person identifying the VASP member ivms101.LegalPerson legal_person = 2; // The TRIXO questionnaire used to register the VASP trisa.gds.models.v1beta1.TRIXOQuestionnaire trixo = 3; } Connecting with mTLS To use the TRISAMembers service, you must authenticate with mTLS using the TRISA identity certificates you were granted during registration.\nThe gRPC documentation on authentication provides code samples for connecting using mTLS in a variety of languages, including Java, C++, Golang, Ruby, and Python.\nFor example, if you were using Golang to connect to the Directory Service, you would use the tls, x509, and credentials libraries to load your TRISA identity certificates from their secure location on your computer and construct TLS credentials to mutually validate the connection with the server. Finally you would use the compiled members protocol buffer code to create a members client. Note: the protocol buffer definitions are described more fully earlier in this page.\nimport ( \"crypto/tls\" \"crypto/x509\" members \"github.com/trisacrypto/directory/pkg/gds/members/v1alpha1\" \"google.golang.org/grpc/credentials\" ) func (m *MyProfile) Connect() (_ members.TRISAMembersClient, err error){ config := \u0026tls.Config{ Certificates: []tls.Certificate{m.Cert}, // m.Cert is your TRISA certificate parsed into a *x509.Certificate MinVersion: tls.VersionTLS12, CurvePreferences: []tls.CurveID{ tls.CurveP521, tls.CurveP384, tls.CurveP256, }, PreferServerCipherSuites: true, CipherSuites: []uint16{ tls.TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384, tls.TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256, tls.TLS_RSA_WITH_AES_256_GCM_SHA384, tls.TLS_RSA_WITH_AES_128_GCM_SHA256, }, ClientAuth: tls.RequireAndVerifyClientCert, // this will ensure an mTLS connection ClientCAs: m.Pool, // m.Pool is a *x509.CertPool that must contain the RA and IA public certs from your TRISA certificate chain } var creds *credentials.TransportCredentials if creds, err = credentials.NewTLS(config); err != nil { return nil, err } var cc *grpc.ClientConn if cc, err = grpc.NewClient(m.Endpoint, grpc.WithTransportCredentials(creds)); err != nil { return nil, err } return members.NewTRISAMembersClient(cc), nil } Note that there are currently two TRISA directories; the TRISA TestNet, which allows users to experiment with the TRISA interactions, and the VASP Directory, which is the production network for TRISA transactions. If you have registered for the TestNet and have TestNet certificates, the endpoint you will pass into the dialing function will be members.trisatest.net:443. Alternatively, if you wish to access members of the VASP Directory and are already a registered member, you will use the endpoint members.vaspdirectory.net:443.",
"description": "Accessing Other TRISA Members",
"tags": [],
"title": "Accessing Members",
"uri": "/gds/members/index.html"
},
{
"breadcrumb": "TRISA Developer Documentation \u003e Testing and Deployment",
"content": "In the process of testing your TRISA implementation, you may wish to generate some test certificates (e.g. for use in unit testing). The TRISA engineers have created a command line tool for this purpose, which can be found in the trisacrypto/directory repository.\nThe Certificates command line client is a utility designed for local disk certificate management and test Certificate Authority (CA) for testing purposes. The code is located under cmd/certs. To install the latest version of the Certificates CLI, you must have Go installed on your computer. The following command will install the latest version of the CLI:\n$ go install github.com/trisacrypto/directory/cmd/certs@latest Alternatively, to install the Certificate CLI from the trisacrypto/directory root, first clone the Directory repository and then run the following:\n$ go install ./cmd/certs Configuration Before using the certs CLI, you must confirm your environment has the certs program in your go workspace bin and is present in your $PATH.\n$ ls $GOPATH/bin certs The certs CLI has two command categories: for the CA and for the client certs. To see the CLI commands and which flags should be specified, use certs --help.\nCreating a Test Certificate Authority (CA) The first step to creating the local disk certificate management is creating the CA certs that contain a randomly generated certificate and RSA key pair. You can use certs init to create CA certs if they do not already exist. The -c flag specifies the output location to write the CA certs; without the flag, the default location of the CA certs will be in fixtures/certs/ca.gz. If you want to overwrite existing CA keys, you can use the -f flag.\n$ certs init -c path/to/ca.gz Generating the Certificates After creating the local CA, it then can issue “self-signed” certificates by that local CA, e.g., certificates signed by the keys in ca.gz, as follows:\n$ certs issue -c ca.gz -n \"Common_Name\" -O \"Organization\" The issue command requires the -n flag (which specifies the common name for the certificate) and the -O flag (which specifies the name of the organization that the certificates are for.) The default output location is \u003ccommon_name.gz\u003e. However, there are other flags to specify additional information for the organization.\n-n value, --name value common name for the certificate -O value, --organization value name of organization to issue certificates for -C value, --country value country of the organization -p value, --province value province or state of the organization -l value, --locality value locality or city of the organization -a value, --address value street address of the organization -z value, --postcode value postal code of the organization You can also PKCS12 encrypt the issued cert with the -P flag to specify the password and the -o flag to specify the output location using the .p12 extension.\n$ certs issue -c ca.gz -o certs.p12 -P password -n \"Common_Name\" -O \"Organization\" Decrypting Files The certs CLI also has a command to decrypt PKCS12 files and can be used as follows:\n$ certs decrypt \u003ccommon_name.p12\u003e -p password The decrypt command requires the -p flag (which specifies the password of the encrypted file). And default output is \u003ccommon_name.gz\u003e, but you can specify the output location using the -o flag.\nCreating Trust Chain Pools Additionally, the certs CLI has a command to create a trust chain pool from certificates that were created on your local disk. It saves the pool into a zip file that you can specify with the -o flag. The pools are used to manage the public trust certificates of peers in the network. The pool maps common names to the provider certificates and ensures that only public providers without private keys are stored in the pool.\n$ certs pool \u003ccommon_name1.pem\u003e \u003ccommon_name2.pem\u003e -o pool.zip While public providers are used in providers pools to facilitate mTLS clients, providers with keys (private providers) are used to instantiate mTLS servers. Such that, if two pairs of certs signed with the same ca.gz will enable you to establish an mTLS connection between two nodes.",
"description": "Using the Certificates Tool and Local Disk Certificate Management and Test CA",
"tags": [],
"title": "Creating Test Certificates",
"uri": "/testing/certs-cli/index.html"
},
{
"breadcrumb": "TRISA Developer Documentation \u003e TRISA Envoy",
"content": "API Credentials In order to use the API you will have to generate an API Key Client ID and Secret either from the user interface, or by using the command line tool as described in “creating api keys”.\nAuthentication and Authorization All API endpoints require authorization using Bearer tokens in the Authorization header. The Bearer token is a time-limited JWT token that is signed by the Envoy server. The JWT token contains the valid claims that the API key has: most importantly the permissions assigned to the API Key. If the endpoint requires a permission that the API key does not have then a 403 error is returned.\nTo obtain the JWT bearer token, you must first authenticate with the server using your client ID and secret with a POST request to /v1/authenticate.\nPOST /v1/authenticate HTTP/1.1 Host: [ENDPOINT] Accept: application/json Content-Type: application/json { \"client_id\": \"[CLIENT_ID]\", \"client_secret\": \"[CLIENT_SECRET]\" } The response will contain a JWT access_token and refresh_token. The access_token should be used as the Authorization: Bearer token for all API requests:\nGET /v1/counterparties HTTP/1.1 Host: [ENDPOINT] Accept: application/json Content-Type: application/json Authorization: Bearer [ACCESS_TOKEN] By default the access token expires after 1 hour and the refresh token expires after 2 hours, becoming available 15 minutes before the access token expires (though these durations can all be configured).\nTo reauthenticate while the refresh_token is still valid, POST the refresh_token to the /v1/reauthenticate endpoint to obtain new access and refresh tokens without having to resupply the client ID and secret.\nPOST /v1/reauthenticate HTTP/1.1 Host: [ENDPOINT] Accept: application/json Content-Type: application/json { \"refresh_token\": \"[REFRESH_TOKEN]\" } Permissions The following table contains the permissions available to API keys:\nPermission Description users:manage Can create, edit, and delete users users:view Can view users registered on the node apikeys:manage Can create apikeys and view associated secret apikeys:view Can view apikeys created on the node apikeys:revoke Can revoke apikeys and delete them counterparties:manage Can create, edit, and delete counterparties counterparties:view Can view counterparty details accounts:manage Can create, edit, and delete accounts and crypto addresses accounts:view Can view accounts and crypto addresses travelrule:manage Can create, accept, reject, and archive transactions and send secure envelopes travelrule:delete Can delete transactions and associated secure envelopes travelrule:view Can view travel rule transactions and secure envelopes config:manage Can manage the configuration of the node config:view Can view the configuration of the node pki:manage Can create and edit certificates and sealing keys pki:delete Can delete certificates and sealing keys pki:view Can view certificates and sealing keys",
"description": "Guide to using the Envoy API",
"tags": [],
"title": "API Guide",
"uri": "/envoy/api/index.html"
},
{
"breadcrumb": "TRISA Developer Documentation \u003e TRISA Protocol and API",
"content": "Error codes are standardized in the TRISA network to prevent confusion and allow easy identification of rejections or other problems to expedite the repair of the connection or information exchange. Then, the human-readable message stating the reason for the error should be loggable and actionable. Both standardized and unique/detail messages are acceptable. The message that caused the error should be retried with a fix, otherwise the rejection is permanent, and the request should not be retried. The payload of the additional data or reasons for the rejection, e.g., a parent error, a diff, a location for redirect, etc., should be described by the error code.\nSee the error protocol buffers for more details.\nTRISA Errors Codes, Messages, and Descriptions ERROR CODE ERROR MESSAGE ERROR DESCRIPTION 0 UNHANDLED Default error - something very bad happened. 1 UNAVAILABLE Generic error - could not handle request, retry later. 1 SERVICE_DOWN_TIME Generic error - could not handle request, retry later. 1 BVRC002 Generic error - could not handle request, retry later. (Alias: Sygna BVRC Rejected Type) 2 MAINTENANCE The service is currently in maintenance mode and cannot respond. 3 UNIMPLEMENTED The RPC is not currently implemented by the TRISA node. 49 INTERNAL_ERROR Request could not be processed by recipient. 49 BVRC999 Request could not be processed by recipient. (Alias: Sygna BVRC Rejected Code) 50 REJECTED Default rejection - no specified reason for rejecting the transaction. 51 UNKNOWN_WALLET_ADDRESS VASP does not control the specified wallet address. 52 UNKNOWN_IDENTITY VASP does not have KYC information for the specified wallet address. 52 UNKOWN_IDENTITY VASP does not have KYC information for the specified wallet address. (Typo left for backwards compatibility.) 53 UNKNOWN_ORIGINATOR Specifically, the Originator Account cannot be identified. 54 UNKOWN_BENEFICIARY Specifically, the Beneficiary account cannot be identified. 54 BENEFICIARY_NAME_UNMATCHED Specifically, the Beneficiary account cannot be identified. (Alias: Sygna BVRC Rejected Type) 54 BVRC007 Specifically, the Beneficiary account cannot be identified. (Alias: Sygna BVRC Rejected Code) 60 UNSUPPORTED_CURRENCY VASP cannot support the fiat currency or coin described in the transaction. 60 BVRC001 VASP cannot support the fiat currency or coin described in the transaction.(Alias: Sygna BVRC Rejected Code) 60 UNSUPPORTED_NETWORK VASP cannot support the specified network (Alias: helpful if the chain is not a currency) 61 EXCEEDED_TRADING_VOLUME No longer able to receive more transaction inflows. 61 BVRC003 No longer able to receive more transaction inflows. (Alias: Sygna BVRC Rejected Code) 75 UNSUPPORTED_ADDRESS_CONFIRMATION VASP will not support the requested address confirmation mechanism. 76 CANNOT_CONFIRM_CONTROL_OF_ADDRESS VASP cannot confirm they control the requested address, but doesn’t necessarily indicate that they do not control the address. 90 COMPLIANCE_CHECK_FAIL An internal compliance check has failed or black listing has occurred. 90 BVRC004 An internal compliance check has failed or black listing has occurred. (Alias: Sygna BVRC Rejected Code) 91 NO_COMPLIANCE VASP not able to implement travel rule compliance. 92 HIGH_RISK VASP unwilling to conduct the transaction because of a risk assessment. 99 OUT_OF_NETWORK Wallet address or transaction is not available on this network. 100 FORBIDDEN Default access denied - no specified reason for forbidding the transaction. 101 NO_SIGNING_KEY Could not sign transaction because no signing key is available. 102 CERTIFICATE_REVOKED Could not sign transaction because keys have been revoked. 103 UNVERIFIED Could not verify certificates with any certificate authority. 104 UNTRUSTED A trusted connection could not be established. 105 INVALID_SIGNATURE An HMAC signature could not be verified. 106 INVALID_KEY The transaction bundle cannot be decrypted with the specified key. 107 ENVELOPE_DECODE_FAIL Could not decode or decrypt private transaction data. (Alias: Sygna BVRC Rejected Type) 107 PRIVATE_INFO_DECODE_FAIL Could not decode or decrypt private transaction data. (Alias: Sygna BVRC Rejected Code) 107 BVRC005 Could not decode or decrypt private transaction data. 108 UNHANDLED_ALGORITHM The algorithm specified by the encryption or signature is not implemented. 150 BAD_REQUEST Generic bad request - usually implies retry when request is fixed. 151 UNPARSEABLE_IDENTITY Could not parse the identity record; specify the type in extra. 151 PRIVATE_INFO_WRONG_FORMAT Could not parse the identity record; specify the type in extra. (Alias: Sygna BVRC Rejected Type) 151 BVRC006 Could not parse the identity record; specify the type in extra. (Alias: Sygna BVRC Rejected Code) 152 UNPARSEABLE_TRANSACTION Could not parse the transaction data record; specify the type in extra. 153 MISSING_FIELDS There are missing required fields in the transaction data, a list of these fields is specified in extra. 154 INCOMPLETE_IDENTITY The identity record is not complete enough for compliance purposes of the receiving VASPs. Required fields or format specified in extra. 155 VALIDATION_ERROR There was an error validating a field in the transaction data (specified in extra). 198 COMPLIANCE_PERIOD_EXCEEDED Send by originating party if the review period has exceeded the required compliance timeline. 199 CANCELED Cancel the ongoing TRISA exchange and do not send funds. 199 CANCEL_TRANSACTION Cancel the ongoing TRISA exchange and do not send funds. (Alias: CANCELED)",
"description": "Describing TRISA Errors and Rejections",
"tags": [],
"title": "TRISA Errors and Rejections",
"uri": "/api/errors/index.html"
},
{
"breadcrumb": "TRISA Developer Documentation \u003e TRISA Envoy",
"content": "Enabling the Webhook To enable the Envoy webhook, you must first specify a webhook endpoint using the $TRISA_WEBHOOK_URL as specified in the “configuration values”. This URL should be available for HTTP POST requests from the Envoy node. If this value is not specified, Envoy will not make any webhook callbacks.\nWhen Envoy receives an incoming travel rule message from a remote counterparty it must return a response to that request (for both TRP and TRISA requests). Envoy may handle the request automatically using accept/reject policies or it may simply send a pending message back as the default response. Envoy also supports handling incoming messages by using a webhook callback for another compliance system to determine handling.\nWhen the webhook is enabled, on every incoming travel rule message Envoy will:\nDecrypt the message (returning an error if decryption is unsuccessful) Validate the message (returning an error if the message is invalid) Make an http POST request to your webhook with the decrypted message as JSON Validate the JSON response from the webhook Encrypt the outgoing message and send back to the recipient Store the secure envelopes locally The webhook will make an POST request to your endpoint supplying the data descrbed in the webhook request in JSON format. Envoy expects a status code 200 response from your endpoint with a reply in UTF-8 encoded JSON.\nA couple of important things to note:\nYou must provide a valid response back to Envoy or an error will be returned to the counterparty and logged on the server. If the webhook is unavailable, Envoy will return service unavailable to the counterparty. Envoy has a request timeout of 30 seconds, however the counterparty may have a shorter duration timeout; if this is the case the request will be canceled. Webhook Request The webhook POST request will contain some metadata about the incoming secure envelope, the counterparty, and will contain one of an error or a payload as follows:\n{ \"transaction_id\": \"\", \"timestamp\": \"\", \"counterparty\": {}, \"hmac_signature\": \"\", \"public _key_signature\": \"\", \"transfer_state\": \"\", \"error\": {}, \"payload\": {} } Field Type Description transaction_id uuid the id of both the Envoy transaction and the secure envelope id timestamp timestamp the RFC3339Nano timestamp of the secure envelope counterparty object the information about the counterparty that Envoy has in its database hmac_signature base64 if the secure envelope has a valid hmac_signature, this is the base64 encoded signature (omitted if not set) public_key_signature string used to identify the public keys that sealed the incoming secure envelope (omitted if not set) transfer_state string the TRISA transfer state of the secure envelope error object if the incoming envelope is a rejection or repair request the error will be set (omitted if payload is set) payload object if the incoming envelope contains a travel rule information payload, this will be the decrypted info (omitted if error is set) Details of the counterparty, error, and payload objects are described below.\nWebhook Reply The reply to the POST request must have a 200 status code and the following data serialized as UTF-8 encoded JSON. Note that either the error field or the payload field may be specified but not both.\n{ \"transaction_id\": \"\", \"error\": {}, \"payload\": {}, \"transfer_action\": \"\" } Field Type Description transaction_id uuid the transaction_id must match the transaction_id of the request error object if you’re rejection or requesting a repair, specify the details in this field (must be omitted if payload is set) payload object the payload to return to the counterparty (may simply be an echo of the original payload) (must be omitted if error is set) transfer_action string the TRISA transfer action you’d like specified in the reply to the counterparty (see below for values) If the transaction_id does not match the ID of the request, then Envoy will fail and return an error to the counterparty.\nThe transfer_action can be one of “PENDING”, “REVIEW”, “REPAIR”, “ACCEPTED”, “REJECTED”, or “COMPLETED”. See TRISA workflows for more about how these states determine responses to incoming messages. A basic summary is as follows:\nUse \"PENDING\" if a compliance officer on your team needs to review the travel rule request, make sure you include a pending and identity in your reply.\nUse \"REVIEW\" if the counterparty’s compliance officer needs to review the travel rule request, make sure you include a transaction and identity in your reply. This is generally used if you’ve made changes to the original payload.\nUse \"REPAIR\" if you need the counterparty to make a change to the payload, e.g. if it is missing fields required for your jurisdiction, make sure you’ve included an error in your reply that describes the changes that need to be made.\nUse \"ACCEPTED\" if you’re ready for the counterparty to make the on-chain transaction and you’re satisfied with the compliance exchange. Make sure to echo back the transaction and identity in your reply.\nUse \"REJECTED\" if you do not want the counterparty to proceed with the on-chain transaction; make sure to include the error in your reply with the rejection information.\nUse \"COMPLETED\" if the compliance exchange is accepted and the on-chain transaction has already been conducted and the payload contains a proper, chain-specific transaction ID in the payload. Make sure you echo back the transaction and identity in your reply.\nAPI Objects This section describes nested objects in the request and reply.\nError Errors are mutually exclusive with payloads, meaning a response or reply to the webhook will have either an error field or a payload field but should not have both.\nAn error describes either a repair or a rejection (determined by the retry boolean flag). A rejection (retry=false) implies that the counterparty should stop the on-chain transaction as the compliance exchange has not been satisfied. A repair (retry=true) implies that the counterparty needs to amend the identity payload, e.g. because there are missing fields that are required for compliance in your jurisdiction.\nThe fields for the error are as follows:\n{ \"code\": 0, \"message\": \"\", \"retry\": false } Field Type Description code int32 the error code from the TRISA api package message string a detailed message about why the request is being rejected or what needs to be repaired retry bool should be false if this is a rejection, true if a repair is being requested View the available error codes in the TRISA API docs.\nPayload Payloads are mutually exclusive with errors, meaning a response or reply to the webhook will have either a payload field or an error field but should not have both.\nAdditionally, payloads have mutually exclusive fields pending and transaction - a payload can have one or the other, but not both.\nThe payload fields are as follows:\n{ \"identity\": {}, \"pending\": {}, \"transaction\": {}, \"sent_at\": \"\", \"received_at\": \"\" } Field Type Description identity object an IVMS101 payload, see IVMS101 docs for more information pending object a TRISA pending message, see TRISA docs for more information transaction object a TRISA generic transaction, see TRISA docs for more information sent_at string the RFC3339 encoded timestamp of when the compliance exchange was initiated received_at string the RFC3339 encoded timestamp of when the compliance exchange was approved by the counterparty For more information about IVMS101, please see: Working with IVMS101.\nFor more information about the pending and transaction generic payloads, please see: TRISA Data Payloads.\nCounterparty The counterparty describes what the Envoy node knows about the remote counterparty. This information may be more complete if the counterparty record was created by the TRISA directory service or stored locally on the node. If the record was created by a TRP record, this information may be fairly sparse.\n{ \"id\": \"\", \"source\": \"\", \"directory_id\": \"\", \"registered_directory\": \"\", \"protocol\": \"\", \"common_name\": \"\", \"endpoint\": \"\", \"travel_address\": \"\", \"name\": \"\", \"website\": \"\", \"country\": \"\", \"business_category\": \"\", \"vasp_categories\": [], \"verified_on\": \"\", \"ivms101\": \"\", \"created\": \"\", \"modified\": \"\" } Field Type Description id ulid the Envoy id of the counterparty for api lookups source string the source of the counterparty info (e.g. user, gds, x509) directory_id uuid the id of the counterparty in the TRISA directory registered_directory string the id of the directory the counterparty is listed in protocol string the preferred protocol of the counterparty (trp or trisa) common_name string the common name associated with the counterparty’s certificates endpoint string the uri endpoint of the counterparty to send travel rule requests travel_address string a travel address identifying the generic endpoint of the counterparty name string the display name of the counterparty website string the website of the counterparty country string the alpha-2 country code of the counterparty business_category string the business category of the counterparty (e.g. private, government, etc) vasp_categories []string the type of virtual asset services the counterparty provides (e.g. Exchange or Miner) verified_on string the RFC3339 timestamp of when the counterparty was verified by the TRISA network ivms101 IVMS 101 the ivms101 record of the legal person representing the counterparty created string the RFC3339nano timestamp of when the counterparty was added to your Envoy node modified string the RFC3339nano timestamp of when the counterparty was lasted modified on your Envoy node",
"description": "Handling incoming messages with webhooks",
"tags": [],
"title": "Webhook Guide",
"uri": "/envoy/webhook/index.html"
},
{
"breadcrumb": "TRISA Developer Documentation \u003e TRISA Envoy",
"content": "How can we help? Open Source One-Time Setup Managed Service Envoy Documentation ✓ ✓ ✓ Access to TRISA Slack Community ✓ ✓ ✓ Training from Envoy Team ✓ ✓ Dedicated Support ✓ Response Time* Within 5 business days Within 5 business days Within 3 business days *The Envoy team’s business hours are 9AM - 6PM Eastern.",
"description": "Envoy Support",
"tags": [],
"title": "Envoy Support",
"uri": "/envoy/support.end/index.html"
},
{
"breadcrumb": "TRISA Developer Documentation \u003e Global Directory Service",
"content": "The TRISA Global Directory Service is managed by administrators appointed by the TRISA board to support and vet VASPs registering to join the TRISA network. TRISA Admins have the following primary responsibilities:\nReview new VASP registrations and vet them for access. Administrate the certificate authority on behalf of TRISA. Provide technical support and advice to VASPs. Manage the GDS system and TestNet. This section of the documentation is specifically focused on the workflows for TRISA admins.\nAdmin UI Each network is controlled by a single GDS, which defines the peers in the network and allocates certificate authority resources (e.g. right now we have a MainNet and a TestNet that are defined by two independent GDS systems). Each GDS is managed by an administrative UI to allow TRISA admins to manage the members in the network.\nAccess to the Admin UI is limited to TRISA administrators; it is not accessible to the general public or members of the TRISA network. If you wish to view the public-facing landing page for the TRISA Global Directory Service, please visit vaspdirectory.net. If you require support accessing your TRISA administrator account to the Admin UI, please contact [email protected].\nThis documentation will be expanded in the future to include common workflows and describe the vetting process and requirements for administration via the Admin UI.",
"description": "A guide for TRISA Administrators",
"tags": [],
"title": "Administration",
"uri": "/gds/admin/index.html"
},
{
"breadcrumb": "TRISA Developer Documentation \u003e TRISA Envoy",
"content": "",
"description": "OpenAPI 3.0 specification generated documentation",
"tags": [],
"title": "API Reference",
"uri": "/envoy/openapi/index.html"
},
{
"breadcrumb": "",
"content": "TRISA Envoy: An Open Source Node TRISA has released an open source node called “Envoy” that may help your organization quickly get up and running with both the TRISA and TRP protocols. If you’re interested, schedule a demo today!\nThe goal of the Travel Rule Information Sharing Architecture (TRISA) is to enable compliance with the FATF and FinCEN Travel Rules for cryptocurrency transaction identity information without modifying core blockchain protocols, and without incurring increased transaction costs or modifying virtual currency peer-to-peer transaction flows. The TRISA protocol and specification is defined by the TRISA Working Group; to learn more about the specification, please read the current version of the TRISA whitepaper.\nThis site contains the developer documentation for the TRISA protocol and reference implementation which can be found at github.com/trisacrypto/trisa. The TRISA protocol is defined as a gRPC API to facilitate language-agnostic, high-performance, peer-to-peer services between Virtual Asset Service Providers (VASPs) that must implement Travel Rule compliance solutions. Both the API and message interchange format are defined via protocol buffers, which can be found in the protos directory of the repository. In addition, a reference implementation in the Go programming language has been made available in the pkg directory of the repository. In the future, other implementations will be made available as library code for specific languages, found in the lib directory of the repository.\nPlease visit the API Documentation for more information about the TRISA package.\nNote: Translations of this documentation are done periodically by human translators, and may become out-of-sync with the English text or reflect errors. If you notice an error, please open a bug report to notify us.",
"description": "TRISA Developer Documentation",
"tags": [],
"title": "TRISA Developer Documentation",
"uri": "/index.html"
},
{
"breadcrumb": "TRISA Developer Documentation",
"content": "",
"description": "",
"tags": [],
"title": "Categories",
"uri": "/categories/index.html"
},
{
"breadcrumb": "TRISA Developer Documentation",
"content": "",
"description": "",
"tags": [],
"title": "Tags",
"uri": "/tags/index.html"
}
]