Skip to content

This guide provides complete instructions for integrating BlockSafe HSM with Ripple Custody. BlockSafe is a blockchain-optimized hardware security module designed specifically for cryptocurrency key management and signing operations.

Before you begin: This guide assumes you have completed Installation environment setup and have BlockSafe HSM hardware deployed and accessible from your Kubernetes cluster.


Overview

How Ripple Custody uses BlockSafe HSM

Ripple Custody uses BlockSafe HSM with a key derivation approach similar to Thales Luna HSM:

  1. Master key creation: The master key is created inside the HSM during the key ceremony when creating HSM slots.
  2. Key derivation: vault derives account keys from master seed using BIP32/SLIP10.
  3. Signing operations: All private key operations performed inside HSM.
  4. Key protection: Private keys never leave the HSM in plaintext.

Key Management Flow:

Notary Initialization:
1. Notary connects to BlockSafe HSM
2. Master key generated inside HSM
3. Public key exported for Vault configuration

Account Creation:
1. Vault connects to BlockSafe HSM
2. Vault derives account key from master seed (BIP32/SLIP10)
3. Public key exported for blockchain operations

Signing Operation:
1. Transaction data sent to Vault
2. Vault requests signature from BlockSafe HSM
3. HSM performs signing operation with derived key
4. Signature returned to Vault
5. Signed transaction broadcast to blockchain

Deployment architecture

PKCS#11 port 3001

PKCS#11 port 3001

BlockSafe HSM

Slot 0: Notary Keys

Slot 1: Vault Keys

Kubernetes Cluster

Notary + KMS Connect

Vault + KMS Connect

PKCS#11 port 3001

PKCS#11 port 3001

BlockSafe HSM

Slot 0: Notary Keys

Slot 1: Vault Keys

Kubernetes Cluster

Notary + KMS Connect

Vault + KMS Connect


Prerequisites

Hardware requirements

BlockSafe HSM Appliance:

  • BlockSafe HSM appliance deployed and powered on
  • Network connectivity from Kubernetes cluster to HSM
  • HSM initialized with admin credentials
  • At least 1 slot configured (one slot per application is sufficient)

Network requirements:

  • TCP connectivity to BlockSafe HSM on configured port (typically 3001)
  • Low latency network connection (< 10ms recommended)
  • Firewall rules allowing traffic from Kubernetes nodes to HSM

Software requirements

From BlockSafe:

  • BlockSafe HSM firmware (latest stable version)
  • PKCS#11 library (provided by BlockSafe)
  • Admin tools for HSM management

From Ripple:

  • Ripple Custody Helm charts
  • Access to Ripple container registry (provided by Ripple)

Network requirements

Connectivity:

  • TCP access to BlockSafe HSM on configured port (default: 3001)
  • Bidirectional network connectivity
  • No NAT or proxy between Kubernetes and HSM (recommended)

Firewall rules:

Source: Kubernetes cluster CIDR (e.g., 10.0.0.0/16)
Destination: BlockSafe HSM IP (e.g., 192.168.1.100)
Port: 3001 (or custom port)
Protocol: TCP
Direction: Outbound from Kubernetes

HSM initialization

This section covers the BlockSafe-specific setup required to prepare your HSM for Ripple Custody integration. Consult your BlockSafe documentation for model-specific instructions.

Customer responsibility: Your infrastructure team performs HSM initialization. Ripple Custody only requires that the HSM be configured with the settings described below before proceeding to Ripple Custody configuration.

Step 1: Deploy and initialize BlockSafe HSM

Complete the following using BlockSafe documentation:

  1. Physical deployment: Rack-mount, power, and network-connect the BlockSafe HSM appliance
  2. Network configuration: Assign a static IP address accessible from your Kubernetes cluster (default port: 3001)
  3. HSM initialization: Set Security Officer (SO) PIN and create admin user
  4. Set HSM label: Use a descriptive label (e.g., "RippleCustodyHSM").

Step 2: Configure HSM slot

Create a dedicated PKCS#11 slot for Ripple Custody:

SlotPurposeLabel Example
Slot 0Ripple CustodyCustodySlot

For the slot:

  • Create the slot with a descriptive label
  • Set a strong PIN for slot access
  • One slot per application is the standard design
  • Document credentials securely

CRITICAL: Save slot PINs securely. Loss of slot PINs will prevent access to keys stored in the HSM. BlockSafe cannot recover lost PINs.

Step 3: Enable required policies

Enable the following policies for Ripple Custody operations (policy names may vary by model):

PolicyPurpose
BIP32Key derivation for blockchain accounts
SLIP10Alternative key derivation scheme
Key wrappingRequired for backup operations

Consult your BlockSafe documentation for exact policy names and configuration procedures.

Step 4: Verify HSM connectivity

Before proceeding to Ripple Custody configuration, verify:

  1. Network connectivity: Port 3001 (or configured port) is reachable from Kubernetes nodes
  2. PKCS#11 connectivity: pkcs11-tool --list-slots shows your configured slots
  3. Authentication: Can login to slots with configured PINs

Step 5: Document configuration

Record the following information for Ripple Custody configuration:

ParameterValueExample
HSM IP AddressBlockSafe HSM IP192.168.1.100
HSM PortPKCS#11 port3001
Device StringFormat: port@hostname3001@192.168.1.100
Notary slotSlot number for notary0
Notary PINSlot 0 PIN(stored securely)
Vault slotSlot number for vault1
Vault PINSlot 1 PIN(stored securely)

Checkpoint: If you can successfully list slots and authenticate using PKCS#11 tools, your BlockSafe HSM is properly configured and ready for Ripple Custody integration.


Ripple Custody configuration

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

Step 1: Gather required information

You'll need the following information from your BlockSafe HSM setup:

ParameterDescriptionExample
DeviceHSM address in port@hostname format3001@192.168.1.100
SlotSlot number for Ripple Custody0
PINSlot PINSlotSecurePin123!

Step 2: Configure notary with BlockSafe HSM

Edit your production.yaml Helm values file:

# production.yaml

components:
  notary:
    enabled: true

    # Platform selection
    platform: kms_blocksafe

    # BlockSafe HSM configuration
    kms_blocksafe:
      device: "3001@192.168.1.100"  # Format: port@hostname
      slot: 0
      pin: "SlotSecurePin123!"

Security best practice: Do NOT store PINs directly in production.yaml. Use Kubernetes Secrets to inject credentials at runtime.

Using Kubernetes Secrets:

# Create secret for Notary credentials
kubectl create secret generic notary-blocksafe-credentials \
  --namespace custody-core \
  --from-literal=device='3001@192.168.1.100' \
  --from-literal=slot='0' \
  --from-literal=pin='SlotSecurePin123!'

Update production.yaml to reference the secret:

components:
  notary:
    enabled: true
    platform: kms_blocksafe
    kms_blocksafe:
      secretRef: "notary-blocksafe-credentials"

Step 3: Configure vault with BlockSafe HSM

# production.yaml

harmonize:
  vaults:
    "00000000-0000-0000-0000-000000000000":
      enabled: true

      # Platform selection
      platform: kms_blocksafe

      # Notary public key (obtained after Notary initialization)
      notary_public_key: "ed25519:50692dfa472f013e2f87e5d210be40cefe178e33787be4688d5da0afe06ed149"

      # BlockSafe HSM configuration (uses same slot as Notary)
      kms_blocksafe:
        device: "3001@192.168.1.100"
        slot: 0  # Same slot as Notary (one slot per application)
        pin: "SlotSecurePin123!"

Using Kubernetes Secrets for vault:

# Create secret for Vault credentials (same slot as Notary)
kubectl create secret generic vault-blocksafe-credentials \
  --namespace custody-vault \
  --from-literal=device='3001@192.168.1.100' \
  --from-literal=slot='0' \
  --from-literal=pin='SlotSecurePin123!'

Update production.yaml:

harmonize:
  vaults:
    "00000000-0000-0000-0000-000000000000":
      enabled: true
      platform: kms_blocksafe
      notary_public_key: "ed25519:${NOTARY_PUBLIC_KEY}"
      kms_blocksafe:
        secretRef: "vault-blocksafe-credentials"

Step 4: Complete configuration example

# production.yaml - Complete BlockSafe HSM Configuration

# Global settings
harmonize:
  repository:
    base: "my-registry.example.com/harmonize"

  urls:
    base: "custody.example.com"
    tls: true

