Skip to main content

Onboard External Party Using the Admin API

This tutorial demonstrates how to onboard an external party using the Admin API. External parties can authorize Daml transactions without the need to trust any node of the network by signing transactions using a key they control. Before proceeding, it is recommended to review the external signing overview to understand the concept of external signing. Additionally, the topology tutorial provides a detailed explanation of the topology concepts used in this tutorial. The tutorial illustrates the onboarding of a party named Alice. The process can be repeated any number of times to onboard new parties.
This tutorial is for demo purposes. The code snippets should not be used directly in a production environment.

Prerequisites

For simplicity, this tutorial assumes a minimal Canton setup consisting of one participant node connected to one synchronizer (which includes both a sequencer node and a mediator node).
If you already have such an instance running, proceed to the Setup section.
This configuration is not necessary to onboard external parties per se, but will be when submitting externally signed transactions.

Start Canton

To obtain a Canton artifact refer to the getting started section. From the artifact directory, start Canton using the command:
Once the “Welcome to Canton” message appears, you are ready to proceed.

Setup

Navigate to the interactive submission example folder located at examples/08-interactive-submission in the Canton release artifact. To proceed, gather the following information by running the commands below in the Canton console:
  • Participant Id
  • Admin API endpoint
In the rest of the tutorial we’ll use the following values, but make sure to replace them with your own:
  • Participant Id: participant1::122083aecbe5b3ca3c95c7584d2e0202891f8051d39754802a156521cd1677c8e759
  • Admin API endpoint: localhost:4002

API

This tutorial interacts with the TopologyManagerWriteService, a gRPC service available on the Admin API of the participant node. See the External Signing Topology Transaction Tutorial for its definition. It uses Python to demonstrate the onboarding of an external party. It is recommended to use a dedicated python environment to avoid conflicting dependencies. Considering using venv.
Then run the setup script to generate the necessary python files to interact with Canton’s gRPC interface:
The tutorial builds up on the externally signed topology transactions tutorial by re-using some if its code and concepts. For convenience, here are the topology utility functions used in the tutorial:
Additionally, the following imports and variables are required for the rest of the tutorial:

Topology Mappings

Onboarding an external party requires three topology mappings:
  • NamespaceDelegation: Defines a root namespace for the party and registers the namespace signing key, which is used to authorize topology changes involving the party’s identity.
  • PartyToKeyMapping:
    • The protocol signing key responsible for authenticating the submission of Daml transactions to the ledger on behalf of the party.
    • A threshold (number) of keys, at least equal to the number of keys registered. At least threshold-many signatures must be obtained for a transaction submission to be authorized.
  • PartyToParticipantMapping:
    • Associates the party with one or more participant nodes, granting them confirmation rights. These rights allow participant nodes to validate Daml transactions involving the party and authorize their commitment to the ledger on behalf of the party.
    • A threshold (number) of participant node, at least equal to the number of hosting participants. At least threshold-many confirmations must be obtained from the hosting participants for a valid transaction to be authorized and committed to the ledger.
Hosting a party on more than one participant nodes for confirmation allows the party to reduce the trust put in any single node, as well as increase their overall availability on the network (e.g if a confirmation node becomes unavailable). See the Trust model for more details.

Signing Keys

Canton uses digital signatures for authentication. As shown in the previous section, two of the three required topology mappings, NamespaceDelegation and PartyToKeyMapping, are used to register the corresponding public keys for these private keys. Best practices suggest using separate signing keys for different purposes, and it is strongly recommended to use distinct key pairs for these two mappings. However, for simplicity, this tutorial will use a single key pair.

Fingerprint

Canton uses fingerprints to efficiently identify and reference signing keys. Refer to the Fingerprint section of the topology tutorial for more information.

Party ID

A Party ID is composed of two parts:
  • A human readable name, in this case: alice
  • The fingerprint of the namespace signing key, also simply called namespace

External Party Onboarding Transactions

Generate the three topology transactions necessary for the onboarding of Alice.
The build_party_to_key_transaction function is an example of how to safely build a topology transaction by first obtaining the highest serial for it unique mapping, updating the mapping’s content and incrementing the serial by 1. This ensures concurrent updates would be rejected. During onboarding of external parties however it is expected that there are no existing mappings and the serial will therefore bet set to 1.
This tutorial uses a single signing key, therefore all transactions are signed exclusively with that key (with the exception of the PartyToParticipant transaction that also needs to be signed by the hosting participant). However, in a production environment where multiple keys are used, each transaction must be signed with the appropriate keys:
  • Namespace Signing Key: All transactions must be signed by this key, as it authorizes any topology state changes involving the party.
  • PartyToKeyMapping Transaction: In addition to the namespace signing key, this transaction must be signed by all protocol signing keys it registers. This ensures the network can verify that the party has control over those keys.
  • PartyToParticipantMapping Transaction: Along with the namespace signing key, this transaction must be authorized by all hosting participants it registers.
Any change to these topology transactions requires a signature from the namespace key. No node can alter the topology state of the external party without an explicit signature from its namespace key.

Multi Transaction Hash

In order to reduce the number of signing operations required, compute a multi-transaction hash of all three transactions combined. Signing this hash allows authenticating all three transactions at once. A function to that effect is already available in the utility functions provided at the beginning of the tutorial.

Signing

First, sign the multi hash with the namespace key:
Then, build the SignedTopologyTransaction messages expected by the Topology API:

Submit

Submit the transactions signed with the external party’s key:

Authorize PartyToParticipant Mapping

The hosting participant must authorize the PartyToParticipant transaction explicitly. In this tutorial there’s only one hosting participant, so its authorization is sufficient to complete the onboarding. If there were multiple hosting participants for the marty, each would have to authorize the transaction individually. See party replication for more details.

