# Thales Luna HSM integration guide

This guide provides complete instructions for integrating the Thales Luna 7 HSM with Ripple Custody. It covers both form factors of the Luna 7 A-series — the **Luna Network HSM 7** appliance and the **Luna PCIe HSM 7 (A700)** card. Both are FIPS 140-2 Level 3 certified hardware security modules that provide hardware-based key protection for your notary and vault components.

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

## Overview

### Supported form factors

This guide covers both form factors of the Thales Luna 7 A-series HSM. Both use an identical PKCS#11 cryptographic interface and Luna 7.x firmware — only the transport layer differs, so the Ripple Custody integration is the same for both.

| Attribute | Luna Network HSM 7 | Luna PCIe HSM 7 (A700) |
|  --- | --- | --- |
| **Connection** | NTLS (network transport layer security), `NetClient=1` | Local PCI bus (card installed in the host server) |
| **Crypto interface** | PKCS#11 | PKCS#11 (identical) |
| **Firmware** | Luna 7.x | Luna 7.x (identical) |
| **Form factor** | Standalone network appliance | PCIe card in host server |


**Shared configuration:** Because the cryptographic interface and firmware are identical, the HSM policies, scalable key storage (SKS) setup, key-derivation behavior, and Ripple Custody configuration described in this guide apply to both form factors. The only differences are the steps that set up the network transport — network ACLs, NTLS/mTLS certificates, and port 1792 — which do not apply to the locally-installed PCIe card (A700).

### How Ripple Custody uses Luna HSM

Ripple Custody uses Luna HSM in two critical components:

1. **Notary**: Uses the master signing key in the HSM to authenticate governance operations
2. **Vault**: Uses the master encryption key in the HSM to protect account private keys


**Key generation flow**:

1. During account creation, the vault requests key generation from the HSM
2. The HSM generates the private key internally using its secure random number generator
3. The private key is encrypted using the HSM master key via PKCS#11
4. The encrypted key (SKS blob) is stored in the Ripple Custody database
5. The HSM master key and plaintext private keys never leave the HSM hardware


### Deployment architecture


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

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

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

The diagram above shows the **Network HSM** topology, where the notary and vault reach the HSM over mTLS on port 1792. For the **PCIe HSM (A700)**, the card is installed directly in the host server and accessed over the local PCI bus, so there is no network hop between the Ripple Custody components and the HSM.

## Prerequisites

### Hardware and software requirements

Before starting, ensure you have:

**From Thales Luna HSM**:

- One of the following Luna 7 A-series HSMs:
  - Thales Luna Network HSM 7 appliance (physical or virtual), or
  - Thales Luna PCIe HSM 7 (A700) card installed in the host server
- Firmware version:
  - **7.7.1 or higher** for BIP32 derivation
  - **7.8.7 or higher** for SLIP10 derivation (recommended)
- Application software 7.8.5-300 (for SLIP10)
- **Network HSM only:** network connectivity on port **1792** (typical). The PCIe HSM (A700) is accessed locally over the PCI bus and does not use network transport.


**From your infrastructure**:

- Linux client machine for HSM administration (LunaCM client)
- Network access from Kubernetes cluster to HSM on port 1792
- Firewall rules allowing bidirectional traffic


**From Ripple**:

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


### Required HSM policies

**CRITICAL:** The following policies are **destructive** and will erase existing HSM data when enabled. Enable these policies BEFORE storing any production keys.

**HSM-level policies** (apply to entire HSM):

- **Policy 6**: Allow masking (required for SKS)
- **Policy 12**: Allow non-FIPS algorithms (required for vault operations)


**Partition-level policies** (apply to each partition):

- **Policy 22**: Allow activation
- **Policy 23**: Allow auto-activation
- **Policy 41**: Partition version
- **Policy 43**: Allow non-FIPS algorithms


### Key derivation schemes

The vault automatically detects HSM capabilities at startup and selects the appropriate derivation scheme:

