{"templateId":"markdown","sharedDataIds":{"sidebar":"sidebar-products/wallet/sidebars.yaml"},"props":{"metadata":{"markdoc":{"tagList":["admonition"]},"type":"markdown"},"seo":{"title":"Run CloudSign in AWS Nitro Enclaves","description":"User guides, API reference, and support resources.","siteUrl":"https://docs.ripple.com","lang":"en-US","llmstxt":{"hide":false,"sections":[{"title":"Table of contents","includeFiles":["**/*"],"excludeFiles":[]}],"excludeFiles":[]}},"dynamicMarkdocComponents":[],"compilationErrors":[],"ast":{"$$mdtype":"Tag","name":"article","attributes":{},"children":[{"$$mdtype":"Tag","name":"Heading","attributes":{"level":1,"id":"run-cloudsign-in-aws-nitro-enclaves","__idx":0},"children":["Run CloudSign in AWS Nitro Enclaves"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["You can run CloudSign inside an AWS Nitro Enclave — an isolated compute environment with no persistent storage, no interactive access, and no direct network connectivity. The enclave isolates the CloudSign node and its key material from the host EC2 instance."]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["This guide assumes you have already created CloudSign devices and recorded their pairing keys. See ",{"$$mdtype":"Tag","name":"MarkdownLink","attributes":{"href":"/products/wallet/user-interface/devices/set-up-and-run-cloudsign"},"children":["Set up and run CloudSign"]},"."]},{"$$mdtype":"Tag","name":"Admonition","attributes":{"type":"warning","name":"New devices only"},"children":[{"$$mdtype":"Tag","name":"p","attributes":{},"children":["An existing CloudSign device that has already paired can't be moved into an enclave. To run CloudSign in a Nitro Enclave, create a new device in the console and pair it from inside the enclave."]}]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":2,"id":"how-it-works","__idx":1},"children":["How it works"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["A Nitro deployment has three components:"]},{"$$mdtype":"Tag","name":"ul","attributes":{},"children":[{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["CloudSign enclave image"]}," — The CloudSign node, packaged as an Enclave Image File (EIF) that runs inside the enclave."]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Networking proxy (",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["tacos"]},")"]}," — A systemd service on the host that tunnels the enclave's traffic between a virtual network interface and the enclave's vsock channel, because the enclave has no network interface of its own."]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Configuration server (",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["servitor"]},")"]}," — A small service on the host that serves the node's configuration to the enclave over HTTP on port ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["3000"]},". The enclave fetches its configuration once at startup."]}]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["In Nitro mode, CloudSign requires a PostgreSQL database — the local storage option isn't available inside an enclave."]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["The EC2 instance requires no inbound network connectivity — the enclave only makes outbound connections through the host. You can apply firewall rules that block all inbound traffic to the instance."]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":2,"id":"prerequisites","__idx":2},"children":["Prerequisites"]},{"$$mdtype":"Tag","name":"ul","attributes":{},"children":[{"$$mdtype":"Tag","name":"li","attributes":{},"children":["An EC2 instance with Nitro Enclaves enabled — for example, ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["m5.xlarge"]}," — running Amazon Linux 2023."]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":["Docker, and the AWS Nitro Enclaves CLI (",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["aws-nitro-enclaves-cli"]}," and ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["aws-nitro-enclaves-cli-devel"]},"). Add your user to the ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["docker"]}," and ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["ne"]}," groups."]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":["The Nitro allocator (",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["/etc/nitro_enclaves/allocator.yaml"]},") configured with at least 1 GB of memory and 2 CPU cores. Restart the ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["nitro-enclaves-allocator"]}," service after you change this file."]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":["Access credentials for the Wallet-as-a-Service container registry (provided by Ripple)."]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":["A PostgreSQL database reachable from the host."]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":["An AWS KMS key ARN for database encryption (",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["DB_ENCRYPTION_KEY_REF"]},")."]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":["A CloudSign pairing key from the console."]}]},{"$$mdtype":"Tag","name":"Admonition","attributes":{"type":"info","name":"Component versions"},"children":[{"$$mdtype":"Tag","name":"p","attributes":{},"children":["The CloudSign Nitro image, ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["tacos"]},", and ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["servitor"]}," versions must be compatible with each other. Confirm the current version set with your Ripple representative before deployment, and use it in place of ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["<version>"]}," below."]}]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":2,"id":"1-pull-the-cloudsign-nitro-image","__idx":3},"children":["1. Pull the CloudSign Nitro image"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Sign in to the Wallet-as-a-Service container registry, then pull the Nitro image:"]},{"$$mdtype":"Tag","name":"CodeBlock","attributes":{"data-language":"shell","header":{"controls":{"copy":{}}},"source":"aws ecr get-login-password --region eu-west-2 | docker login --username AWS --password-stdin 335650072995.dkr.ecr.eu-west-2.amazonaws.com\n\ndocker pull 335650072995.dkr.ecr.eu-west-2.amazonaws.com/external/custody/cloudsign-nitro/app:<version>\n","lang":"shell"},"children":[]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":2,"id":"2-install-the-networking-proxy","__idx":4},"children":["2. Install the networking proxy"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Install ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["socat"]},", then install and start the ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["tacos"]}," service. The proxy runs on the host and forwards the enclave's traffic on ports ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["8080"]}," and ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["9080"]},":"]},{"$$mdtype":"Tag","name":"CodeBlock","attributes":{"data-language":"shell","header":{"controls":{"copy":{}}},"source":"sudo yum install -y socat\nsudo systemctl enable tacos.service --now\n","lang":"shell"},"children":[]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Wallet-as-a-Service distributes the ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["tacos"]}," binary and its systemd unit file as release artifacts — your Ripple representative can point you to the download for your version."]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":2,"id":"3-build-the-enclave-image-file","__idx":5},"children":["3. Build the enclave image file"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Build the EIF from the Docker image:"]},{"$$mdtype":"Tag","name":"CodeBlock","attributes":{"data-language":"shell","header":{"controls":{"copy":{}}},"source":"nitro-cli build-enclave \\\n  --docker-uri 335650072995.dkr.ecr.eu-west-2.amazonaws.com/external/custody/cloudsign-nitro/app:<version> \\\n  --output-file ~/cloudsign-<version>.eif\n","lang":"shell"},"children":[]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":2,"id":"4-install-and-run-the-configuration-server","__idx":6},"children":["4. Install and run the configuration server"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Install the ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["servitor"]}," binary (also distributed as a release artifact) to ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["/usr/local/bin/servitor"]},", then run it with the node's configuration:"]},{"$$mdtype":"Tag","name":"CodeBlock","attributes":{"data-language":"shell","header":{"controls":{"copy":{}}},"source":"PAIRING_KEY=<pairing-key> \\\nDB_ENCRYPTION_KEY_REF=<kms-key-arn> \\\nDB_DATA_SOURCE='postgres://user:password@host:5432/cloudsign?sslmode=require' \\\nTSM_DB_DATA_SOURCE='postgres://user:password@host:5432/cloudsign?sslmode=require' \\\nservitor\n","lang":"shell"},"children":[]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["The server listens on port ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["3000"]}," and serves the configuration to the enclave. ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["SIGN_MODE_ACTIVE"]}," (default ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["true"]},") and ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["LOG_LEVEL"]}," are optional."]},{"$$mdtype":"Tag","name":"Admonition","attributes":{"type":"warning","name":"Protect the configuration"},"children":[{"$$mdtype":"Tag","name":"p","attributes":{},"children":["The configuration contains the pairing key and database credentials. If you store it in a file, restrict its permissions (for example, ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["chmod 600"]},") and don't commit it to source control."]}]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":2,"id":"5-run-the-enclave","__idx":7},"children":["5. Run the enclave"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Restart the proxy, then launch the enclave with the resources you allocated:"]},{"$$mdtype":"Tag","name":"CodeBlock","attributes":{"data-language":"shell","header":{"controls":{"copy":{}}},"source":"sudo systemctl restart tacos.service\n\nnitro-cli run-enclave \\\n  --eif-path ~/cloudsign-<version>.eif \\\n  --cpu-count 2 \\\n  --memory 1024 \\\n  --enclave-cid 5\n","lang":"shell"},"children":[]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["At startup, the enclave fetches its configuration from the host's configuration server and pairs with the platform. The device in the console moves to ",{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Waiting for approval"]},", and setup continues as in the ",{"$$mdtype":"Tag","name":"MarkdownLink","attributes":{"href":"/products/wallet/user-interface/devices/set-up-and-run-cloudsign#approve-cloudsign-devices"},"children":["standard flow"]},": approve the device, create a quorum, and create wallets."]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["To see the enclave's console output while debugging, add ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["--attach-console"]}," to the ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["run-enclave"]}," command."]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":2,"id":"troubleshooting","__idx":8},"children":["Troubleshooting"]},{"$$mdtype":"Tag","name":"div","attributes":{"className":"md-table-wrapper"},"children":[{"$$mdtype":"Tag","name":"table","attributes":{"className":"md"},"children":[{"$$mdtype":"Tag","name":"thead","attributes":{},"children":[{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"th","attributes":{"data-label":"Problem"},"children":["Problem"]},{"$$mdtype":"Tag","name":"th","attributes":{"data-label":"Cause"},"children":["Cause"]},{"$$mdtype":"Tag","name":"th","attributes":{"data-label":"Solution"},"children":["Solution"]}]}]},{"$$mdtype":"Tag","name":"tbody","attributes":{},"children":[{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"td","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["nitro-cli run-enclave"]}," fails with insufficient resources"]},{"$$mdtype":"Tag","name":"td","attributes":{},"children":["Allocator not configured or not restarted"]},{"$$mdtype":"Tag","name":"td","attributes":{},"children":["Check ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["/etc/nitro_enclaves/allocator.yaml"]}," reserves at least 1 GB and 2 CPUs; restart ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["nitro-enclaves-allocator"]}]}]},{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"td","attributes":{},"children":["Enclave starts but the device doesn't pair"]},{"$$mdtype":"Tag","name":"td","attributes":{},"children":["Configuration server or proxy not running"]},{"$$mdtype":"Tag","name":"td","attributes":{},"children":["Verify ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["servitor"]}," is running on port 3000 and ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["tacos.service"]}," is active; then restart the enclave"]}]},{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"td","attributes":{},"children":["Enclave can't reach the platform"]},{"$$mdtype":"Tag","name":"td","attributes":{},"children":["Blocked egress from the host"]},{"$$mdtype":"Tag","name":"td","attributes":{},"children":["The enclave's traffic egresses through the host — apply the ",{"$$mdtype":"Tag","name":"MarkdownLink","attributes":{"href":"/products/wallet/user-interface/devices/set-up-and-run-cloudsign#network-requirements"},"children":["network requirements"]}," to the host instance"]}]}]}]}]}]},"headings":[{"value":"Run CloudSign in AWS Nitro Enclaves","id":"run-cloudsign-in-aws-nitro-enclaves","depth":1},{"value":"How it works","id":"how-it-works","depth":2},{"value":"Prerequisites","id":"prerequisites","depth":2},{"value":"1. Pull the CloudSign Nitro image","id":"1-pull-the-cloudsign-nitro-image","depth":2},{"value":"2. Install the networking proxy","id":"2-install-the-networking-proxy","depth":2},{"value":"3. Build the enclave image file","id":"3-build-the-enclave-image-file","depth":2},{"value":"4. Install and run the configuration server","id":"4-install-and-run-the-configuration-server","depth":2},{"value":"5. Run the enclave","id":"5-run-the-enclave","depth":2},{"value":"Troubleshooting","id":"troubleshooting","depth":2}],"frontmatter":{"title":"Run CloudSign in AWS Nitro Enclaves","seo":{"title":"Run CloudSign in AWS Nitro Enclaves"}},"lastModified":"2026-08-19T17:59:32.000Z","pagePropGetterError":{"message":"","name":""}},"slug":"/products/wallet/user-interface/devices/run-cloudsign-in-aws-nitro-enclaves","userData":{"isAuthenticated":false,"teams":["anonymous"]},"isPublic":true}