Security
Headlines
HeadlinesLatestCVEs

Headline

Confidential computing on AWS Nitro Enclave with Red Hat Enterprise Linux

Confidential computing is needed to protect sensitive data not only when it is stored or transmitted, but also while it is actively being processed in memory - traditionally the most vulnerable phase. In this article, I demonstrate how to implement a secure runtime environment using AWS Nitro Enclaves for applications on EC2 instances running Red Hat Enterprise Linux 9.6+ (RHEL).To fully understand the concepts, use cases, and justifications for confidential computing, read our previous articles. The hardware used to provide secure communication and certification is based on AWS Nitro architec

Red Hat Blog
#mac#amazon#linux#red_hat#js#git#intel#aws#amd#ibm#docker#ssl

Confidential computing is needed to protect sensitive data not only when it is stored or transmitted, but also while it is actively being processed in memory - traditionally the most vulnerable phase. In this article, I demonstrate how to implement a secure runtime environment using AWS Nitro Enclaves for applications on EC2 instances running Red Hat Enterprise Linux 9.6+ (RHEL).

To fully understand the concepts, use cases, and justifications for confidential computing, read our previous articles. The hardware used to provide secure communication and certification is based on AWS Nitro architecture.

To follow along with this guide, you must have access to the AWS Console, a RHEL 9.6+ deployment, or a ROSA deployment.

Why run workloads in a confidential computing environment

In conventional environments, data in use can be exposed to threats such as privileged insiders, compromised hypervisors, or advanced malware capable of reading servers’ memory. Confidential computing solves this by placing workloads inside a hardware-protected Trusted Execution Environment (TEE) that encrypts memory and strictly controls access, helping ensure that even cloud providers, system administrators, and system-level software cannot view or modify data in use.

RHEL plays a key role by providing a hardened, enterprise-grade operating system that’s fully compatible with modern confidential computing technologies. RHEL integrates with CPU-level features such as AMD SEV-SNP, Intel TDX, and IBM Secure Execution, to enable encrypted virtual machines and secure enclaves. RHEL abstracts much of the complexity involved in configuring these hardware protections, offering security profiles, attestation tooling, and lifecycle management that make confidential computing easier to deploy and operate in production.

By running workloads on RHEL within a confidential computing environment, organizations can maintain compliance with increasingly stricter regulatory requirements and achieve a high level of data assurance in hybrid or cloud-hosted architecture. RHEL’s long support lifecycle, predictable updates, and security certifications help ensure that confidential computing deployments remain stable and secure over time. This combination of hardware-level isolation with RHEL’s enterprise security capabilities provides a trusted foundation for processing the most sensitive workloads, from financial data to healthcare records to AI models.

Deploy workloads in an environment you trust

The purpose of this blog is to show how you can use confidential computing technology in order to deploy workloads in a TEE. The fundamental feature of confidential computing is the ability to prove that you are running in a secure environment. In order to achieve this objective, you must:

  1. Build a workload in such a way that you can prove its identity using cryptographic measurements.
  2. Deploy services that will verify the identity of the workload and the validity of the TEE it is running on.
  3. Deploy the workload itself in such a way that you know it will be unable to run if not running in a suitably protected TEE.

Resources available to enclaved workloads on AWS EC2 supported instances

The operating system and container orchestration system don’t impose limits on the number of application enclaves you can run, but system resource constraints must be considered. Specifically, the vCPU and memory allocated to each enclave impacts the total number of enclaves you can deploy on a single host. For example, on an instance with 8 vCPUs and 32 GB of memory, the vCPU allocation is the limiting factor if multi-threading is a requirement. With 2 vCPUs reserved for the parent host, the remaining 6 vCPUs can support no more than 3 enclaves of 2 vCPUs and 8 GB of memory each. Additionally, on AWS Nitro Enclave, the absolute maximum number of enclaves per parent instance is four. For further details on system considerations for multi-enclave deployment, refer to official AWS documentation.

Implementing confidential computing on AWS Nitro Enclaves

In the following example, I run application code in a Podman container on AWS’s Nitro Enclave, which uses RHEL as its parent host. I’ll show the application build and packing into the enclave, communicating over Linux Virtual Socket (Vsock), a communication mechanism designed to facilitate efficient and isolated communication between a hypervisor and its guest VM. I’ll demonstrate how to verify the attestation certificate chain with OpenSSL, and verify the built enclave measurements known as the platform configuration register (PCR) with the measurement reported in the attestation document.

Start with an EC2 instance supporting AWS Nitro Enclaves (you can find the latest enabled parent instances in AWS documentation). From the EC2 console:

  1. Navigate to the instance’s Advanced Details
  2. Enable the Nitro Enclave option
  3. Select RHEL 9 from the console for your instance operating system.

