# Enclaves

_Evervault Enclaves let you deploy Docker workloads in AWS Nitro Enclaves with built‑in TLS attestation, networking and tooling._

Evervault Enclaves are the easiest way to build, deploy, and scale applications in a [confidential computing](#what-is-confidential-computing) environment. They allow developers to easily deploy Docker containers in a secure enclave, powered by AWS Nitro Enclaves. They offer easy deployment, invocation, and attestation of secure enclaves without the engineering overhead.

## What is a secure enclave?

A secure enclave — otherwise referred to as a trusted execution environment (TEE) — is a highly constrained compute environment which supports cryptographic attestation of the code that it's running. They have no persistent storage, no shell access, and no networking by default. They allow you to run sensitive workloads in completely segregated environments with heavily restricted external access.

Evervault uses secure enclaves extensively throughout our stack, and they're used to secure parts of our infrastructure which handle sensitive data and key material. This includes the Evervault Encryption Engine (E3), which is powered by AWS Nitro Enclaves.

### Why use secure enclaves?

Secure enclaves are essential for developers seeking strong security guarantees for sensitive workloads. They enable developers to ensure that their code remains untampered by malicious actors through attestation.

Secure enclaves offer all the benefits of standard containerized compute environments, such as Amazon ECS or Kubernetes, while providing additional security through attestation and significantly restricted I/O (e.g., no persistent storage and no networking by default).

Companies that often need to reassure clients about their security posture can delegate much of that responsibility to the secure enclaves architecture. This helps them secure deals with the most security-conscious customers without altering their software development processes.

More importantly, secure enclaves provide developers with the most secure method for deploying sensitive workloads. They significantly reduce the risk exposure of data, applications, and storage from insiders and third parties. As a result, they're rapidly gaining traction among security-conscious businesses and attracting substantial investment from cloud and hardware vendors like AWS, Google Cloud, and Microsoft Azure.

### The anatomy of an enclave

![An illustration of the anatomy of an enclave.]()

Evervault Enclaves are built on top of AWS Nitro Enclaves. A Nitro Enclave is an isolated set of cores on an AWS EC2 instance which provides a segregated environment for running sensitive workloads. Nitro Enclaves are only accessible from the parent EC2 instance over a local VSock channel, and they have no persistence or networking support.

Evervault Enclaves build on this by making it easy to migrate existing Docker-based workloads by abstracting away VSock, supporting optional egress networking, and exposing attestation measures that can be verified by our open source clients. An Evervault Enclave is comprised of two processes to make this possible: the control plane, and the data plane.

#### Control plane

The control plane is a daemon process which runs on the host EC2 instance. The main function of the control plane is to act as a TCP passthrough for incoming TLS connections to the enclave. The control plane also proxies any outgoing network connections for the enclave, enforcing the defined allowlist, and produces the transaction logs for the enclave.

#### Data plane

The data plane runs within the enclave as a sidecar. The data plane performs several functions to allow your process to run without any major changes:

- Proxies traffic from VSock to TCP: One of the biggest barriers to enclave adoption is the ability to use VSock with popular frameworks and languages. The data plane abstracts away the in-enclave networking and forwards incoming traffic to the loopback interface. Your process can bind to a TCP port as normal.
- Terminating TLS: The data plane provisions a trusted TLS certificate to the enclave on start-up. This certificate is used to terminate TLS on incoming connections, ensuring that your requests are only decrypted within the enclave itself.
- Authenticates requests: The data plane ensures that incoming requests have a valid Evervault API key with permissions to invoke the enclave. This feature can be disabled to support invoking the enclave from an untrusted client.
- Decrypts Evervault encrypted data: Evervault encrypted data that's sent to an enclave is transparently decrypted within the data plane before forwarding to your process. This allows you to share encrypted data with your process and handle it in plaintext.
- Enables easy attestation: The Evervault SDKs help you to ensure every request to your enclave is attested within the TLS handshake. This attestation protocol is enabled by the data plane's position in the enclave. When an Evervault client needs to attest an enclave, it pulls an attestation document from the data plane, and uses it to validate every subsequent connection. You can read more about our attestation protocol [here](/enclaves#attestation-in-tls).
- Produces request transaction logs: Running scalable, production services within an enclave can be challenging due to the lack of observability. To combat this, the data plane produces a transaction log of every request. The transaction logs cover a minimal amount of information (status code, request path, standard HTTP headers etc.) to aid debugging without eroding the secure enclave's security model. This feature is configurable, and can be disabled.

## Getting started

All accounts are enrolled in a trial which starts when you deploy your first enclave. The steps below get you up and running with a `Hello World` service, and a client capable of attesting it.

### Set up the Evervault CLI

You can install the Evervault CLI by running the following command in your terminal:

```bash
curl https://cli.evervault.com/v4/install -sL | sh
```

You will also need to have [Docker](https://docs.docker.com/get-docker/) installed on your system as the Enclaves CLI needs to perform Docker builds using the Docker CLI.

**Authenticating the CLI**

The Enclaves CLI currently only supports API key authentication. To set up a session in your terminal, you need to create a scoped app API key in the Evervault Dashboard. After you have the API key, you can authenticate the CLI by setting the following environment variables:

```bash
export EV_API_KEY=<API_KEY> export EV_APP_UUID=<APP_UUID>
```

### Initialize your enclave

To create your first enclave, you’ll need a server and a `Dockerfile`. If you don’t have one already, then you can use our [Hello, Enclave](https://github.com/evervault/hello-enclave) repository as a starting point. You can clone it by running the following command:

```bash
git clone https://github.com/evervault/hello-enclave
```

After you have a server and a `Dockerfile`, you can initialize a new Evervault Enclave using the following command:

```bash
ev enclave init -f ./Dockerfile \
                --name hello-enclave \
                --egress
```

This command generates a new `enclave.toml` [configuration file](#configuration) and registers a new enclave inside of your Evervault app.

Note that we use the `--egress` flag to allow the enclave to make outgoing network requests. This is optional, and you can omit it if you want to create an enclave that only accepts incoming requests.

> **Debug mode**
>
> During development, you may want to enable debug mode to access the logs from
>   the enclave.

### Build your enclave

Now that we have our `enclave.toml`, we can build our enclave. The build command converts the service’s `Dockerfile` into an enclave image file (`.eif`). An `.eif` file is a binary image that we'll use to initialize an AWS Nitro Enclave. All attestation measures are based on the `.eif` binary.

```bash
ev enclave build -v --output .
```

The first build can be slow (approximately 2 minutes) as the CLI has to build several Docker images. Subsequent builds should be faster because the images get cached.

After the enclave is built, its PCRs are written to the `enclave.toml` file. This helps with tracking changes in attestation measures within source control.

Our `enclave.toml` should now have a section that looks something like this at the end of it:

```toml
[attestation]
HashAlgorithm = "Sha384 { ... }"
PCR0 = "8576aa759528d6dc82b6a35504edf491bcf245266acb5745f7f15801e15988a5abbc8c637af3edeb96efcbe8e8a433a1"
PCR1 = "bcdf05fefccaa8e55bf2c8d6dee9e79bbff31e34bf28a99aa19e6b29c37ee80b214a414b7607236edf26fcb78654e63f"
PCR2 = "4ffe3d8b0211341c9eac73abccfcfed63f694a4a84b7758e70d1941d0ac6c0a7091c7860aa1ff2e4d39bbdd2b220608f"
PCR8 = "9f357c7861268d124143701d30fbd0401f4f2854db7698851c51a08bc719abe9cc89645324d24cdbac1f216b482d6ad8"
```

These four PCR values are the attestation measurements that we will use to trust the remote server (the enclave) before we share any sensitive data with it. The four measurements reflect various aspects of the image you are running in the enclave.

| PCR | Measures | Description |
| --- | --- | --- |
| PCR0 | Enclave Image File | A measure of the Image that will be run within the Enclave. |
| PCR1 | Linux Kernel and Bootstrap | A measure of the kernel and boot ramfs data. |
| PCR2 | User Application | A measure of the User Application without the boot ramfs. |
| PCR8 | Signing Certificate | A measure of the certificate used to sign the Enclave Image File. |

You can read more about attestation for enclaves [here](#attestation).

The build command will also create two files: `enclave.eif` and `ev-user.Dockerfile`. The `enclave.eif` file is the image that the enclave runs in the AWS Nitro Enclave, and the `ev-user.Dockerfile` is the Dockerfile that was used to generate it.

### Deploy your enclave

To deploy your enclave using an existing `.eif` you can run the following command:

```bash
ev enclave deploy -v --eif-path $EIF_PATH
```

The CLI tracks your enclave deployment. After the deployment has stabilized, you should see a log which includes the domain for your enclave:

```bash
Enclave deployed successfully. Your Enclave is now available at https://<enclave_name>.<app_id>.enclave.evervault.com
```

> You can build a fresh `.eif` for a deployment by omitting the `--eif-path`
>   argument. This means you can skip the `ev enclave build` step and deploy in one
>   command.

You can now call your enclave over the internet. If you deployed the Evervault `Hello, Enclave` template, you can use the following cURL command to try it out:

```bash
curl https://<enclave_name>.<app_uuid>.enclave.evervault.com/hello \
  -H "API-Key: <API_KEY>"
```

You should now see an echo response from your enclave:

```json
{
  "response": "Hello! I'm writing to you from within an enclave"
}
```

### Attest your enclave

With your enclave deployed and accessible, we can attest it to verify that its running the code we deployed.

> **Debug mode**
>
> If your enclave is running in debug mode, the attestation measures will be all
>   zeroes. We strongly advise against running in debug mode in a production
>   setting.

To attest the enclave, we'll take the PCR values that we emitted during our deployment and supply them to the Node SDK's `createEnclaveHttpsAgent` function. This function returns an HTTP Agent which can be used to validate that any connections to your enclave's hostname pass an attestation check before establishing a TLS connection.

```javascript
const AttestationBindings = require("@evervault/attestation-bindings");
const encrypted = await evervault.encrypt("Your Data");

const enclaveHttpsAgent = await evervaultClient.createEnclaveHttpsAgent(
  {
    "my-enclave": [{ pcr8: "PCR8FULLHASH" }, { pcr0: "PCR0FULLHASH" }],
  },
  AttestationBindings
);

const response = await axios.post(
  "https://my-enclave.my-app.enclave.evervault.com",
  encrypted,
  {
    httpsAgent: enclaveHttpsAgent,
  }
);
```

You can read more about attestation for enclaves [here](#attestation).

## Encryption and decryption

By design, data that is encrypted with Evervault that passes into the enclave is automatically decrypted. There is no further action required to decrypt and start using the data. If you need to manually encrypt or decrypt data within the enclave, you can use the [internal API](#internal-api).

## Internal API

Evervault exposes a simple internal API within the enclave which allows you to encrypt or decrypt Evervault encrypted strings, as well as manually retrieve an attestation document if you wish to implement your own attestation protocol. This internal API runs on port `9999` by default, and is only accessible from within the enclave.

### /encrypt

To encrypt data, you can make a request to `/encrypt`

```javascript
app.post("/keys", async (req, res) => {
  const { publicKey, privateKey } = crypto.generateKeyPair();
  const encryptedPrivateKey = await axios.post(
    "http://127.0.0.1:9999/encrypt",
    privateKey.toString("base64")
  );
  return res.json({ publicKey, encryptedPrivateKey });
});
```

### /decrypt

> By design, data that is encrypted with Evervault that passes into the enclave
>   is automatically decrypted. There is no further action required to
>   decrypt and start using the data.

The purpose of the decryption API is to offer flexibility with applications built inside the Enclave. Examples could be if you need to upload a list of large files of encrypted data to be decrypted on start up of the enclave or a process that pulls in encrypted data from an external source.

Another point to note is that when TLS termination is turned off in the data plane, it’s not possible for the request to be scanned for encrypted strings. This is another instance where the Decrypt API could be used.

```javascript
const result = await axios.post("http://127.0.0.1:9999/decrypt", {
  encrypted: "ENCRYPTED_STRING",
});
```

### /attestation-doc

To fetch the attestation document for the enclave, you can make a request to `/attestation-doc`. You can provide a challenge, nonce, and public key to be included in the attestation document. Each field is optional.

The challenge and nonce are taken as UTF-8 encoded values, and the `publicKey` is taken as a base64 encoded value.

```javascript
const response = await axios.post("http://127.0.0.1:9999/attestation-doc", {
  challenge: "abc",
  nonce: "123",
  publicKey: "def",
});
```

## Ports

By default, traffic within the enclave is forwarded to port `8008` on loopback. This can be configured by supplying an `EXPOSE` directive in your Dockerfile.

Certain ports are reserved within enclaves for internal services. In certain cases, these ports are only reserved when a feature is enabled. The reserved ports are as follows:

| Port | Reason | Feature |
| --- | --- | --- |
| 9999 | Used by the Internal API | -- |
| 53 | Used to proxy egress DNS calls | [Egress](#egress) |
| 4444 | Used to proxy egress TCP traffic | [Egress](#egress) |

## Environment variables

Environment variables can be configured using the UI or CLI. Secrets can be encrypted on creation and are made available to your enclave environment in plaintext on startup. When you create or modify an environment variable for your enclave, it only takes effect after you redeploy the enclave. You can [restart your enclave's current deployment](/sdks/cli#restart) to redeploy your existing enclave image without affecting it's PCRs.

Details on how to update your enclave's environment variables are detailed in the [Enclaves CLI reference](/sdks/cli#enclaves)

## TLS termination

TLS termination is enabled by default on your enclave. When enabled, any requests to your enclave terminate TLS within the enclave using a cert signed by a trusted CA. With TLS termination enabled, you have access to features like automatic field decryption, authentication using your Evervault API key, and transaction logging. You can disable TLS termination by setting `tls_termination=false` in your `enclave.toml` configuration file.

With TLS termination disabled, you need to terminate TLS on all incoming connections within your own process. This allows for enclaves to perform client authentication for mTLS, or to use self-signed certificates.

> If you disable TLS, you need to configure your Enclave to perform its
>   `healthcheck` on a different port to incoming traffic. This can be done using
>   the healthcheck section of the `enclave.toml` file.

## HTTP transaction logging

When TLS termination is enabled on your enclave, you can enable HTTP transaction logging which propagates request logs to the Evervault **Activity Screen** within the dashboard. These logs contain HTTP status codes, methods, timestamps etc. This can be configured within the `enclave.toml` by setting `trx_logging = false` (default is true).

A unique ID is also appended to each request. This ID can be found in the response headers under `x-evervault-ctx`. You can then search for this ID in the **Activity Screen**.

## Trusted headers

By default, your Enclave's transaction logs obfuscate any non-standard HTTP headers. You can specify a list of headers to pass through using the `trusted_headers` key in the `enclave.toml` file. This can be used to surface error codes or similar diagnostic information from your enclave. For example:

```toml
trusted_headers = ["X-Error-*", "X-Trace-Id"]
```

Certain headers cannot be trusted to avoid accidentally leaking credentials. This currently includes: `api-key`, `authorization`, and `proxy-authorization`.

## Debug mode

If you want to test your Docker Image in an enclave and see the output, you can run your enclave in `debug` mode. Transaction logs are emitted and viewable through the Evervault Dashboard. Raw logs from your enclave can be viewed using the `ev enclave logs` command in the [CLI](/sdks/cli).

> When running an enclave in Debug mode, the attestation measure returned consists entirely of zeroes. This means that an enclave in debug mode is not attestable.

## Egress

By default there is no networking out of an enclave. If you wish to make requests out of the enclave, turn on egress by including `--egress` on enclave init or update the `enclave.toml`.

You can also configure the allowed domains that requests out of the enclave should be allowed to with `--egress-destinations`. The list is enforced in both the data plane and the control plane. Requests to domains that are not explicitly allowed will fail during the DNS lookup. You can specify exact domains or wildcards to allow all subdomains, for example `enclave.evervault.com` or `*.evervault.com`. The default behavior is to allow requests to any domain but we recommend restricting them in production environments.

## Authentication

Enclaves expect an Evervault API key in the `api-key` request header by default. This can be disabled if you wish to implement your own form of authentication to the enclave. This can be useful if your enclave is exposed directly to end users.

## Healthchecks

By default, enclaves perform a shallow healthcheck. The communication between the host instance and the enclave is tested, and the enclave environment is validated to ensure that initialization completed successfully.

This healthcheck can be extended to include a `GET` to the service running in the enclave. Every second, the `Evervault-Healthcheck-Agent` sends a `GET` request to your process. Your process is regarded as healthy if it responds with a successful status code (e.g., 2XX).

You can configure your enclave to perform healthchecks on a dedicated port using the `healthcheck` section of the `enclave.toml` as shown in the toml reference below. This is particularly useful for enclaves that perform their own TLS termination.

## Concurrent request processing

By default, the data plane accepts incoming connections serially. Each connection completes its TLS handshake before the next one is accepted, so a single slow client can delay every other connection waiting behind it.

For workloads that handle many simultaneous connections, you can enable concurrent processing of connection acceptance and TLS handshakes. This improves networking performance by letting handshakes proceed in parallel instead of one at a time.

Concurrent processing is opt-in and configured through the `[acceptor]` table in your `enclave.toml`. When the table is absent, the data plane keeps its serial behavior, so existing enclaves are unaffected.

```toml
[acceptor]
# The maximum number of connections to process concurrently.
max_concurrent_connections = 1024
# The maximum number of TLS handshakes to perform concurrently.
max_concurrent_handshakes = 256
# The timeout for a single TLS handshake, in milliseconds.
handshake_timeout = 10000
```

Each field is optional:

- `max_concurrent_connections` caps the number of connections the data plane processes at once. Connections beyond this limit are terminated (meaning they aren't queued or processed at all).
- `max_concurrent_handshakes` caps the number of in-progress TLS handshakes so the enclave isn't overloaded.
- `handshake_timeout` limits how long a single TLS handshake can take, in milliseconds. Stalled handshakes are dropped after the timeout, freeing the slot for other clients.

Two rules apply when setting these values:

- Any value you set must be greater than zero.
- `max_concurrent_handshakes` must not exceed `max_concurrent_connections`. A connection is accepted before its handshake begins, so extra handshake slots can never be used.

An invalid `[acceptor]` table is rejected when you run `ev enclave init` and at build time, so misconfigurations fail fast rather than producing a broken enclave.

> Tuning the connection cap is a tradeoff. A higher cap admits more concurrent
>   clients, but each connection holds a slot for its full lifetime. Set the cap
>   based on the resources available to your enclave and your expected connection
>   volume.

## Configuration

Enclaves allow configuration to be embedded within the source code, so it is easily attestable and can't be tampered with. Simply include an `enclave.toml` file in the root of your repository and Evervault automatically includes it at build time.

The `enclave.toml` can be used to configure rules such as network egress and debug mode. It also includes dynamic attestation measures so each time your enclave is built, the PCR measures can be verified by comparing the result of the attestation with the measures included in Evervault's TLS attestation.

```toml
# The major version of Enclaves being used
version = 1
# The name of your enclave
name = "hello-enclave"

# The ID of your enclave
uuid = "<YOUR_ENCLAVE_ID>"

# The ID of the Evervault app which is hosting the enclave
app_uuid = "<APP_ID>"

# The ID of the Evervault team which owns the app
team_uuid = "<TEAM_ID>"

# Whether `debug` mode should be enabled.
# Logs are only available in `debug` mode.
debug = true

# Whether API key auth is enabled for the enclave
api_key_auth = true

# Whether transaction logging is enabled for the enclave.
# Note: Requires TLS termination to be enabled
trx_logging = true

# Define a list of headers to ignore during obfuscation of transaction logs.
# Supports absolute matches and suffix wildcards.
trusted_headers = ["X-Error-*", "X-Trace-Id"]

# Turn off TLS termination in the data plane.
# Note: you will have to handle TLS termination within your process.
tls_termination = false

# Enables forwarding proxy protocol when TLS termination is disabled.
# Note: this prepends incoming requests with the binary proxy protocol.
# If your in-enclave process does not expect proxy protocol, it will likely fail to parse requests.
forward_proxy_protocol = false

# The path to your enclave's `Dockerfile`
dockerfile = "Dockerfile"

# Whether or not to enable outbound network requests from your enclave
# If enabled, the networking layer will be bundled at build time
[egress]
enabled = true
destinations = ["*.evervault.com"]

# Configuration for the in-enclave healthcheck.
[healthcheck]
# An endpoint exposed by your service to track its health within the enclave.
# This endpoint will receive a `GET` request every second.
# The healthcheck's user agent will be: "Evervault-Healthcheck-Agent"
path = "/health"
# The port that the healthcheck is being exposed on.
# If unset, the healthcheck will be sent over the same port as incoming requests.
port = 8081

# The amount of replicas you would like to run for your enclave.
# Note: If only running one replica, there will be downtime
# between deployments. (Default 2)
[scaling]
desired_replicas=2

# Opt-in configuration for concurrent connection acceptance and TLS handshakes.
# If unset, the data plane accepts connections serially.
[acceptor]
# The maximum number of connections to process concurrently.
max_concurrent_connections = 1024
# The maximum number of TLS handshakes to perform concurrently.
max_concurrent_handshakes = 256
# The timeout for a single TLS handshake, in milliseconds.
handshake_timeout = 10000

# The configuration for your in-enclave service.
# If unset, the port will be taken as the last exposed port in the Dockerfile.
[service]
port = 8080

# The path to the signing key and certificate for your enclave
[signing]
certPath = "~/.ev/enclaves/cert.pem"
keyPath = "~/.ev/enclaves/key.pem"
```

## Best practices

### Writing the Dockerfile

Since enclaves are built using Docker, a good place to start is making sure that you are [formatting your Dockerfile correctly](https://docs.docker.com/develop/develop-images/dockerfile_best-practices/).

First you need to use the `FROM` command which creates a layer from the Docker image you want to use. It’s best to use one of the container images available on [Docker Hub](https://hub.docker.com/) to ensure you are using a trusted source. You can also opt for using the `slim` version of the container which can help reduce the image size, however the `slim` versions may not contain all of the common packages in the default tag.

```
FROM node:16-alpine3.16-slim
```

Next you need to copy any files from your local source to the filesystem of the container. It’s best to use absolute paths in the Dockerfile. When your Docker container is converted to an enclave, your commands might not be run in the directory you expect them to be, so it is safer to reference your files as absolute paths.

```
COPY ./index.js /index.js
COPY ./package.json /package.json
COPY ./package-lock.json /package-lock.json
```

Make sure that you are exposing the non-reserved port you want to listen on since that is where traffic within the enclave is forwarded. The enclaves documentation uses PORT `8008` as an example, but this can be any available port that you define.

```
EXPOSE 8008
```

Here are some examples of what your Dockerfile might look like.

### Dependency management

Some of the instructions in your Dockerfile install required packages. You can use whichever package manager makes sense for your application.

In some cases, you may want to use a manifest file that contains the required packages and their versions, like a `package.json` for Node or `requirements.txt` for Python.

For Python specifically, it can also be helpful to use a [virtual environment](https://docs.python.org/3/library/venv.html). You can run the virtual environment within the container and then install the packages within the environment. This also helps with minimizing image size.

Here is an example:

```
FROM python:3.8-slim

RUN python3 -m venv /opt/venv
COPY requirements.txt requirements.txt
RUN /opt/venv/bin/pip install -r requirements.txt

COPY app.py /app.py

EXPOSE 8008

ENTRYPOINT ["/venv/bin/python", "/app.py"]
```

## What is confidential computing?

Confidential computing allows teams to run their services in highly constrained compute environments, known as secure enclaves. While confidential computing can take many forms, they typically share two common features — restricted I/O and attestation. These two features are powerful building blocks in creating trustworthy, and secure services.

### Restricted I/O

Secure enclaves have no persistent storage which dramatically reduces the attack surface for data exposure. They also prevent external access — meaning there’s no way for an attacker to gain direct access to a service at runtime. The only interface that the secure enclave exposes is the API that your service offers.

### Attestation

Attestation is a way for the integrity of a service running in a secure enclave to be validated at runtime. This offers teams a guarantee that they're talking to a known version of their service.

In practice, attestation is typically a two step process. Before a service is deployed to a secure enclave, it's measured and signed. Measuring the service involves computing checksums over the bundle that's deployed, and the signature allows teams to lock down deployments to trusted sources (e.g., environments that can sign the bundle using a known private key).

When a client interacts with the service, they can request the attestation document and validate that it contains the expected checksums, and is signed by a known key pair.

Allowing clients to verify the integrity of services that process sensitive data, can massively improve the security of a system by preventing sensitive data from being leaked to unknown or untrusted deployments.

The Evervault Client SDKs for [Node](/sdks/node), [Python](/sdks/python), [Go](/sdks/go), [iOS](/sdks/ios), and [Android](/sdks/android) all expose attestation helpers which perform attestation on every connection to your enclave. This is done by pulling an attestation document from the enclave, and comparing its signed PCRs against the set of PCRs provided to the SDKs. If the PCRs are found to match, the challenge from the attestation document is compared against the certificate public key to confirm that the TLS connection is being terminated inside the enclave.

You can then validate it locally using the `ev enclave attest` command in the CLI. This validates that the PCRs in the `enclave.toml` file match the PCRs returned in the handshake.

The attestation doc for an enclave is publicly accessible through the `/.well-known/attestation` endpoint. This allows the Evervault SDKs to poll the attestation document and detect any changes resulting from deployments.

You can request the attestation document using the following curl command:

```bash
curl https://<enclave_name>.<app_uuid>.enclave.evervault.com/.well-known/attestation-doc
```

#### Attestation in TLS

Attesting a remote server can be difficult to get right, but can be extremely powerful. Evervault Enclaves embed the attestation check within the TLS handshake. This ensures that, when using an Evervault client, you cannot connect to an enclave that fails attestation.

##### CA provisioning

![A flowchart diagram of the CA provisioning flow]()

When your enclave boots within Evervault's infrastructure for the first time, it generates a key pair to use for terminating TLS. The public key for this pair is then used to create an order with a trusted CA using the ACME process. The generated private key never leaves the enclave in plaintext. The Evervault managed process that runs on the host EC2 instance forwards this ACME order to the trusted CA. The trusted CA then returns an ACME challenge which is used to prove ownership over the requested domain. The enclave begins to poll the order status with the trusted CA, which eventually resolves to the issued cert.

The ACME challenge, the generated public key, and the encrypted private key are uploaded to an AWS S3 bucket by the host process. This allows us to reuse the same key pair across deployments of your enclave, and speeds up subsequent deployments.

The trusted CA then sends an HTTP challenge to the enclave's domain. This is routed to an Evervault managed service, which maps the challenge request to the challenge value stored in S3. We serve the challenge in the response to the trusted CA who then issues an end-entity certificate for our enclave.

The order status being polled then resolves with a link to the location of our newly issued certificate. The enclave downloads the certificate and can use it to begin terminating TLS. The enclave also uploads this certificate to S3 via the host process to allow subsequent deployments, or other instances of the enclave to download and reuse the same certificate.

##### Performing attestation from the client

![A flowchart diagram of the attestion flow]()

Now that the enclave has a trusted TLS certificate, we can walk through the process of how a client attests the enclave.

First, when initializing a client, you map a set of enclave names to accepted PCRs. While the implementation differs based on the language being used, the client begins intermittently polling the enclave hostnames in the background. The polling requests hit the publicly available `/.well-known/attestation` endpoint which returns an attestation document. These attestation documents are then stored in an in-memory cache which is checked on every enclave call.

So, when a client is sending a request to an enclave, it begins by performing a standard TLS handshake:

- Validates the hostname corresponds with the requested domain
- Validates that there is a valid trust chain going back to a trusted root CA.

The client then attests the connection:

- Checks the attestation document Cache for the requested enclave.
- Validates the signature over the attestation document against the public AWS Nitro CA.
- Validates that the embedded PCRs match a set of PCRs given to the client on initialization — the remote Enclave is running the expected service.
- Confirms that the public key of the server cert is embedded within the attestation document.

After all of the above checks have passed, the client can begin sending sensitive data into the enclave. This guarantees that the data is sent over a TLS connection directly to the enclave which is running the expected code.

## Enclaves trial

All accounts are enrolled in a trial which starts when you deploy your first enclave. The terms of the trial are given below.

### How long is the trial program?

Starting from the day you deploy your first enclave, you have full access to the Evervault platform (free plan) and enclaves for 14 days, so you can try building and deploying enclaves. After that period, you’ll have the option to sign up for monthly pricing to continue testing.

If you’re unsure how long you have — you can always check the countdown timer in your Evervault Dashboard to see how much time is left in the allotment. If you need to adjust the timing or have any questions regarding the trial, feel free to reach out to our team.

### How many enclaves can I create?

During the 14 day trial period, a team can run one Enclave. Enclaves are run as a single instance which may cause downtime for deployments, however this is only for your trial period.

Following the initial trial, if you upgrade to a paid plan and start using enclaves in production, we will provide multiple instances with high availability and zero downtime deployments.

### What happens during the trial?

You can play around with enclaves to see if it fits your use-case, free of charge. [Start here](#getting-started) if you’re not sure where to get started.

We would love to know more about the use cases you are building for, any errors or bugs you encounter, and any feedback you have. You can contact us at [support@evervault.com](mailto:support@evervault.com).

### What happens after the trial?

At the end of the 14-day period, we’ll notify you that your trial access has ended, and any active enclaves will be deactivated.

Once deactivated, you will no longer be able to send requests to your enclave but it will remain visible in the Evervault Dashboard. If at any time you’d like to continue using enclaves, you can upgrade to a paid plan and we will restart your enclave instances.

Upgrading to the paid plan will give you access to all of the [Evervault Pro](https://evervault.com/pricing) features and allow you to run multiple enclave instances with high availability and zero downtime deployments.

## Frequently asked questions

##### What is an AWS Nitro Enclave?

[AWS Nitro Enclaves](https://aws.amazon.com/ec2/nitro/nitro-enclaves/) is a product from Amazon Web Services that allows you to create isolated Amazon EC2 instances with all of the security characteristics of a Secure Enclave.

    AWS Nitro Enclaves is available by default to customers of Amazon EC2, but building, deploying and scaling Nitro Enclaves can be a major time investment for engineering teams that have competing priorities.

##### How can I access the client IP address?

There are two ways to see the original IP on the connection.

    When using TLS termination, the IP is included in the HTTP `X-Forwarded-For` header.

    If you have TLS termination disabled, you can receive the client IP via proxy protocol by setting the `FORWARD_PROXY_PROTOCOL` environment variable in your enclave.

##### How large can an enclave be?

The current limit for enclaves is `16 vCPUs` and `64 gigabytes` of RAM. For trial usage, enclaves are capped at `4 vCPUs` and `16 gigabytes` of RAM.

    Enclaves use a RAM-based filesystem. This means that the memory allocated to your enclave is used for both storage and RAM.

##### Can I run an enclave on my own infrastructure?

Evervault Enclaves are managed and run by Evervault on our infrastructure. A major advantage of using Enclaves is that the burden of hosting and scaling all of the infrastructure necessary to run secure enclaves is handled by Evervault.

    Evervault running your enclaves doesn't weaken the security guarantees provided by secure enclaves, thanks to attestation. You are still provided with the attestation measure at build-time and can verify that these haven't been tampered with — all within the TLS handshake.

##### Can I run multiple instances of an enclave?

Yes, the number of instances an enclave runs on can be configured using the `desired_replicas` option in the `enclave.toml`. The EC2 instances running the enclave are split between two availability zones in a region for greater resiliency.

    During the trial period, enclaves run as a single instance. During this time, deployments result in downtime.

##### Can I restart my enclave?

Enclaves can be restarted from either the **Versions** tab in the **Enclaves** section of the dashboard or by using the [CLI](/sdks/cli).

##### Why does my enclave perform decrypt requests on start-up?

Enclaves order a trusted TLS certificate on their first deployment. The private key is encrypted in the enclave, and backed-up so it can be loaded in on every subsequent start-up. As a result, when each instance of the enclave launches, they perform a single decrypt request to load in their private key in plaintext.

