Deploy a Hello, World! Cage

Cages are an Evervault Primitive which allow teams to easily deploy existing Docker containers into Secure Enclaves, managed by Evervault.

Cages are built on top of Nitro Enclaves, the AWS Trusted Execution Platform built on top of EC2. Nitro Enclaves offer all of the foundational properties of a Secure Enclave (as discussed in the Overview). Cages abstract away the complexity of building, deploying, and scaling Nitro Enclaves as well as supporting Attestation in every request.

This guide will walk you through deploying a basic Hello, World! example Node API to Cage.

Prerequisites

Before you get started, you’ll need an Evervault account. You can sign up for one here. Once you sign up, you will have 2 weeks of trial access to Cages. During the trial period, you can deploy a Cage to 2 instances - this can be distributed across 2 distinct Cages, or both instances can be allocated to a single Cage.

TL;DR

  • Install the CLI: curl https://cage-build-assets.evervault.com/cli/install -sSL | sh
  • Clone the repo: git clone https://github.com/evervault/hello-cage.git
  • Initialize your Cage in the hello-cage directory: ev-cage init -f ./Dockerfile --name hello-cage --debug --egress --healthcheck /health
  • Deploy your Cage: ev-cage deploy
  • Attest your Cage: ev-cage attest
  • Invoke your Cage: curl https://hello-cage.<app_uuid>.cage.evervault.com/hello

Install the CLI

To start, you’ll need to install the Cages CLI. This will let you manage your Cages, and deploy them from your machine or from CI.

1
curl https://cage-build-assets.evervault.com/cli/install -sSL | sh

You can verify that the installation was successful by running the ev-cage CLI command without any subcommand:

1
ev-cage

Initialize your Cage

Once you have the CLI installed, you’ll need to clone the hello-cage sample repo:

1
git clone https://github.com/evervault/hello-cage.git

Then cd into the freshly cloned repo:

1
cd hello-cage

This repo contains a simple Node express app, and a simple Dockerfile which exposes the Node App on port 8008.

Before we use the CLI, we’ll need to get our environment prepped to authenticate with the API. The easiest way to do that is to run export your API Key in your shell:

1
export EV_API_KEY=your-api-key

Once that’s done, we’re ready to initialize your Cage. We’ll run the ev-cage init command. The command takes a series of flags that are used to setup your Cage’s config:

1
ev-cage init -f ./Dockerfile --name hello-cage --egress --healthcheck /health
  • -f tells the Cage CLI where to find the Dockerfile from our service. The CLI uses this Dockerfile as a base for all Cage build and deployments
  • --name defines the name of our Cage, which we will use later when sending requests to it
  • --egress bootstraps our Secure Enclave Environment with the ability to send network requests to the public internet. When this flag is not set the Secure Enclave has no ability to send requests anywhere, it can only respond to requests that it receives.
    • We can further scope our egress permissions within the Cage using the --egress-ports to define the ports we want to send traffic on (defaults to 443), and --egress-destinations to restrict the allowed hostnames.
  • --healthcheck defines the path in our service that should be used as the Cage’s healthcheck.

This is not an exhaustive list of the options supported in the init command. You can find out more by running ev-cage init --help.

You can see the complete config that was generated for your Cage by looking at the cage.toml file. It should look something like this:

1
name = "hello-cage"
2
uuid = "<YOUR_CAGE_ID>"
3
app_uuid = "<APP_ID>"
4
team_uuid = "<TEAM_ID>"
5
debug = true
6
dockerfile = "Dockerfile"
7
healthcheck = "/health"
8
9
[egress]
10
enabled = true
11
ports = ["443"]
12
13
[scaling]
14
desired_replicas = 2
15
16
[signing]
17
certPath = "~/.ev/cages/cert.pem"
18
keyPath = "~/.ev/cages/key.pem"

Once we’re happy with the Cage config, we can move on to building and deploying our Cage.

Build your Cage

While the services to run in Cages are built using Dockerfiles, the file used during deployment is an EIF. An EIF is an Enclave Image File. When we run the build command, we will generate an EIF which we can then use to deploy the Cage.

Deployments don’t require an explicit build step. You can deploy a Cage without running the build command first using ev-cage deploy. However, it is useful to see the files generated during our build step.

To build the Cage, we can run:

1
ev-cage build --output .

To build the Cage, the CLI updates the provided Dockerfile and embeds an Evervault maintained runtime. This runtime abstracts away the complexities of the Secure Enclave from our service, allowing us to continue writing our Node app as normal. The runtime also provides some useful features such as provisioning a trusted certificate for terminating TLS, tracking the requests to the Cage, and, optionally, allowing our Secure Enclave to speak to specific hosts on the public internet.

This build may take a while, as the Cage CLI has to build multiple Docker images (this is to support building an EIF across a wider range of hosts).

Once the build is finished, we should see that an EIF file was generated in our current directory. We will use this file to deploy the Cage in our next step.

Looking at our cage.toml, there should be a new attestation section which contains the measurements of our image that we can use as an integrity check at runtime:

1
[attestation]
2
HashAlgorithm = "Sha384 { ... }"
3
PCR0 = "..."
4
PCR1 = "..."
5
PCR2 = "..."
6
PCR8 = "..."

These PCR values each correspond to a measurement of a specific part of the image being deployed:

PCRMeasuresExplanation
PCR0Enclave Image FileA measure of the Image that will be run within the Cage
PCR1Linux Kernel and BootstrapA measure of the kernel and boot ramfs data
PCR2User ApplicationA measure of the User Application without boot ramfs
PCR8Signing CertificateA measure of the certificate used to sign the Enclave Image File

Deploy your Cage

To deploy the Cage from the EIF generated from the build command, we can run:

1
ev-cage deploy --eif-path ./enclave.eif

The CLI will track the progress of your deployment and update you as it moves through the deployment process. When the deployment is complete, the CLI will log a message that includes the domain of the Cage:

1
Cage deployed successfully. Your Cage is now available at https://hello-cage.<app-uuid>.cage.evervault.com

Attest your Cage

Now that your Cage is running, you can attest it using the CLI:

1
ev-cage attest --eif-path ./enclave.eif

This will verify that the measurements taken from the ./enclave.eif file match those of the Cage running in AWS, and that the Cage is in fact running in a Secure Enclave.

When interacting with a Cage from a production client, the Evervault SDKs will handle the attestation process for you on each request.

Invoke your Cage

We can verify that the Cage is reachable by cURLing the domain given by the deploy command:

1
curl https://hello-cage.<app-uuid>.cage.evervault.com/hello -H 'Api-Key: <Your Evervault Api Key>'

You should see the cage respond with:

1
{ "response": "Hello! I'm writing to you from within an Enclave." }

Summary

This guide walked through the process of taking a basic Node.js Express app and deploying it into a Secure Enclave. With our Express app deployed into the Secure Enclave, we were able to verify the integrity of our service and still cURL it as normal.