Enclaves
Evervault Enclaves are the easiest way to build, deploy, and scale applications in a 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 an 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 is 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 are 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 are 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
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/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 this Enclave. Note: this feature can be disabled to support invoking the Enclave from an untrusted client.
- Decrypts Evervault Encrypted Data: Evervault encrypted data that is sent to an Enclave will be 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.
- 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. Note: this feature is configurable, and can be disabled.
Getting Started
All accounts are enrolled in an Enclaves Trial which starts when you deploy your first Enclave. The steps below will get you up and running with a simple Hello World service, and a client capable of attesting it.
Setup the Evervault CLI
You can install the Evervault CLI by running the following command in your terminal:
You will also need to have 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 setup a session in your terminal, you will first need to create a scoped App API Key in the Evervault Dashboard. Once you have created the API Key, you can authenticate the CLI by setting the following environment variables:
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! repository as a starting point. You can clone it by running the following command:
Once you have a server and a Dockerfile, you can initialize a new Evervault Enclave using the following command:
This command will generate a new enclave.toml configuration file and register 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 will convert 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.
The first build will be slow (approximately 2 minutes) as the CLI has to build several Docker images. Subsequent builds should be faster once the images have been cached.
Once the Enclave has finished building, the Enclave PCRs will be written to the enclave.toml file. This will help 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:
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 | Mesaures | 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.
The build command will also create two files: enclave.eif and ev-user.Dockerfile. The enclave.eif file is the image that the Enclave will run 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:
The CLI will track your Enclave deployment. Once the deployment has stabilized, you should see a log which includes the domain for your Enclave:
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:
You should now see an echo response from your 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 a 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.
You can read more about attestation for Enclaves here.
Encryption / Decryption
By design, data that is encrypted with Evervault that passes into the Enclave will automatically be 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
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
/decrypt
By design, data that is encrypted with Evervault that passes into the Enclave will automatically be 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.
/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.
Ports
By default, traffic within the Enclave will be 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 |
| 4444 | Used to proxy egress TCP traffic | Egress |
Environment Variables
Environment Variables can be configured using the UI or CLI. Secrets can be encrypted on creation and will be made available to your Enclave environment in plaintext on startup. When you create or modify an Environment Variable for your Enclave, it will only take effect once you redeploy the Enclave. You can restart your Enclave's current deployment 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
TLS Termination
TLS termination is enabled by default on your Enclave. When enabled, any requests to your Enclave will terminate TLS within the enclave using a cert signed by a Trusted CA. With TLS termination enabled, you will 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 will 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 will 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 will propagate 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 will 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. This can be used to surface error codes or similar diagnostic information from your Enclave. For example:
Note: 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 a Enclave and see the output, you can run your Enclave in debug mode. Transaction Logs will be emitted and viewable through the Evervault Dashboard. Raw logs from your Enclave can be viewed using the ev enclave logs command in the CLI.
When running an Enclave in debug mode, the attestation measure returned will consist entirely of zeroes. This means that a 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 will be 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 your End-Users.
Healthchecks
By default, Enclaves will perform a shallow healthcheck. The communication between the host instance and the Enclave will be tested, and the Enclave environment will be validated to ensure that the Enclave 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 will send a GET request to your process. Your process will be regarded as healthy if it responds with a successful status code (i.e. 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 which are performing their own TLS Termination.
Configuration
Enclaves allows 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 will automatically include 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.
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.
First you need to use the FROM command which will create a layer from the Docker image you wish to use. It’s best to use one of the container images available on Docker Hub 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.
Next you will 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.
Make sure that you are exposing the non-reserved port you want to listen on since that is where traffic within the Enclave will be forwarded. The Enclaves documentation uses PORT 8008 as an example, but this can be any available port that you define.
Here are some examples of what your Dockerfile might look like.
Dependency Management
Some of the instructions in your Dockerfile will 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 will contain 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. You can run the virtual environment within the container and then install the packages within the environment. This will also help with minimizing image size.
Here is an example:
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 trustable, and secure services.
Restricted I/O
Secure Enclaves have no persistent storage which dramatically reduces the attack surface for data exposure. Additionally, Secure Enclaves 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 are 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 is ‘measured’ and signed. Measuring the service involves computing checksums over the bundle that will be deployed, and the signature allows teams to lock down deployments to trusted sources (i.e. environments that can sign the bundle using a known private key).
Then, when a client interacts with the service, they can request the Attestation Document/Evidence 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/untrusted deployments.
The Evervault Client SDKs for Node, Python, Go, iOS, and Android all expose attestation helpers which will 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 will validate 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:
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

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. Note: 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 will be used to prove ownership over the requested domain. The Enclave begins to poll the order status with the Trusted CA, which will eventually resolve 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 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 will then resolve 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

Now that the Enclave has a trusted TLS Certificate, we can walk through the process of how a client will attest 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 will begin intermittently polling the Enclave hostnames in the background. The polling requests will 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.
Once 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 will 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 will run as a single instance which may cause downtime for deployments, however this is only for your trial period.
Following 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 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.
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 easily 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 features and allow you to run multiple Enclave instances with high availability and zero downtime deployments.