# Securosys Primus HSM integration guide

This guide provides complete instructions for integrating Securosys Primus HSM with Ripple Custody. The Securosys Primus HSM is a **FIPS 140-2 Level 3** certified hardware security module that generates, manages, and protects cryptographic keys. Securosys is currently pursuing **FIPS 140-3 Level 3** certification.

**Note:** Securosys and Ripple have a partnership that allows customers to access either Securosys Primus HSMs or CloudHSMs under the Ripple contract. Interested customers should contact their customer partner success director for more information.

**Before you begin:** This guide assumes you have completed [Installation environment setup](/products/custody/v1.36/deployment/install/helm-chart-installation) and are ready to configure your HSM for use with Ripple Custody.

## Overview

### How Ripple Custody uses Securosys Primus HSM

**Key-generation flow**:

1. During account creation, the vault requests key generation from the HSM.
2. The HSM creates three master keys, one for each elliptic curve.
3. The HSM encrypts the private key using its master key via PKCS#11.
4. Ripple Custody stores the encrypted private key (PKCS#11 blob) in its database.
5. During signing operations, the HSM performs all private key operations internally.
6. Unencrypted (plaintext) private keys never leave the HSM.


### Deployment architecture


```mermaid
flowchart TB
    subgraph compute["Compute"]
        direction LR
        notary["Notary + KMS Connect"]
        vault["Vault + KMS Connect"]
    end

    subgraph hsm["Securosys Primus HSM HA Group"]
        direction LR
        p1["Partition #1"]
        p2["Partition #2"]
        p1 <--> p2
    end

    notary -->|mTLS port 2410| hsm
    vault -->|mTLS port 2410| hsm
```

## Prerequisites

### Hardware and software requirements

Before starting, ensure you have:

**From Securosys HSMs**:

- Securosys Primus HSM appliance deployed.
- HSM initialized with admin credentials.
- Network connectivity on port **2410** (typical).


**From your infrastructure**:

- Linux client machine for HSM administration.
- Securosys Primus PKCS#11 API Provider client software downloaded and installed.
- Network access from the chosen compute infrastructure to the HSM.
- Firewall rules allowing bidirectional traffic from Kubernetes nodes to HSM.


**From Ripple**:

- Ripple Custody Helm charts (version 1.30+)
- Access to the Ripple container registry (`metaco.azurecr.io`)


### Key derivation scheme

The vault automatically detects the HSM capabilities at startup and selects the appropriate derivation scheme. For Securosys Primus HSM, use only SLIP10.

| Scheme | Supported Curves | Supported Blockchains | Firmware Required |
|  --- | --- | --- | --- |
| **SLIP10** | secp256k1, Ed25519 | All blockchains (Bitcoin, Ethereum, XRPL, Solana, Algorand, etc.) | v2.11.0+ |


### Documentation references (Securosys)

- [Primus HSM Configuration](https://docs.securosys.com/pkcs/Installation/primus_hsm_settings)
- [PKCS#11 API Provider Installation](https://docs.securosys.com/pkcs/Installation/pkcs11_provider_installation)
- [PKCS#11 API Provider Configuration](https://docs.securosys.com/pkcs/Installation/pkcs11_provider_configuration/)
- [Permanent Secret Fetching](https://docs.securosys.com/pkcs/Installation/permanent_secret_management/)
- [Cluster Synchronization](https://docs.securosys.com/cloudhsm/Architecture/cluster_synchronization/)
- [Backups](https://docs.securosys.com/cloudhsm/Architecture/backups/)


## HSM initialization

This section covers the vendor-specific setup required to prepare your Securosys Primus HSM for use with Ripple Custody. Detailed step-by-step commands are available in the [Securosys Primus HSM documentation](https://docs.securosys.com/pkcs/Installation/primus_hsm_settings).

**Customer responsibility**: Your infrastructure team performs HSM initialization. You must configure the HSM with the settings described below before proceeding to Ripple Custody configuration.

### Step 1: Deploy and initialize Securosys Primus HSM appliance

Complete the following using Securosys Primus documentation:

1. **Physical deployment**: Rack, power, and network-connect the Securosys Primus HSM appliance
2. **Initial setup**: Complete the Initial Wizard as described in [Chapter 3 of the Primus HSM User Guide](https://support.securosys.com/external/knowledge-base/article/63).
3. **Firmware verification**: For the most robust support (including SLIP10), and compliance (including FIPS/CC considerations), firmware **2.11+** or **3.1+** (for X2/E2-series hardware) is recommended.


### Step 2: Configure the HSM

Follow the steps in [Primus HSM Configuration](https://docs.securosys.com/pkcs/Installation/primus_hsm_settings).

The Primus PKCS#11 API Provider has two main configuration files:

- */etc/primus/primus.cfg* contains public settings, such as connectivity details (hostname, port) and partition names.
- */etc/primus/.secrets.cfg* contains secret values, such as the permanent secret used to authenticate to the HSM.


Here is a template *primus.cfg* configuration file:


```cpp
#-----------------------------
# Primus PKCS#11 configuration
#-----------------------------
version = "1.0";
/* This example configuration template contains 1 slot:                    */
/* hsm0: standalone hsm with one partition (slot id 0)                     */
/*--- GLOBAL CONFIGURATION SECTION ----------------------------------------*/
primus:
{
  wait_delay = 250; /* in ms*/
  wait_max_tries = 5;
  connect_on_init = true;
  /*--- HSM CONFIGURATION SECTION -----------------------------------------*/
  hsms:
  {
     /*--- HSM0, e.g. standalone hsm with one partition, slot id 0 */
     hsm0:
     {
        host = "grimsel.securosys.ch";
        port = "2410";
        priority = 0; /* Optional priority. Default 0, which is highest priority */
        slots:
        {
           slot0:
           {
              client_id = "Client_ID0"; /* Client-supplied, determined by us */
              user_name = "PRIMUSDEV390"; /* partition/slot name */
              id = 0;
           }; /* end slot0 */
        }; /* end slots */
     }; /* end hsm0 */
  }; /* end hsms */
  /*--- LOG CONFIGURATION SECTION -----------------------------------------*/
  log:
  {
/*    file = "/tmp/primus.log";    /* optional for unix, logs to LOCAL1 syslog */
/*    file = "%PUBLIC%\Securosys\Primus P11\primus.log";  /* for windows */
    write_log_file      = true;     /* write to log-file */
    write_syslog        = true;     /* write to syslog */
    trace_linenumber    = false;    /* true or false */
    trace_timestamp     = true;     /* true or false */
    trace_function      = true;     /* true or false */
    trace_inout         = false;    /* true or false */
    trace_pid           = true;     /* true or false */
    trace_filename      = false;    /* true or false */
    trace_mask          = 0x00;
    trace_level         = 4;        /* 0-7 log level details */
  }; /* end log */
}; /* end primus */
```

Here is a template *.secrets.cfg* configuration file:


```cpp
version = "1.0";
primus :
{
  users :
  {
    user0 :
    {
      name = "PRIMUSDEV390"; /* partition name */
      secret = "<hex_secret>";
    };
  };
};
```

### Step 3: Fetch permanent secret

To authenticate to Securosys Primus HSMs, you must generate a *permanent secret* in addition to the PIN. Use the Securosys-provided `ppin` tool with a temporary setup secret:


```bash
$ ppin -a -e HSM_USERNAME <SETUP_PASSWORD> <PIN>
```

Note that this requires write access to */etc/primus/.secrets.cfg*.

For more information, see [Permanent Secret Fetching](https://docs.securosys.com/pkcs/Installation/permanent_secret_management/)

### Step 4: Configure high availability (HA) groups

HA groups provide redundancy by synchronizing keys across multiple HSM partitions. If one HSM fails, the other continues to provide cryptographic services.

You can run Securosys Primus HSMs in a partition-synced cluster for HA. This configuration makes the partition keys available on each instance and allows you to clone them for backup.

For more information, see [Primus HSM - High Availability Cloning](https://docs.securosys.com/primus-hsm/Concepts/ha_cloning).

### Step 5: Configure network access and mTLS

**Network ACL**: Add the IP range for your PKCS#11 client(s) to the HSM's network ACL, using `network add`.

### Step 6: Verify HSM connectivity

Before proceeding to Ripple Custody configuration, verify:

1. **Network connectivity**: Port 2410 is reachable from PKCS#11 client application
2. **PKCS#11 connectivity**: `ppin --test` tests connectivity to your defined HSMs and partitions (see [Connection Test](https://docs.securosys.com/pkcs/Tutorials/ppin_tool#connection-test))
3. **Authentication**: Can login to partitions with configured PIN and permanent secret fetched in Step 3.
4. **Cryptographic operations**: Basic operations execute without errors


**Checkpoint:** If `ppin --test` shows your HSMs, and you can successfully login to partitions, your Securosys Primus HSM is properly configured and ready for Ripple Custody integration.

## Ripple Custody configuration

Now that your Securosys Primus HSM is initialized, configure Ripple Custody to use it for the notary and vault components.

### Step 1: Gather the configuration information

Make sure you have the necessary configuration information:

- **PIN code**
- **Permanent secret**
- **HSM hostname** (one or more)
- **HSM port** (typically **2410**)
- **Partition name** (only one partition name, as this partition is to be cloned to the other HSMs as part of HA configuration)


### Step 2: Configure notary with Securosys Primus HSM

The following is an example *production.yaml* file for a Kubernetes environment using the simplified configuration Custodian Chart.

You need to:

1. Declare the HSMS list, and their network address and relative priorities.
2. Declare the partition name.
3. (If you are an existing Kubernetes Secret user), declare before installation.



```yaml
# production.yaml

notary:
  install: true
  bridge:
    endpoint: "https://foo.bar"
  kms:
    kind: "primus"
    existingSecret: "primus-secret"
    primus:
      hsms:
        - host: "grimsel.securosys.ch"
          port: 2410
          priority: 0
      haGroup:
        - member: "PRIMUSDEV390"
```

**Security best practice:** Do NOT store the partition PIN directly in `production.yaml`. Use Kubernetes Secrets or an external secrets manager (HashiCorp Vault, Conjur) to inject the PIN at runtime.

### Step 3: Configure vault with Securosys Primus HSM

Configure the vault component to use Securosys Primus HSM for key encryption. As with the notary, you need to:

1. Declare the HSMS list, and their network address and relative priorities.
2. Declare the partition name.
3. (If you are an existing Kubernetes Secret user), declare before installation.



```yaml
# production.yaml

vault:
  install: true
  http:
    endpoint: "https://foo.bar"
  kms:
    kind: "primus"
    existingSecret: "primus-secret"
    primus:
      hsms:
        - host: "grimsel.securosys.ch"
          port: 2410
          priority: 0
      haGroup:
        - member: "PRIMUSDEV390"
```

**Using Kubernetes Secrets for vault PIN**:


```bash
# Create secret for Vault PIN (same partition as Notary)
kubectl create secret generic primus-secret \
  --namespace custody-vault \
  --from-literal=pin='partition-password'
```

## Verification and testing

After configuring your Helm values, do the following to verify the integration.

1. Verify that the application starts successfully with no errors and no crashes during init.
2. Check the KMS log messages.


With Securosys Primus HSM, the startup log should look somewhat like the following:


```log
{"date":1769688916.132,"time":"2026-01-29 12:15:16.132","app":"kms-server[1:1]","level_int":"6","function":"loadConfig()","message":"Log configuration - Tracing: 'Parameters'"}
{"date":1769688916.403,"time":"2026-01-29 12:15:16.403","app":"kms-server[1:1]","level_int":"5","function":"C_Initialize()","message":"rv: CKR_OK"}
{"date":1769688916.403,"time":"2026-01-29 12:15:16.403","app":"kms-server[1:1]","level_int":"5","function":"C_GetSlotList()","message":"rv: CKR_OK"}
{"date":1769688916.403,"time":"2026-01-29 12:15:16.403","app":"kms-server[1:1]","level_int":"5","function":"C_GetSlotList()","message":"rv: CKR_OK"}
{"date":1769688916.439,"time":"2026-01-29 12:15:16.439","app":"kms-server[1:1]","level_int":"5","function":"C_GetTokenInfo()","message":"rv: CKR_OK"}
{"date":1769688916.439,"time":"2026-01-29 12:15:16.439","app":"kms-server[1:1]","level_int":"5","function":"C_OpenSession()","message":"rv: CKR_OK"}
{"date":1769688916.471,"time":"2026-01-29 12:15:16.471","app":"kms-server[1:1]","level_int":"5","function":"C_Login()","message":"rv: CKR_OK"}
```

## Troubleshooting

See [PKCS#11 Troubleshooting](https://docs.securosys.com/pkcs/Tutorials/troubleshooting/).

## Production best practices

See **[Production best practices](/products/custody/v1.36/deployment/integrate-kms/production-best-practices)** for detailed instructions that apply to all KMS platforms.

For production-ready Securosys Primus HSM deployments, implement the following patterns.

### Securosys Primus HSM-specific considerations

| Practice | Securosys Primus HSM Implementation |
|  --- | --- |
| **High Availability** | Configure Securosys Primus HA groups with `hagroup createGroup` and add multiple HSM members |
| **Namespace Segmentation** | One partition per application (Ripple Custody) per environment (to ensure the partition master keys differ between environments) |
| **Backup** | Use `partition backup` command, store backups securely, test quarterly |
| **HA Sync** | Regularly verify HA group synchronization with `hagroup synchronize` |


**Securosys Primus HSM HA group configuration**:

- Use `hagroup createGroup` to create HA groups for notary and vault partitions
- Configure `HAOnly = 1` in `Chrystoki.conf` to ensure operations only use HA groups
- Set `VirtualTokenActiveRecovery = activeEnhanced` for automatic failover -->


## Next steps

After successfully integrating Securosys Primus HSM with Ripple Custody:

1. **Backup HSM keys**: Implement backup procedures for SKS master keys.
  - Back up SMK to a secondary Securosys Primus HSM
  - Store backup HSM in secure, off-site location
  - Document recovery procedures
2. **Production hardening**:
  - Enable HSM audit logging
  - Configure HSM monitoring and alerting
  - Implement HSM access controls (role-based access)
  - Schedule regular HSM firmware updates
3. **Disaster recovery planning**:
  - Document HSM replacement procedures
  - Test HA failover scenarios
  - Create runbooks for common HSM issues
  - Establish HSM vendor support contacts
4. **Security audit**:
  - Review HSM policies and partition configurations
  - Verify network ACLs are restrictive
  - Test backup and recovery procedures
5. **Review [Production best practices](/products/custody/v1.36/deployment/integrate-kms/production-best-practices)** for namespace segmentation, HA patterns, and monitoring


**Congratulations!** You have successfully integrated Securosys Primus HSM with Ripple Custody. Your notary and vault components are now protected by FIPS 140-2 Level 3 certified hardware security.