# BlockSafe HSM integration guide

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](/products/custody/v1.34/deployment/install/helm-charts) 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


```mermaid
flowchart TB
    subgraph k8s["Kubernetes Cluster"]
        direction LR
        notary["Notary + KMS Connect"]
        vault["Vault + KMS Connect"]
    end

    subgraph blocksafe["BlockSafe HSM"]
        direction LR
        slot0["Slot 0: Notary Keys"]
        slot1["Slot 1: Vault Keys"]
    end

    notary -->|PKCS#11 port 3001| blocksafe
    vault -->|PKCS#11 port 3001| blocksafe
```

## 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:

| Slot | Purpose | Label Example |
|  --- | --- | --- |
| **Slot 0** | Ripple Custody | `CustodySlot` |


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):

| Policy | Purpose |
|  --- | --- |
| **BIP32** | Key derivation for blockchain accounts |
| **SLIP10** | Alternative key derivation scheme |
| **Key wrapping** | Required 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:

| Parameter | Value | Example |
|  --- | --- | --- |
| **HSM IP Address** | BlockSafe HSM IP | `192.168.1.100` |
| **HSM Port** | PKCS#11 port | `3001` |
| **Device String** | Format: `port@hostname` | `3001@192.168.1.100` |
| **Notary slot** | Slot number for notary | `0` |
| **Notary PIN** | Slot 0 PIN | (stored securely) |
| **Vault slot** | Slot number for vault | `1` |
| **Vault PIN** | Slot 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:

| Parameter | Description | Example |
|  --- | --- | --- |
| **Device** | HSM address in `port@hostname` format | `3001@192.168.1.100` |
| **Slot** | Slot number for Ripple Custody | `0` |
| **PIN** | Slot PIN | `SlotSecurePin123!` |


### Step 2: Configure notary with BlockSafe HSM

Edit your `production.yaml` Helm values file:


```yaml
# 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**:


```bash
# 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:


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

### Step 3: Configure vault with BlockSafe HSM


```yaml
# 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**:


```bash
# 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`:


```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


```yaml
# 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**:

| Approach | Description | Use Case |
|  --- | --- | --- |
| **External Secrets Operator (ESO)** | Sync secrets from HashiCorp Vault, AWS Secrets Manager, or Azure Key Vault to Kubernetes | Enterprise environments with centralized secret management |
| **HashiCorp Vault Agent Injector** | Inject secrets directly into pods at runtime | Organizations already using Vault Agent |
| **AWS Secrets Manager** | Store and rotate secrets in AWS | AWS-native deployments |


For complete setup instructions, see the **[Advanced secret management guide](/products/custody/v1.34/how-to/integrate-kms/advanced-secret-management)**.

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


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

## Verification and testing

### Step 1: Deploy notary component


```bash
# 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


```bash
# 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


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

# Retrieve Notary public key
curl https://api.custody.example.com/v1/system/properties | jq '.notary_public_key'

# Example output:
# "ed25519:50692dfa472f013e2f87e5d210be40cefe178e33787be4688d5da0afe06ed149"
```

### Step 4: Deploy vault component

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


```bash
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


```bash
# Create blockchain account to verify key derivation
curl -X POST https://api.custody.example.com/v1/accounts \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer ${ACCESS_TOKEN}" \
  -d '{
    "name": "Test Account",
    "ledger": "ethereum",
    "derivation_strategy": "deterministic"
  }'

# Verify account creation succeeded
# This confirms:
# 1. Vault can communicate with BlockSafe HSM
# 2. Key derivation is working (BIP32/SLIP10)
# 3. Account keys are properly generated
```

### Step 6: Test signing operation


```bash
# Create a test transaction
curl -X POST https://api.custody.example.com/v1/transactions \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer ${ACCESS_TOKEN}" \
  -d '{
    "account_id": "<account-id-from-step-5>",
    "ledger": "ethereum",
    "to": "0x742d35Cc6634C0532925a3b844Bc9e7595f0bEb",
    "amount": "0.001",
    "currency": "ETH"
  }'

# This confirms:
# 1. Vault can perform signing operations via BlockSafe HSM
# 2. PKCS#11 signing interface is working
# 3. End-to-end transaction flow is functional
```

## Troubleshooting

| Error Message | Cause | Solution |
|  --- | --- | --- |
| `CKR_DEVICE_ERROR` | HSM not accessible | Check network connectivity and device string format (`port@hostname`) |
| `CKR_PIN_INCORRECT` | Wrong PIN | Verify PIN in Kubernetes secret matches slot PIN |
| `CKR_SLOT_ID_INVALID` | Invalid slot number | Verify slot exists and is initialized |
| `CKR_SESSION_HANDLE_INVALID` | Session timeout | Restart KMS Connect pod |
| `CKR_FUNCTION_NOT_SUPPORTED` | Unsupported operation | Check firmware version and policies |
| `Connection refused` | HSM port not accessible | Check 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](/products/custody/v1.34/how-to/integrate-kms/production-best-practices) guide** for detailed instructions that apply to all KMS platforms.

### BlockSafe HSM-specific considerations

| Practice | BlockSafe HSM Implementation |
|  --- | --- |
| **High availability (HA)** | Configure BlockSafe HSM in cluster mode with multiple appliances across racks/locations. |
| **Namespace segmentation** | Separate PKCS#11 slots per namespace/vault for isolation. |
| **Monitoring** | Use `pkcs11-tool` commands (`--show-info`, `--list-slots`, `--list-objects`) plus Prometheus metrics. |
| **Backup** | Export 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](/products/custody/v1.34/deployment/install/installation) 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](/products/custody/v1.34/how-to/integrate-kms/production-best-practices)** for namespace segmentation, HA patterns, and monitoring.