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.
Ripple Custody uses BlockSafe HSM with a key derivation approach similar to Thales Luna HSM:
- Master key creation: The master key is created inside the HSM during the key ceremony when creating HSM slots.
- Key derivation: vault derives account keys from master seed using BIP32/SLIP10.
- Signing operations: All private key operations performed inside HSM.
- 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 blockchainBlockSafe 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
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)
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 KubernetesThis 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.
Complete the following using BlockSafe documentation:
- Physical deployment: Rack-mount, power, and network-connect the BlockSafe HSM appliance
- Network configuration: Assign a static IP address accessible from your Kubernetes cluster (default port: 3001)
- HSM initialization: Set Security Officer (SO) PIN and create admin user
- Set HSM label: Use a descriptive label (e.g., "RippleCustodyHSM").
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.
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.
Before proceeding to Ripple Custody configuration, verify:
- Network connectivity: Port 3001 (or configured port) is reachable from Kubernetes nodes
- PKCS#11 connectivity:
pkcs11-tool --list-slotsshows your configured slots - Authentication: Can login to slots with configured PINs
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.
Now that your BlockSafe HSM is initialized, configure Ripple Custody to use it for the notary and vault components.
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! |
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"# 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"# 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}"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.
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# 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# 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!# 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"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# 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# 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| 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.
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.
| 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
After successfully integrating BlockSafe HSM with Ripple Custody:
Complete installation: Continue with Installation and initialization to deploy remaining components
Configure blockchain indexers: Set up blockchain node connections as described in [Blockchain node connectivity planning(../../deployment/planning/blockchain-nodes.md)
Backup procedures:
- Document HSM backup procedures.
- Test key-recovery process.
- Store backup HSM in secure location.
- Implement regular backup schedule.
Production hardening:
- Enable HSM audit logging.
- Configure HSM monitoring and alerting.
- Implement PIN-rotation policy.
- Review and harden network access controls.
High availability (HA):
- Deploy backup BlockSafe HSM.
- Configure HSM failover.
- Test failover procedures.
- Document recovery runbooks.
Security audit:
- Review HSM access controls.
- Audit slot PINs and credentials.
- Verify network segmentation.
- Test disaster recovery (DR) procedures.
Review Production best practices for namespace segmentation, HA patterns, and monitoring.