In the implementation of this sample system, I used a M5.2xlarge instance, which has 8 vCPUs and 32 GB of RAM. I initiated the instance with a 30 GB boot volume using RHEL 9.7 sourced from the AWS console.

Once the instance is provisioned, initiate Nitro Enclave support by changing the instance metadata settings and the enclave environment settings for memory and CPU allocation policies. Refer to AWS documentation for instructions.

Install the Nitro Enclave CLI and SDK

Next, you must install the Nitro Enclave CLI and SDK. For RHEL, you must build the CLI and SDK tools from the AWS Git repository. Pull the source code and build the tools according to the documentation available in the Git repository. Make sure your instance has enough storage space to build the tools (it’s recommended that you have at least 20 GB of instance storage for the build process).

Once you’ve compiled the code, initiate the Nitro Enclave service:

$ sudo systemctl start nitro-enclaves-allocator.service

Create an example server and client

For this article, I used a simple Python application as the enclave server, and communicated from the parent host to the enclave server with a Python client. The communication between the application enclave server and the client is conducted over VSOK, the application enclave does not communicate over any other communication protocol.

I built this server code into a Podman image, and deployed it into the Nitro Enclave:

import socket
VSOCK_PORT = 5000
ANY_CID = socket.VMADDR_CID_ANY
def main():
    server = socket.socket(socket.AF_VSOCK, socket.SOCK_STREAM)
    server.bind((ANY_CID, VSOCK_PORT))
    server.listen(5)
    print(f"[Enclave] vsock server listening on port {VSOCK_PORT}...")
    while True:
        conn, client_addr = server.accept()
        print(f"[Enclave] Connection from CID {client_addr[0]}")
        data = conn.recv(4096)
        if not data:
            conn.close()
            continue
        print(f"[Enclave] Received: {data.decode()}")
        response = f"Enclave received: {data.decode()}"
        conn.sendall(response.encode())
        conn.close()
if __name__ == "__main__":
    main()

This client code is used in the parent host to communicate with the enclave, and to send and receive data from the confidential application:

import socket
import sys
VSOCK_PORT = 5000
def main():
    if len(sys.argv) != 2:
        print("Usage: python3 client.py <enclave_cid>")
        sys.exit(1)
    enclave_cid = int(sys.argv[1])
    client = socket.socket(socket.AF_VSOCK, socket.SOCK_STREAM)
    client.connect((enclave_cid, VSOCK_PORT))
    message = "Hello from parent instance!"
    print(f"[Parent] Sending: {message}")
    client.sendall(message.encode())
    data = client.recv(4096)
    print(f"[Parent] Received: {data.decode()}")
    client.close()
if __name__ == "__main__":
    main()

Build an enclave image

Next, build an enclave image (an .eif file). The build process provides you with the following artifacts:

  • The application enclave package

  • The measurements (PCR values) used by the application and client for attestation

    $ sudo podman build -t my-enclave

Once the application package is built, launch the application from your parent instance:

$ sudo nitro-cli build-enclave \
        --docker-uri my-enclave:latest
        --output-file my-enclave.eif

The enclave image is created along with the PCR information:

Start building the Enclave Image...
Using the locally available Docker image...
Enclave Image successfully created.
{
  "Measurements": {
    "HashAlgorithm": "Sha384 { ... }",
    "PCR0": "9b96d2ada83ed3d4012bc76f51d3eef5469a8c810ed1b4766521457a8ac5fc1e642e1482bea3a983d4500096248cf0e5",
    "PCR1": "0343b056cd8485ca7890ddd833476d78460aed2aa161548e4e26bedf321726696257d623e8805f3f605946b3d8b0c6aa",
    "PCR2": "76d89864f99fd0fd2c2211ca253102c30701c483073ec523d55dae720b5185db7b95657373d4316b4dbc61baf0f77347"
  }
}

Start the enclave:

$ sudo nitro-cli run-enclave \
        --eif-path my-enclave.eif \
        --cpu-count 2 \
        --memory 2048

When the enclave is initiated, you see output containing the enclave IDs, confirming that the application enclave is operational:

Start allocating memory...
Started enclave with enclave-cid: 19, memory: 2048 MiB, cpu-ids: [1, 5]
{
  "EnclaveName": "my-enclave",
  "EnclaveID": "i-04f6e376436007ea0-enc19aa04d68d968dc",
  "ProcessID": 37434,
  "EnclaveCID": 19,
  "NumberOfCPUs": 2,
  "CPUIDs": [
    1,
    5
  ],
  "MemoryMiB": 2048
}

Ensure that your application is communicating from the parent instance to the enclave. The sample Python application in the enclave receives a call from the parent instance over VSOCK on port 5000. The enclave application doesn’t accept external calls, and encrypts the memory it uses in the enclave.

$ python3 client.py 19
[Parent] Sending: Hello from parent instance!
[Parent] Received: Enclave received: Hello from parent instance!

Next, verify the enclave integrity by using the attestation documents. Using AWS Nitro hardware signature, provided by the Nitro Security Module (NSM) communicating over the /dev/nsm device, you can verify that the application you’re running is using the designated enclave and the context identifier (CID). The enclave application communicates with the Nitro hardware through CID 3 and port 9000 (CID 3 is dedicated to the Nitro hardware, and I selected port 9000 arbitrarily).

Here’s the Python code for the parent client to request attestation:

import socket,json,sys,base64
from cryptography import x509
from cryptography.hazmat.primitives import serialization,hashes
from cryptography.hazmat.primitives.asymmetric import padding
VSOCK_PORT_APP = 5000
if len(sys.argv) < 3:
    print('Usage: python3 client.py <enclave_cid> <command>')
    print('Commands: attest)
    sys.exit(1)
cid = int(sys.argv[1])
cmd = sys.argv[2]
s = socket.socket(socket.AF_VSOCK, socket.SOCK_STREAM)
s.connect((cid, VSOCK_PORT_APP))
if cmd == 'attest':
    nonce = base64.b64encode(b'parent-nonce-1234').decode()
    s.sendall(json.dumps({'action':'attest','nonce':nonce}).encode())
    resp = s.recv(65536)
    print('Attestation response:', resp.decode())
else:
    print('unknown command')
s.close()

In the enclave, the application uses the provided nonce to verify the validity of the host sending the request. An example response from the enclave:

$ python3 client.py 19 attest
Attestation response: 
{
  "document": {
    "module_id": "AWS-NitroEnclaves-04f6e376436007ea0-enc19aa04d68d968dc",
    "module_version": 1,
    "timestamp": "2025-11-23T07:14:29Z",
    "digest": {
      "pcrs": {
        "0": "324cead9b93a8ef58523b1758a97ed779f02d783ce90abcc99c29f1afa6883fe",
        "1": "c1196cfbcda499b3d968ab36a7dc45fd765b7b6c8ccd94ae61ad0c1c8bbb642d",
        "2": "7dfa884e0e528cde6f5c0f1a7c94c07b474197e931ff61cbbe2eb6171ac98ab4"
      },
      "nonce": "abcd1234",
      "user_data": "68656c6c6f"
    },
    "certificate_chain": [
      "-----BEGIN CERTIFICATE-----\nMIID...AWS NITRO ROOT...\n-----END CERTIFICATE-----",
      "-----BEGIN CERTIFICATE-----\nMIIE...AWS NITRO INTERMEDIATE...\n-----END CERTIFICATE-----"
    ]
  },
  "signature": "MEUCIQCJX1W9Jqk8TKLI+o0lK3c1o7i2Y5dfjGkzJNm3M5YSUgIgCuc/6pKX4+fx7ZlTGgXWfWxbtDD0eWsLy0oS7b8yovU=",
  "public_key": "MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEB70akL3zZlN8R2UoSd1C8Fp1z37ZrwVYQMw..."
}

Success!

Conclusion

In this article, you’ve seen how workloads that require an increased level of isolation and security are deployed on AWS Nitro Enclave using RHEL 9+ as the parent host instance.

Red Hat Enterprise Linux plays a vital role by integrating the necessary kernel-level and virtualization support to both host and confidential computing workloads. For cloud deployments (such as AWS Nitro Enclave), Red Hat offers purpose-built images so you can easily deploy your confidential computing applications. These images are optimized to leverage the underlying hardware’s memory encryption features, providing strong confidentiality guarantees for data processed within the enclave. The images are available as Amazon Machine Images (AMI) from AWS Console or AWS Marketplace.

Furthermore, Red Hat’s cloud-native platform, Red Hat OpenShift, supports confidential containers to allow developers to deploy sensitive, containerized applications into a TEE. Enterprises can now achieve a zero trust security posture and run regulated workloads on AWS Cloud. This solution enables the protection of valuable intellectual property, such as AI/ML models, without compromising the consistency, compliance, and agility provided by the RHEL and OpenShift ecosystem.

To begin your confidential computing deployment, access the RHEL images on the AWS Console or Marketplace and leverage the combined power of Nitro Enclaves and RHEL to secure your data-in-use.

Red Hat Blog: Latest News

Confidential computing on AWS Nitro Enclave with Red Hat Enterprise Linux