Attestation is a central feature of secure enclaves. It offers a cryptographic guarantee of the remote enclave's integrity — the server you're speaking to is exactly as expected.
Attesting a remote server can be difficult to get right, but can be extremely powerful. Evervault Cages embed the attestation check within the TLS handshake. This ensures that, when using an Evervault client, you cannot connect to a Cage that fails attestation.
To do this, Cages use an Evervault signed root CA and generate an attestable leaf cert. The Evervault SDKs will then download the root CA public key and validate both the cert itself, and the embedded attestation document.
When your Cage boots within Evervault's Infrastructure, it performs a handshake with an Evervault managed provisioning server. The Evervault managed process that runs on the host EC2 instance connects to the provisioner over mTLS. The provisioner is then able to produce a signed token for that Cage to use to request its secrets over an attested connection.
The process on the host then sends the signed token into the Enclave over VSock. The Evervault Data Plane within the Enclave embeds the token into an attestation document. It then opens a connection to the provisioner via the host process and performs a TLS handshake. Once TLS is established, the Data Plane sends a get request containing the token and attestation document.
The provisioner uses the token and attestation document to identify the Cage, retrieve its secrets, and generates an intermediate CA for it to use to generate attestable certificates. The secrets and CA are only served to the Cage if the PCRs in the attestation document match the expected PCRs that were provided during the deployment.
Now that the Cage has been given its own CA, it can generate attestable certs to terminate TLS.
The Data Plane starts by generating a key pair to be used by the leaf cert. The public key of the leaf cert is then sent to the AWS Nitro Security Module in the challenge field. This creates a dependency between the attestation of the Cage and the TLS cert shared with the client.
The data plane then generates a Certificate Signing Request (CSR). The Subject Alt Names in the CSR include both the base Cage hostname (
<cage_name>.<app_uuid>.cages.evervault.com) and an attestable hostname (
<attestation_doc>.<cage_name>.<app_uuid>.cages.evervault.com). The CSR is then signed by the intermediate cert, to produce the Cage's leaf cert. The inclusion of the attestable hostname in the leaf cert ties the TLS cert back to the Cage.
Because there is a cyclic dependency between the cert used to terminate TLS and the attestation document within it, we can use it to prove that the TLS connection is only able to be terminated within the Enclave. To avoid replay attacks, this scheme also supports the inclusion of a nonce. Sending a request to
<nonce>.<attest>.<cage_name>.<app_uuid>.cages.evervault.com will result in a fresh cert generation. The process for generating the cert is the same, but the nonce is taken from the requested hostname and included in the attestation document.
Now that the Cage has access to an intermediate CA, and has generated an attestable leaf cert, we can walk through the process of how a client will attest the Cage.
The client begins by performing the steps of a typical TLS handshake:
- Validates the hostname corresponds with the requested domain
- Validates that there is a valid trust chain going back to the Cages Root CA.
The client then attests the connection:
- Extracts the attestation document from the Subject Alternative Names
- Validates the signature over the Attestation Document against the public AWS Nitro CA.
- Validates that the embedded PCRs match the PCRs returned on build — the remote Cage is running the expected service.
- Optionally, confirms that the attestation document returned includes the nonce from their initial request.
- 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 Cage. This guarantees that the data is sent over a TLS connection directly to the enclave which is running the expected code.
While it’s helpful to understand how we provision the certificates used by a Cage, it’s more illustrative to step through the ways the connection could be intercepted, and show how this protocol uses standard TLS plus Attestation to protect your data.
The following diagrams consider how a malicious actor within Evervault could attempt to perform a man-in-the-middle attack on your connection to the Cage, and how your client is protected in each case.
Assuming a rogue actor within Evervault could obtain a CA signed by the Cages root CA, and could intercept the initial handshake from the client to the Cage, the MITM could then perform its own handshake (including the nonce provided by the client).
The MITM could then use the response to its own handshake to extract an Attestation document from the Cage (Note: the attestation document contains the public key of the cert).
The MITM could then generate a trusted certificate which contains this attestation document, which it would then use to complete the handshake with the client. The client would trust this cert as it has installed the Evervault Cages Root CA.
However, as the client validates the attestation document, it would notice that the public key in the certificate doesn’t match the public key embedded within the attestation document.
To avoid the client detecting the public key mismatch, the MITM could alternatively generate a trusted cert which has the same public key as the cert held in the Cage. In this case, the client will be unable to detect that there is a MITM in place, but the MITM will be unable to decrypt any of the data over the connection.