Observe Onboarded Party

Finally, wait to observe the party in the topology, confirming it was created successfully:
Alice is now successfully onboarded and ready to interact with the ledger. Move to the next tutorial to learn how to submit externally signed transactions.

Tooling

The scripts mentioned in this tutorial can be used as tools for testing and development purposes

Onboard external party

Create an external party on the ledger and write their private and public keys to local der files. By default the synchronizer ID and participant ID will be picked up from the files written by the canton bootstrap script in this directory. They can be overridden with --synchronizer-id synchronizer_id and --participant-id participant_id.
Output:

Advanced Onboarding Topics

Multi-Hosted Party

A multi hosted party is a party hosted on more than one Participant Node. This tutorial uses a simplified setup with a single participant, however external parties can be multi-hosted. To create a multi-hosted external party, follow the tutorial above with the following two adjustments:
  • Update the PartyToParticipant topology mapping:
    • List all hosting participants (along with their permission) instead of just one
    • Adjust the confirming threshold to strike the desired tradeoff between security and availability
  • On each hosting participants, approve the PartyToParticipant transaction.
The following python function illustrates this process:
Example usage:

Offline party replication

This section only illustrates how to authorize changes to the PartyToParticipant mapping of an external party. It is NOT sufficient to fully replicate an existing party to new nodes. Follow the procedure described in the offline party replication documentation.
Offline party replication is the action of replicating an existing party to additional hosting nodes. This is a complex process described in detail in the offline party replication documentation. The procedure is similar for local and external parties, with the exception that, as established in this tutorial, changes to the topology of the external party need to be authorized explicitly with a signature of the topology transaction. Party replication involves updating the PartyToParticipant mapping of the party and therefore signing the updated transaction with the namespace key of the party. The following code demonstrates how to update the PartyToParticipant mapping for an external party via the Canton Admin API:
Example usage:
For a complete example demonstrating external party multi-hosting, check out this file:

Onboard External Party

This tutorial demonstrates how to onboard an external party using the Ledger API.

Prerequisites

This tutorial uses a script which is included as an example in the Canton artifact. Please note that the script uses openssl to create keys on the file system, which is not secure for production use. To obtain a Canton artifact refer to the getting started section. From the artifact directory, start Canton using the command:

Run The Script

The steps of this tutorial are included in the script external_party_onboarding.sh located in the examples/08-interactive-submission directory of the artifact. The steps covered by the script are:
  • Create a private key using openssl for the external party.
  • Determine the synchronizer-id available.
  • Create a set of topology transactions to define a new external party.
  • Sign the topology transactions.
  • Upload the signed topology transactions to the Ledger API.
Make sure to run the script from the same directory where you started Canton such that the script can find the canton_ports.json file which contains the port configuration of the running Canton instance, or invoke the script with the hostname and port of the Ledger API using the command line argument -p1 <host>:<port>. Once you start it, you will see:
Note that the script supports a few command line arguments, which you can see by inspecting the code.

The Details of the Script

First, the script determines the available synchronizer-ids using the v2/connected-synchronizers endpoint, assuming that there is exactly one. The party allocation must be repeated for each synchronizer-id the party should be hosted on.
Next, openssl is used to create a private Ed25519 key for the external party (other types of keys are supported as well). The public key is then extracted in DER format and convert the binary DER format to base64.
The script uses the convenience endpoint /v2/parties/external/generate-topology to generate the topology transactions required to onboard the external party. This is fine if the node is trusted. In other scenarios, the transactions should be built manually or inspected before signing, including recomputing the hash.
The convenience endpoint returns the generated topology transactions together with the computed party-id for the new party and the fingerprint of the public key. In addition, it also returns a multi-hash, which is a commitment to the entire set of transactions.
This hash needs to be signed by the private key of the new party. The script uses openssl to sign the hash and then converts the signature to base64.
Using the signature and the data from the previous step, the script submits the topology transactions and the signature to the ledger API to complete the onboarding of the new external party:
The transactions can be signed one by one, or together as one hash, as done in the script.

Onboard Multi-Hosted External Party

This tutorial demonstrates how to onboard an external party using the Ledger API which is hosted on multiple validators. It is a simple extension to the onboard external party tutorial.

Prerequisites

Make sure that you have completed the onboard external party tutorial and still have a running Canton example instance.

Run The Script

The example script used in the previous tutorial also supports onboarding a multi-hosted external party. It will onboard by default on two nodes if invoked with the --multi-hosted command line argument.

The Details of the Script

The flag --multi-hosted will pass the second participant id into the generate-topology request through the
field. This will cause the generated topology transaction to include the additional participant id in the hosting relation ship. Other options are fields such as observingParticipantUids, confirmationThreshold and more. If not configured, then the confirmation threshold will be set to the number of confirming nodes. The generated topology transactions then just need to be uploaded to the Ledger API of the second participant: “bash ALLOCATE=$(cat: You can try this out on the Canton console if you have two participants connected to the same synchronizer. In the following example, you will use the participant1 to create the hosting proposal for an internal party. This way, you don’t need to deal with creating signatures for the topology transactions externally. The approval of the proposal will be done using participant2. First, create a hosting proposal using participant1:
Then, list the proposals on participant2. The new proposal should appear shortly:
This will show the pending proposal, awaiting the signature of the second participant. The proposal is identified by the transaction hash txHash, which can be obtained from the output of the previous command:
Authorize the proposal using the console command topology.transactions.authorize:
This will add the signature of participant2 to the proposal. Because the proposal is now fully signed, the party will appear as being hosted on both nodes: