Installation
This guide shows how to integrate the Canton Network Wallet Gateway with a Securosys Primus HSM or CloudHSM using the signing-securosys driver.
Prerequisites
Before you start, you need the following:
- A Securosys Primus HSM or CloudHSM partition reachable through a Transaction Security Broker instance.
- TSB credentials for that partition: API keys, a JWT bearer token, an mTLS client certificate, or a combination of these. See API Authentication.
- A host with Node.js 20 or newer and pnpm 11.
- A Canton participant or validator node the Wallet Gateway can reach. The wallet repository can start a local Canton node for evaluation.
Obtain the Wallet Gateway
Clone the Canton Network wallet repository and install its dependencies:
git clone https://github.com/canton-network/wallet.git
cd wallet && corepack enable pnpm && pnpm install
The Securosys driver is part of the monorepo at
core/signing-securosys
and is built together with the rest of the workspace. Nothing has to be installed separately.
If you run your own Wallet Gateway build instead of the reference one, add the published package:
pnpm add @canton-network/core-signing-securosys
Prepare TSB Access
The driver talks to two groups of TSB endpoints, each protected by its own role:
| Role | Used for | Configured as |
|---|---|---|
Key Management (keyManagementToken) | Creating, renaming, and reading keys | SECUROSYS_TSB_KEY_MANAGEMENT_API_KEY |
Key Operation (keyOperationToken) | Signing and reading request status | SECUROSYS_TSB_KEY_OPERATION_API_KEY |
Authentication methods can be combined. Use whichever your TSB deployment is configured for:
- API keys: On-premise TSB with
apiAuthenticationenabled. See Configure API Keys. - JWT bearer token: The default for CloudHSM, where a JWT identifies the partition.
- mTLS: PKCS#12 client certificate presented to TSB. See Configure mTLS.
Give the Wallet Gateway a dedicated HSM Partition. The Wallet Gateway can enumerate, read, and use all keys stored on the Partition. Use SKA for per-key authorization control.
Configure the Signing Driver
The remote Wallet Gateway reads its Securosys configuration from environment variables:
| Environment variable | Required | Description |
|---|---|---|
SECUROSYS_TSB_BASE_URL | Yes | Base URL of the TSB service. If unset, the Securosys signing provider is not registered. |
SECUROSYS_TSB_KEY_MANAGEMENT_API_KEY | Conditional | X-API-KEY for the /v1/key endpoints. |
SECUROSYS_TSB_KEY_OPERATION_API_KEY | Conditional | X-API-KEY for signing and request status endpoints. |
SECUROSYS_TSB_BEARER_TOKEN | Conditional | JWT access token, sent as Authorization: Bearer. |
SECUROSYS_TSB_MTLS_P12_PATH | Conditional | Path to the PKCS#12 client certificate when TSB requires mTLS. |
SECUROSYS_TSB_MTLS_P12_PASSWORD | Conditional | Password for that PKCS#12 file. |
SECUROSYS_TSB_KEY_PASSWORD | No | TSB key password, used for key attributes and signing. |
SECUROSYS_TSB_SIGNATURE_ALGORITHM | No | TSB signature algorithm. Defaults to EDDSA. |
At least one authentication method must be configured; which of the conditional variables you set depends on how your TSB instance authenticates clients.
Canton external-party signatures are Ed25519. Leave SECUROSYS_TSB_SIGNATURE_ALGORITHM at its
default EDDSA unless you have a specific reason to change it — other algorithms produce
signatures the ledger rejects.
For a custom Gateway build, pass the same values to the driver constructor:
import SecurosysSigningDriver from '@canton-network/core-signing-securosys'
const driver = new SecurosysSigningDriver({
baseUrl: 'https://sbx-rest-api.cloudshsm.com',
keyManagementApiKey: process.env.TSB_KEY_MANAGEMENT_API_KEY,
keyOperationApiKey: process.env.TSB_KEY_OPERATION_API_KEY,
mtlsP12Path: process.env.TSB_MTLS_P12_PATH,
mtlsP12Password: process.env.TSB_MTLS_P12_PASSWORD,
})
The same settings can be inspected and changed at runtime through the Gateway configuration RPC,
using the PascalCase property names BaseURL, KeyManagementApiKey, KeyOperationApiKey,
BearerToken, MtlsP12Path, MtlsP12Password, KeyPassword, and SignatureAlgorithm.
Secret values are returned masked.
Start the Wallet Gateway
For an evaluation setup, fetch and start a local Canton node:
pnpm script:fetch:canton
pnpm start:canton --network=devnet
Wait for the Canton bootstrap to finish. The command can then be interrupted with Ctrl+C;
the node keeps running under PM2.
Start the wallet stack with your TSB settings. With mTLS:
SECUROSYS_TSB_BASE_URL=https://tsb.example.com SECUROSYS_TSB_MTLS_P12_PATH=./etc/client_mtls_tsb.p12 SECUROSYS_TSB_MTLS_P12_PASSWORD=<password> pnpm start:all
With a JWT bearer token:
SECUROSYS_TSB_BASE_URL=https://sbx-rest-api.cloudshsm.com SECUROSYS_TSB_BEARER_TOKEN=<JWT> pnpm start:all
Check that the Gateway is up:
curl -i http://localhost:3030/healthz
If SECUROSYS_TSB_BASE_URL is missing, the Gateway logs
Securosys TSB base URL not set — Securosys signing provider will be unavailable
and starts without the provider.
Create a Wallet
Open the Wallet Gateway UI at http://localhost:3030, create a new wallet, and select
Securosys as the signing provider.
Confirm that the key was created in the HSM by listing the keys on the Partition:
curl -s https://sbx-rest-api.cloudshsm.com/v1/key --header "X-API-KEY: ${TSB_KEY_MANAGEMENT_API_KEY}"
The new key appears under a label that is the base64url encoding of the wallet's raw Ed25519 public key.
If the wallet stays in status initialized, the topology transaction is still waiting on the TSB or HSM.
In this case, check the request status, and the pending approval tasks if an SKA policy is in place.
Key material
Keys created by the driver use these TSB parameters:
| Parameter | Value |
|---|---|
algorithm | ED |
curveOid | 1.3.101.112 (Ed25519) |
attributes | sign: true, verify: true, decrypt: false, unwrap: false, extractable: false, modifiable: true, destroyable: true |
policy | Empty SKA policy — no approval rules, key not blocked |
The key is created under a temporary wallet-{uuid} label and renamed once TSB returns the
public key. The final label is the base64url form of the normalized 32-byte public key, which
makes it deterministic, collision-free across users and networks, and resolvable without
scanning the partition. TSB Ed25519 public keys returned in SPKI form are reduced to the raw
32-byte key the Wallet Gateway expects.
Sign a Transaction
Submit a transaction from a dApp, or from the wallet UI, for the party you just created. The Gateway sends the prepared transaction hash to TSB, polls for the result, and submits the signed transaction to the ledger.
You can query a request's status to follow its progress:
curl -s https://sbx-rest-api.cloudshsm.com/v1/request/${REQUEST_ID} --header "X-API-KEY: ${TSB_KEY_OPERATION_API_KEY}"
A successful request reports status EXECUTED and returns the signature in result.
Sign requests
Sign requests are sent with payloadType UNSPECIFIED and signatureType RAW, so TSB returns
a raw 64-byte Ed25519 signature. The metaData field carries a base64-encoded JSON object with
the internal transaction id, the user identifier, the key identifier, and the signature algorithm
and type — this is the information shown to approvers when an SKA policy applies.