# Deploy a vault in an enclave

These steps describe how to deploy a vault in an AWS Nitro enclave to connect your HSM to Ripple Custody.

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

## Prerequisites

To configure your HSM to work with Ripple Custody, you'll need:

- From Ripple:
  - An AWS enclave Terraform script
  - The `encrypt-cli` tool
- From your AWS CloudHSM cluster:
  - The wrapping key label
  - Credentials of the vault manager user
For more information, see [Initialize the HSM](/products/custody/v1.19/get-started/deployment/deploy-kms/cloud/aws/initialize).
- From your Ripple Custody environment:
  - The notary messaging public key, retrieved with a call to the [List system properties](/products/custody/v1.19/api/reference/openapi/systemproperties/getsystemproperties) API operation.


## Deploy the vault

To deploy the vault:

1. As the vault manager user, create your enclave contract as a Podman Play YAML file, in a format similar to the following example:



```json Enclave contract example
"apiVersion": "v1"
"auths":
  - "password": "<REGISTRY_PASSWORD>"
    "registry": "metacodev.azurecr.io"
    "username": "<REGISTRY_USERNAME>"
"encryptionKeyData": "<ENCRYPTION_KEY_DATA>"
"encryptionKeyVar": "<ENCRYPTION_KEY_VAR>"
"hostname": "example.com"
"kind": "Enclave"
"requireDataDisk": true
"requireVarDisk": false

---
"apiVersion": "v1"
"kind": "Pod"
"metadata":
  "name": "pod_hmz_vault_with_aws_wrap"
  "terraform_enclave_contract_template_name": "vault_with_kms_aws_wrap"
"spec":
  "containers":
    - "args":
        - "opt/entrypoint.sh | tee /var/log/hmz-vault-stdout.log"
      "command":
        - "/bin/sh"
        - "-c"
      "env":
        - "name": "VAULT_ID"
          "value": "<VAULT_ID>"
        - "name": "VAULT_TRUSTED_SIG"
          "value": "pem:<VAULT_TRUSTED_SIG>"
        - "name": "HARMONIZE_CORE_ENDPOINT"
          "value": "<HARMONIZE_CORE_ENDPOINT>"
        - "name": "VAULT_LOGLEVEL"
          "value": "7"
        - "name": "VAULT_BRIDGE_LOGLEVEL"
          "value": "7"
        - "name": "PLATFORM"
          "value": "kms"
        - "name": "VAULT_KMS_ENDPOINT"
          "value": "localhost:10000"
        - "name": "VAULT_CORE_ADDRESS"
          "value": "localhost:10054"
      "image": "metacodev.azurecr.io/custody/vault-releases@sha256:<VAULT_IMAGE_SHA>"
      "imagePullPolicy": "Always"
      "name": "hmz_vault"
      "securityContext":
        "allowPrivilegeEscalation": false
        "readOnlyRootFilesystem": false
        "runAsGroup": 0
        "runAsNonRoot": true
        "runAsUser": 0
      "volumeMounts":
        - "mountPath": "/var/log"
          "name": "volume-for-stdout-logs-dir"
          "readOnly": false
    - "args":
        - "/usr/bin/kms | tee /var/log/kms-connect-stdout.log"
      "command":
        - "/bin/sh"
        - "-c"
      "env":
        - "name": "KMS_LOGLEVEL"
          "value": "7"
        - "name": "HMZ_KMS_CONNECT_SOFTWARE_MASTER_KEY"
          "value": "<HMZ_KMS_CONNECT_SOFTWARE_MASTER_KEY>"
        - "name": "KMS_REWRAPPING_KEY"
          "value": "aws:<AWS_WRAP_KEY_LABEL>"
        - "name": "AWS_WRAP_CLUSTER_ENI_IP"
          "value": "<ENI_IP>"
        - "name": "AWS_WRAP_CLUSTER_CERTIFICATE"
          "value": |
            -----BEGIN CERTIFICATE-----
            <CERTIFICATE>
            -----END CERTIFICATE-----
        - "name": "AWS_WRAP_PIN"
          "value": "<CRYPTO_USER:CRYPTO_PIN>"
        - "name": "AWS_WRAP_KEY_LABEL"
          "value": "<AWS_WRAP_KEY_LABEL>"
        - "name": "AWS_WRAP_CLUSTER_CONSISTENCY_THRESHOLD"
          "value": 1
      "image": "metacodev.azurecr.io/custody/kms-soft@sha256:<KMS_IMAGE_SHA>"
      "imagePullPolicy": "Always"
      "name": "kms_connect"
      "securityContext":
        "allowPrivilegeEscalation": false
        "readOnlyRootFilesystem": false
        "runAsGroup": 0
        "runAsNonRoot": true
        "runAsUser": 0
      "volumeMounts":
        - "mountPath": "/opt/kms/cfg"
          "name": "volume-for-kms-connect-soft-config"
          "readOnly": true
        - "mountPath": "/var/log"
          "name": "volume-for-stdout-logs-dir"
          "readOnly": false
    - "args":
        - "--config=/etc/otel-collector-contrib/config.yaml"
      "env":
        - "name": "OTEL_LOG_LEVEL"
          "value": "info"
      "image": "otel/opentelemetry-collector-contrib:latest"
      "imagePullPolicy": "Always"
      "name": "otel-collector"
      "security_context":
        "allow_privilege_escalation": false
        "read_only_root_filesystem": true
        "run_as_group": 1000
        "run_as_non_root": true
        "run_as_user": 1000
      "volumeMounts":
        - "mountPath": "/etc/otel-collector-contrib"
          "name": "otel-collector-config"
          "readOnly": true
        - "mountPath": "/var/log"
          "name": "volume-for-stdout-logs-dir"
          "readOnly": true
  "podSecurityContext":
    "fsGroup": 1001
    "fsGroupChangePolicy": "OnRootMismatch"
  "volumes":
    - "configMap":
        "name": "config-map"
      "name": "volume-for-kms-connect-soft-config"
    - "configMap":
        "name": "config-map"
      "name": "otel-collector-config"
    - "emptyDir": {}
      "name": "volume-for-stdout-logs-dir"

---
"apiVersion": "v1"
"data":
  "config.yaml": |
    "exporters":
      "otlphttp":
        "endpoint": "<OTEL_COLLECTOR_ENDPOINT>"
        "headers":
          "Authorization": "Basic <OTEL_COLLECTOR_AUTH>"
        "tls":
          "insecure_skip_verify": true
    "processors":
      "batch": {}
      "resource":
        "attributes":
        - "action": "upsert"
          "key": "service.name"
          "value": "hmz-vault"
        - "action": "upsert"
          "key": "telemetry.sdk.name"
          "value": "otel-collector"
        - "action": "upsert"
          "key": "environment"
          "value": "PROD"
        - "action": "upsert"
          "key": "tenant"
          "value": "client-name"
    "receivers":
      "filelog/hmz_vault_stdout_logs":
        "include":
        - "/var/log/hmz-vault-stdout.log"
        "include_file_name": true
        "include_file_name_resolved": false
        "include_file_owner_name": false
        "include_file_path": false
        "include_file_path_resolved": false
        "multiline":
          "line_start_pattern": "^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}\\.\\d{3}Z|^\\d{4}-\\d{2}-\\d{2}
            \\d{2}:\\d{2}:\\d{2},\\d{3}"
        "start_at": "beginning"
      "filelog/kms_connect_stdout_logs":
        "include":
        - "/var/log/kms-connect-stdout.log"
        "include_file_name": true
        "include_file_name_resolved": false
        "include_file_owner_name": false
        "include_file_path": false
        "include_file_path_resolved": false
        "multiline":
          "line_start_pattern": "^[A-Za-z]+"
        "start_at": "beginning"
    "service":
      "pipelines":
        "logs":
          "exporters":
          - "otlphttp"
          "processors":
          - "batch"
          - "resource"
          "receivers":
          - "filelog/hmz_vault_stdout_logs"
          - "filelog/kms_connect_stdout_logs"
  "soft.cfg": "master = [HMZ_KMS_CONNECT_SOFTWARE_MASTER_KEY]"
"kind": "ConfigMap"
"metadata":
  "name": "config-map"
```

For help to define an appropriate pod structure for the current release, [contact Ripple](/products/custody/v1.19/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.