# Notary configuration
components:
  notary:
    enabled: true
    platform: kms_blocksafe
    kms_blocksafe:
      secretRef: "custody-blocksafe-credentials"
      # Or inline configuration (not recommended for production):
      # device: "3001@192.168.1.100"
      # slot: 0
      # pin: "${SLOT_PIN}"

# Vault configuration (uses same slot as Notary)
harmonize:
  vaults:
    "00000000-0000-0000-0000-000000000000":
      enabled: true
      platform: kms_blocksafe
      notary_public_key: "ed25519:${NOTARY_PUBLIC_KEY}"
      kms_blocksafe:
        secretRef: "custody-blocksafe-credentials"
        # Or inline configuration (not recommended for production):
        # device: "3001@192.168.1.100"
        # slot: 0  # Same slot as Notary
        # pin: "${SLOT_PIN}"

Advanced secret management

For production deployments, store sensitive credentials (PKCS#11 PIN, slot ID) in an external secrets manager rather than directly in Helm values or Kubernetes secrets.

Production best practice: Never store sensitive credentials in plaintext YAML files or Git repositories.

Recommended approaches for BlockSafe HSM credentials:

ApproachDescriptionUse Case
External Secrets Operator (ESO)Sync secrets from HashiCorp Vault, AWS Secrets Manager, or Azure Key Vault to KubernetesEnterprise environments with centralized secret management
HashiCorp Vault Agent InjectorInject secrets directly into pods at runtimeOrganizations already using Vault Agent
AWS Secrets ManagerStore and rotate secrets in AWSAWS-native deployments

For complete setup instructions, see the Advanced secret management guide.

When using external secret management, reference the secret in your Helm values:

components:
  notary:
    platform: kms_blocksafe
    kms_blocksafe:
      existingSecret: "notary-blocksafe-credentials"  # ESO-managed secret

Verification and testing

Step 1: Deploy notary component

# Deploy notary first
helm upgrade --install harmonize ./harmonize-custody \
  --namespace custody-core \
  --create-namespace \
  -f production.yaml \
  --set components.vault.enabled=false

# Wait for Notary to be ready
kubectl wait --for=condition=ready pod \
  -l app=notary \
  -n custody-core \
  --timeout=300s

Step 2: Verify BlockSafe HSM connectivity

# Check KMS Connect logs
kubectl logs -n custody-core deployment/harmonize-notary -c kms-connect --tail=100

# Expected log entries:
# - "Connected to BlockSafe HSM"
# - "PKCS#11 session established"
# - "Slot 0 authenticated"

# Test network connectivity from pod
kubectl exec -it -n custody-core deployment/harmonize-notary -c kms-connect -- \
  nc -zv 192.168.1.100 3001

# Expected output:
# Connection to 192.168.1.100 3001 port [tcp/*] succeeded!

Step 3: Initialize notary and retrieve public key

# Initialize Notary via Genesis API
curl -X POST https://api.custody.example.com/v1/genesis \
  -H "Content-Type: application/json" \
  -d @genesis.json

# Retrieve the notary communication key from system properties
curl https://api.custody.example.com/v1/properties \
  -H "Authorization: Bearer ${ACCESS_TOKEN}" \
  | jq '.items[] | select(.data.id == "NOTARY_COMMUNICATION_KEY") | .data.value.publicKey.value'

# Example output:
# "MFYwEAYHKoZIzj0CAQYFK4EEAAoDQgAE..."

Step 4: Deploy vault component

Update production.yaml with notary public key, and deploy vault:

helm upgrade --install harmonize ./harmonize-custody \
  --namespace custody-core \
  -f production.yaml

kubectl wait --for=condition=ready pod \
  -l app=vault \
  -n custody-vault \
  --timeout=300s

Step 5: Create test account

All state mutation custody operations, including account creation, go through the signed intent flow. Verifying that the BlockSafe HSM can derive keys means submitting a v0_CreateAccount intent that targets the vault you just deployed. For the complete intent lifecycle (propose, sign, submit, poll), see Intent lifecycle.

The minimal request body for the create-account intent looks like this:

{
  "request": {
    "author": { "id": "<your-user-id>", "domainId": "<your-domain-id>" },
    "expiryAt": "2027-12-31T23:59:59Z",
    "targetDomainId": "<your-domain-id>",
    "id": "<fresh-uuid>",
    "customProperties": {},
    "description": "BlockSafe HSM verification — test account",
    "type": "Propose",
    "payload": {
      "type": "v0_CreateAccount",
      "id": "<fresh-uuid>",
      "alias": "blocksafe-test",
      "description": "Account to verify BlockSafe HSM key derivation",
      "customProperties": {},
      "providerDetails": {
        "type": "Vault",
        "vaultId": "<vault-uuid-from-step-4>",
        "keyStrategy": "VaultHard"
      },
      "ledgerIds": ["xrpl-testnet"],
      "lock": "Unlocked"
    }
  },
  "signature": "<base64 signature over the canonicalized request>"
}

Submit it:

curl -X POST https://api.custody.example.com/v1/intents \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer ${ACCESS_TOKEN}" \
  -d @intent_body.json

A successful response returns a requestId. Poll GET /v1/domains/{domainId}/requests/{requestId} until the status reaches a terminal state. Executed confirms:

  1. The vault component can communicate with the BlockSafe HSM via PKCS#11.
  2. Key derivation (BIP32/SLIP10) succeeded for the requested ledger.
  3. Account keys were generated and persisted.

Step 6: Test signing operation

Submit a v0_CreateTransactionOrder intent against the account from Step 5 to exercise the full HSM signing path (the HSM signs the blockchain transaction bytes, not just the intent envelope). See the Create transaction order reference and the intent lifecycle walkthrough for the full payload shape.

Use POST /v1/intents/dry-run first to validate without committing state. If the dry-run returns success: true, submit the same payload to POST /v1/intents and poll the resulting requestId until terminal. Executed confirms:

  1. The vault performs blockchain-level signing via the BlockSafe HSM.
  2. The PKCS#11 signing interface produces signatures the target ledger accepts.
  3. The end-to-end transaction flow — propose, sign, broadcast, finalize — is functional.

Troubleshooting

Error MessageCauseSolution
CKR_DEVICE_ERRORHSM not accessibleCheck network connectivity and device string format (port@hostname)
CKR_PIN_INCORRECTWrong PINVerify PIN in Kubernetes secret matches slot PIN
CKR_SLOT_ID_INVALIDInvalid slot numberVerify slot exists and is initialized
CKR_SESSION_HANDLE_INVALIDSession timeoutRestart KMS Connect pod
CKR_FUNCTION_NOT_SUPPORTEDUnsupported operationCheck firmware version and policies
Connection refusedHSM port not accessibleCheck firewall rules and HSM status (default port: 3001)

For detailed troubleshooting, consult your BlockSafe HSM documentation or contact BlockSafe support.


Production best practices

For production-ready BlockSafe HSM deployments, implement the following patterns. See the Production best practices guide for detailed instructions that apply to all KMS platforms.

BlockSafe HSM-specific considerations

PracticeBlockSafe HSM Implementation
High availability (HA)Configure BlockSafe HSM in cluster mode with multiple appliances across racks/locations.
Namespace segmentationSeparate PKCS#11 slots per namespace/vault for isolation.
MonitoringUse pkcs11-tool commands (--show-info, --list-slots, --list-objects) plus Prometheus metrics.
BackupExport PKCS#11 objects from slots, store backups securely, and test quarterly.

BlockSafe HSM Clustering:

  • Deploy multiple HSM appliances for redundancy
  • Configure automatic failover between HSM nodes
  • Use multiple HSM endpoints in Helm values for failover

Next steps

After successfully integrating BlockSafe HSM with Ripple Custody:

  1. Complete installation: Continue with Installation and initialization to deploy remaining components

  2. Configure blockchain indexers: Set up blockchain node connections as described in [Blockchain node connectivity planning(../../deployment/planning/blockchain-nodes.md)

  3. Backup procedures:

    • Document HSM backup procedures.
    • Test key-recovery process.
    • Store backup HSM in secure location.
    • Implement regular backup schedule.
  4. Production hardening:

    • Enable HSM audit logging.
    • Configure HSM monitoring and alerting.
    • Implement PIN-rotation policy.
    • Review and harden network access controls.
  5. High availability (HA):

    • Deploy backup BlockSafe HSM.
    • Configure HSM failover.
    • Test failover procedures.
    • Document recovery runbooks.
  6. Security audit:

    • Review HSM access controls.
    • Audit slot PINs and credentials.
    • Verify network segmentation.
    • Test disaster recovery (DR) procedures.
  7. Review Production best practices for namespace segmentation, HA patterns, and monitoring.