| Scheme | Supported Curves | Supported Blockchains | Firmware Required |
|  --- | --- | --- | --- |
| **SLIP10** (preferred) | secp256k1, Ed25519 | All blockchains (Bitcoin, Ethereum, XRPL, Solana, Algorand, etc.) | 7.8.7+ |
| **BIP32** (fallback) | secp256k1 only | Bitcoin, Ethereum, XRPL, Litecoin, Polygon | 7.7.1+ |


**Automatic selection:** The vault will automatically choose SLIP10 if the HSM firmware supports it (7.8.7+), otherwise it defaults to BIP32. No manual configuration is required.

### Key storage strategy

By default, Ripple Custody vaults use hierarchical-deterministic (HD) key derivation (SLIP10). You can optionally configure a vault to use **random keys** instead, but this is not the recommended default.

**Random key backups:** The random key strategy has implications for backups. Unlike HD-derived keys, random keys cannot be regenerated from a single seed, so their backups must be managed manually and periodically reconducted. Use HD derivation (the default) unless you have a specific requirement for random keys.

### Documentation references

- [Thales Luna Network HSM 7 documentation](https://thalesdocs.com/gphsm/luna/7/docs/network/Content/Home_Luna.htm)
- [BIP32 mechanism support](https://thalesdocs.com/gphsm/luna/7/docs/network/Content/sdk/extensions/BIP32.htm)
- [Partition administration guide](https://thalesdocs.com/gphsm/luna/7/docs/network/Content/admin_partition/Preface.htm)
- [High-availability groups](https://thalesdocs.com/gphsm/luna/7/docs/network/Content/admin_partition/ha/ha.htm)


## HSM initialization

This section covers the vendor-specific setup required to prepare your Luna HSM for use with Ripple Custody. Detailed step-by-step commands are available in the [Thales Luna Network HSM 7 documentation](https://thalesdocs.com/gphsm/luna/7/docs/network/Content/Home_Luna.htm).

**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 Luna HSM appliance

Complete the following using Thales documentation:

1. **Physical deployment**: Rack, power, and network-connect the Luna HSM appliance
2. **Initial setup**: Complete the setup wizard via serial console or web interface
3. **Network configuration**: Assign a static IP address accessible from your Kubernetes cluster
4. **Firmware verification**: Confirm firmware is **7.7.1+** (BIP32) or **7.8.7+** (SLIP10)


### Step 2: Enable required HSM policies

**WARNING:** Enabling these policies will **destroy all existing keys and data** on the HSM. Perform this step on a freshly initialized HSM or after backing up all existing keys.

**HSM-level policies** (required for Ripple Custody):

| Policy | Name | Required Value | Purpose |
|  --- | --- | --- | --- |
| **6** | Allow masking | `1` (enabled) | Required for Scalable Key Storage (SKS) |
| **12** | Allow non-FIPS algorithms | `1` (enabled) | Required for vault operations |


Use `hsm changePolicy` and `hsm showPolicies` commands to configure and verify.

### Step 3: Configure scalable key storage (SKS) partition

SKS allows you to store unlimited keys while maintaining hardware-level security. The SKS master key (SMK) remains in the HSM, while encrypted key blobs are stored externally in the Ripple Custody database.

**Create one partition** for Ripple Custody:

- Partitions must be **type V1** for SKS support
- Assign a strong password for the partition
- One partition per application is the standard design (partitions are expensive)


**Enable partition-level policies** on the partition:

| Policy | Name | Required Value | Purpose |
|  --- | --- | --- | --- |
| **22** | Allow activation | `1` (enabled) | Required for partition access |
| **23** | Allow auto-activation | `1` (enabled) | Required for automatic login |
| **41** | Partition version | `1` (enabled) | Required for SKS |
| **43** | Allow non-FIPS algorithms | `1` (enabled) | Required for blockchain operations |


**Assign client access** by registering the Kubernetes client with partition access using `client assignPartition`.

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


```mermaid
flowchart TB
    subgraph prod["Production HA Cluster"]
        subgraph apps["Client Applications"]
            direction LR
            notary["Notary"]
            vault1["Vault Replica"]
            vault2["Vault Replica"]
        end

        subgraph luna["Thales Luna HA Group"]
            hsm1["HSM 1<br/>Partition"]
            hsm2["HSM 2<br/>Partition"]
            hsm3["HSM 3<br/>Partition"]

            hsm1 <-->|"Replication"| hsm2
            hsm2 <-->|"Replication"| hsm3
        end
    end

    notary -->|"Client Cert"| luna
    vault1 -->|"Client Cert"| luna
    vault2 -->|"Client Cert"| luna
```

**Requirements**:

- At least 2 Luna HSM appliances (one partition per HSM for replication)
- Matching partition configurations on each HSM


**Configuration**:

1. Use `lunacm` on your Linux client to create HA groups using `hagroup createGroup`
2. Add additional HSM partitions as members using `hagroup addMember`
3. Verify HA configuration is saved to `/etc/Chrystoki.conf`


Key `Chrystoki.conf` settings:

- `HAOnly = 1` ensures PKCS#11 operations only use HA groups
- `VirtualTokenActiveRecovery = activeEnhanced` enables automatic failover


See [Thales HA configuration guide](https://thalesdocs.com/gphsm/luna/7/docs/network/Content/admin_partition/ha/ha.htm) for detailed instructions.

### Step 5: Configure network access and mTLS

**PCIe HSM (A700):** Skip this step. The card communicates with its host over the local PCI bus, so there is no network ACL, NTLS/mTLS certificate exchange, or port 1792 to configure. Instead, confirm the card is visible as a local slot using `slot list` in `lunacm`.

**Network ACL**: Add your Kubernetes cluster node IP range to the HSM's network ACL using `network add`.

**mTLS Certificates**: Luna HSM uses mutual TLS (mTLS) for secure communication.

1. **Generate client certificate** on your Linux client using `vtl createCert`
2. **Register client with HSM** using `client register` and assign partition access
3. **Download HSM server certificate** for client-side verification.


You will need three files for Ripple Custody configuration:

- Client certificate (`client.pem`)
- Client private key (`client.key`)
- HSM server certificate (`server.pem`)


### Step 6: Verify HSM connectivity

Before proceeding to Ripple Custody configuration, verify:

1. **Network connectivity**: Port 1792 is reachable from Kubernetes nodes
2. **PKCS#11 connectivity**: `vtl verify` shows your HA groups
3. **Authentication**: Can login to partitions with configured PINs
4. **Cryptographic operations**: Basic operations execute without errors


**Checkpoint:** If `vtl verify` shows your HA groups and you can successfully login to partitions, your Luna HSM is properly configured and ready for Ripple Custody integration.

## Ripple Custody configuration

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

**PCIe HSM (A700):** The network transport fields shown in the examples below — `host`, `port`, and the `client`/`server` certificate blocks — do not apply, because the card is accessed locally over the PCI bus rather than over NTLS. Configure the same `kms_luna` platform with your partition `slot` and `pin`. If you are unsure which fields your deployment requires for the PCIe form factor, [contact Ripple](/products/custody/support/get-support).

### Step 1: Prepare certificate files

You'll need to provide three certificate files in your Helm configuration:

1. **Client certificate** (`<client-hostname>.pem`): Authenticates Ripple Custody to the HSM
2. **Client private key** (`<client-hostname>Key.pem`): Private key for client certificate
3. **Server certificate** (`server.pem`): HSM's server certificate for verification


**Convert certificates to base64 for Helm values**:


```bash
# Client certificate
$ cat /usr/safenet/lunaclient/cert/client/<client-hostname>.pem | base64 -w 0 > client-cert.b64

# Client private key
$ cat /usr/safenet/lunaclient/cert/client/<client-hostname>Key.pem | base64 -w 0 > client-key.b64

# Server certificate
$ cat /usr/safenet/lunaclient/cert/server/server.pem | base64 -w 0 > server-cert.b64
```

### Step 2: Configure notary with Luna HSM

Edit your `production.yaml` Helm values file to configure the notary component:


```yaml
# production.yaml

components:
  notary:
    enabled: true

    # Platform selection
    platform: kms_luna

    # Luna HSM configuration
    kms_luna:
      host: "luna-hsm.example.com"  # Luna HSM hostname or IP
      port: "1792"                   # Luna HSM port (must be string)
      slot: "0"                      # HA group slot number (0 for first HA group)
      pin: "notary-partition-password"  # Partition password

      # Client certificate (for mTLS)
      client:
        certificate: |
          -----BEGIN CERTIFICATE-----
          MIIDXTCCAkWgAwIBAgIJAKZ...
          -----END CERTIFICATE-----
        key: |
          -----BEGIN PRIVATE KEY-----
          MIIEvQIBADANBgkqhkiG9w0...
          -----END PRIVATE KEY-----

      # Server certificate (Luna HSM)
      server:
        certificate: |
          -----BEGIN CERTIFICATE-----
          MIIDXTCCAkWgAwIBAgIJAKZ...
          -----END CERTIFICATE-----
```

**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.

**Using Kubernetes Secrets for PIN**:


```bash
# Create secret for Notary PIN
kubectl create secret generic notary-luna-pin \
  --namespace custody-core \
  --from-literal=pin='notary-partition-password'

# Reference secret in production.yaml
```


```yaml
components:
  notary:
    platform: kms_luna
    kms_luna:
      # ... other config ...
      pinSecretRef: notary-luna-pin  # Reference to Kubernetes secret
```

### Step 3: Configure vault with Luna HSM

Configure the vault component to use Luna HSM for key encryption:


```yaml
# production.yaml

harmonize:
  vaults:
    "00000000-0000-0000-0000-000000000000":  # Default vault UUID
      enabled: true

      # Platform selection
      platform: kms_luna

      # Notary public key (obtained after Notary initialization - see Step 4)
      notary_public_key: "ed25519:50692dfa472f013e2f87e5d210be40cefe178e33787be4688d5da0afe06ed149"

      # Luna HSM configuration
      kms_luna:
        host: "luna-hsm.example.com"
        port: "1792"
        slot: "0"  # Same partition as Notary (one partition per application)
        pin: "partition-password"

        client:
          certificate: |
            -----BEGIN CERTIFICATE-----
            MIIDXTCCAkWgAwIBAgIJAKZ...
            -----END CERTIFICATE-----
          key: |
            -----BEGIN PRIVATE KEY-----
            MIIEvQIBADANBgkqhkiG9w0...
            -----END PRIVATE KEY-----

        server:
          certificate: |
            -----BEGIN CERTIFICATE-----
            MIIDXTCCAkWgAwIBAgIJAKZ...
            -----END CERTIFICATE-----
```

**Using Kubernetes Secrets for vault PIN**:


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

### Step 4: Complete configuration example

Here's a complete example showing both notary and vault configured with Luna HSM:


```yaml
# production.yaml - Complete Luna 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_luna
    kms_luna:
      host: "luna-hsm.example.com"
      port: "1792"
      slot: "0"
      pin: "${NOTARY_PIN}"  # Injected from secrets manager
      client:
        certificate: |
          -----BEGIN CERTIFICATE-----
          ${LUNA_CLIENT_CERT}
          -----END CERTIFICATE-----
        key: |
          -----BEGIN PRIVATE KEY-----
          ${LUNA_CLIENT_KEY}
          -----END PRIVATE KEY-----
      server:
        certificate: |
          -----BEGIN CERTIFICATE-----
          ${LUNA_SERVER_CERT}
          -----END CERTIFICATE-----

# Vault configuration (uses same partition as Notary)
harmonize:
  vaults:
    "00000000-0000-0000-0000-000000000000":
      enabled: true
      platform: kms_luna
      notary_public_key: "ed25519:${NOTARY_PUBLIC_KEY}"  # Set after Notary initialization
      kms_luna:
        host: "luna-hsm.example.com"
        port: "1792"
        slot: "0"  # Same partition as Notary
        pin: "${PARTITION_PIN}"
        client:
          certificate: |
            -----BEGIN CERTIFICATE-----
            ${LUNA_CLIENT_CERT}
            -----END CERTIFICATE-----
        key: |
          -----BEGIN PRIVATE KEY-----
          ${LUNA_CLIENT_KEY}
          -----END PRIVATE KEY-----
        server:
          certificate: |
            -----BEGIN CERTIFICATE-----
            ${LUNA_SERVER_CERT}
            -----END CERTIFICATE-----
```

## Advanced secret management

For production deployments, store sensitive credentials (PKCS#11 PIN, certificates) 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 Luna 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 **[Advanced secret management](/products/custody/deployment/integrate-kms/advanced-secret-management)**.

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


```yaml
components:
  notary:
    platform: kms_luna
    kms_luna:
      existingSecret: "notary-luna-credentials"  # ESO-managed secret
```

## Verification and testing

After configuring your Helm values, follow these steps to deploy and verify the integration.

### Step 1: Verify HSM connectivity (before deployment)

Before deploying Ripple Custody components, verify network connectivity to the Luna HSM:


```bash
# Test network connectivity from a Kubernetes node or test pod
nc -zv luna-hsm.example.com 1792

# Expected output:
# Connection to luna-hsm.example.com 1792 port [tcp/*] succeeded!

# Verify PKCS#11 connectivity using vtl (from Luna client machine)
vtl verify

# Expected output should show your HA groups
```

**IMPORTANT:** Verify HSM connectivity before deploying components. Troubleshooting connectivity issues after deployment is more difficult.

### Step 2: Deploy notary component


```bash
# Deploy Notary first (Vault needs Notary's public key)
helm upgrade --install harmonize ./harmonize-custody \
  --namespace custody-core \
  --create-namespace \
  -f production.yaml \
  --set components.vault.enabled=false \
  --set components.indexers.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 sidecar logs to verify HSM connection
kubectl logs -n custody-core deployment/harmonize-notary -c kms-connect --tail=100

# Expected output should show:
# - Successful PKCS#11 connection to Luna HSM
# - HA group detection
# - Partition login success
```

### Step 3: Initialize notary and retrieve public key

After notary is deployed and connected to the HSM, initialize it and retrieve the public key. For detailed API instructions, see the [Installation and initialization](/products/custody/deployment/install/first-time-installation) guide.


```bash
# Check Notary logs for successful initialization
kubectl logs -n custody-core deployment/harmonize-notary -c notary-core --tail=50

# Retrieve Notary public key via the System Properties API
# See: API Reference > System Properties > Get System Properties
```

**Save the notary public key** - you'll need it for the vault configuration.

### Step 4: Deploy vault component

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


```bash
# Deploy Vault
helm upgrade --install harmonize ./harmonize-custody \
  --namespace custody-core \
  -f production.yaml

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

# Verify Vault HSM connectivity
kubectl logs -n custody-vault deployment/harmonize-vault -c kms-connect --tail=100
```

### Step 5: Verify end-to-end functionality

Create a test blockchain account to verify the complete integration:

1. **Register the vault** via the Web UI: **Administration > Vaults > Create a vault**
2. **Create a test account** via the Web UI: **Accounts > Create account**
3. **Verify account creation** succeeded with a valid blockchain address


This confirms:

- vault can communicate with Luna HSM
- Key derivation is working (BIP32/SLIP10)
- SKS blob encryption/storage is functional


For detailed instructions on account creation, see the [Create an account](/products/custody/accounts-and-assets/accounts/manage-accounts-ui#create-an-account-in-the-ui) guide.

## Troubleshooting

| Error Message | Cause | Solution |
|  --- | --- | --- |
| `CKR_DEVICE_ERROR` | HSM not reachable | Check network connectivity and firewall rules for port 1792 |
| `CKR_PIN_INCORRECT` | Wrong partition password | Verify PIN in Kubernetes secret matches HSM partition password |
| `CKR_TOKEN_NOT_PRESENT` | HA group not configured | Configure HA group and verify `Chrystoki.conf` |
| `CKR_SESSION_HANDLE_INVALID` | Session timeout | Increase session timeout or check HSM load |
| `SSL handshake failed` | Certificate mismatch | Regenerate certificates and verify mTLS configuration |
| `BIP32_DERIVE not supported` | Firmware too old | Upgrade to firmware 7.7.1+ |
| `SLIP10_DERIVE not supported` | Firmware too old | Upgrade to firmware 7.8.7+ |


For detailed troubleshooting, see the [Thales Luna Network HSM 7 documentation](https://thalesdocs.com/gphsm/luna/7/docs/network/Content/Home_Luna.htm).

## Production best practices

For production-ready Luna HSM deployments, implement the following patterns. See **[Production best practices](/products/custody/deployment/integrate-kms/production-best-practices)** for detailed instructions that apply to all KMS platforms.

### Luna HSM-specific considerations

| Practice | Luna HSM Implementation |
|  --- | --- |
| **High Availability** | Configure Luna HA groups with `hagroup createGroup` and add multiple HSM members |
| **Namespace Segmentation** | Separate Luna partitions per namespace/vault for isolation |
| **Monitoring** | Use `lunacm` commands (`hsm show`, `partition show`, `hagroup show`) plus Prometheus metrics |
| **Certificate Rotation** | Generate new certificates with `vtl createCert`, update Kubernetes secrets, perform rolling update |
| **Backup** | Use `partition backup` command, store backups securely, test quarterly |
| **HA Sync** | Regularly verify HA group synchronization with `hagroup synchronize` |


**Luna 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 Luna HSM with Ripple Custody:

1. **Backup HSM keys**: Implement backup procedures for SKS master keys.
  - Back up SMK to a secondary Luna 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
  - Audit certificate expiration dates
  - Verify network ACLs are restrictive
  - Test backup and recovery procedures
5. **Review [Production best practices](/products/custody/deployment/integrate-kms/production-best-practices)** for namespace segmentation, HA patterns, and monitoring


## AWS Nitro Enclave deployment

For enhanced security, you can deploy the vault in an AWS Nitro enclave to connect your Luna HSM to Ripple Custody.

These steps require support assistance from Ripple to complete. For more information, contact your Ripple liaison.

### Prerequisites

To configure a Luna HSM with AWS Nitro enclave to work with Ripple Custody, you need:

- From Ripple:
  - An AWS enclave Terraform script
  - The `encrypt-cli` tool
- From your Ripple Custody environment:
  - The notary messaging public key, retrieved with a call to the [List system properties](/products/custody/reference/api/openapi/systemproperties/getsystemproperties) API operation.


### Deploy the vault

1. Create your enclave contract, in a format similar to the following Podman Play YAML file:

```yaml
# Enclave configuration (required)
kind: Enclave
apiVersion: v1
#
# specify if enclaves requires disk storage via NBD
requireVarDisk: false
requireDataDisk: false
#
# base64 encoded disk encryption keys, min=32 byte. If empty keys are auto-generated on every boot!
# Example: dd if=/dev/random bs=1 count=32 | base64
encryptionKeyVar: <your-encryption-key>
encryptionKeyData: <your-encryption-key>
#
# auths: login credentials for private container registries (optional)
auths:
  - registry: metaco.azurecr.io
    username: <your-username>
    password: <your-password>
hostname: enclave-vault-1
---
# POD definition (required)
# Pod configuration map (optional)
kind: ConfigMap
apiVersion: v1
metadata:
  name: config
data:

---
kind: Pod
apiVersion: v1
metadata:
  name: vault-pod
spec:
  volumes:
    - name: config
      configMap:
        name: config
  containers:
```


For help to define an appropriate pod structure for the current release, [contact Ripple](/products/custody/support/get-support).

1. Using `encrypt-cli`, generate the enclave contract token.
2. Run the Terraform script with the contract token created in step 2 as an input parameter.


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