---
title: "Using Fortanix Confidential Computing Manager to Build an Enclave OS Application from Scratch"
slug: "using-fortanix-confidential-computing-manager-to-build-an-enclave-os"
updated: 2026-06-26T16:29:50Z
published: 2026-06-26T16:29:50Z
canonical: "support.fortanix.com/using-fortanix-confidential-computing-manager-to-build-an-enclave-os"
---

> ## Documentation Index
> Fetch the complete documentation index at: https://support.fortanix.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Using Fortanix Confidential Computing Manager to Build an Enclave OS Application from Scratch

## 1.0 Introduction

This guide will walk you through creating a simple Dockerized Python server and then deploying it within a Trusted Execution Environment using Fortanix Enclave OS. The guide offers the options to convert your Docker application to an Enclave OS application either using the Fortanix CCM UI or by issuing REST API calls.

## 2.0 Create a Docker Application

### 2.1 Creating a Python Application

Let us start by creating a simple Python server using Flask. Create a file named `server.py` with the following contents:

```python
from flask import Flask
app = Flask("Hello Flask Server")

@app.route("/")
def hello():
    return "Hello Flask"

if __name__ == '__main__':
    app.run(host='0.0.0.0', port='9000')
```

This application is a minimal Flask server that accepts requests on port 9000 and returns a greeting message.

### 2.2 Create a Docker Container

Next, let us create a Docker container containing this application and push it to a container registry.

#### Step 1: Create a Dockerfile

Create a file called **Dockerfile** with the following contents:

```dockerfile
FROM python:3.7

EXPOSE 9000
RUN pip3 install flask

RUN mkdir /app
COPY server.py /app/
WORKDIR /app

ENTRYPOINT ["python3", "server.py"]
```

#### Step 2: Build a Docker image

You can now create a Docker image by running the following command:

```bash
docker build -t fortanix/python-flask:latest .
```

> [!NOTE]
> NOTE
> 
> If you want to use your own container registry, replace "`fortanix`" with the name of your registry.

You can now run the Docker container using the following command:

```bash
docker run -p 9000:9000 fortanix/python-flask:latest
```

From another terminal, you can use the following command to send an HTTP request to your newly deployed server:

```bash
curl localhost:9000
```

#### Step 3: Push the image to a registry

To make this image publicly accessible, you can push it to a public registry as follows:

```bash
docker push fortanix/python-flask:latest
```

> [!NOTE]
> NOTE
> 
> The above command will fail if you have not used your own registry, but you can skip this step since the image is already pushed and available in the Fortanix public registry. [https://hub.docker.com/r/fortanix/python-flask](https://hub.docker.com/r/fortanix/python-flask).

## 3.0 Option 1: Build an Enclave OS Application Using the Fortanix CCM UI

In this section of the guide, we will walk through the steps of converting your Docker application into an Enclave OS application that can run securely inside a Trusted Execution Environment, using the [Fortanix CCM UI](https://ccm.fortanix.com).

### 3.1 Signing in to the Fortanix CCM UI

Go to [https://ccm.fortanix.com](https://ccm.fortanix.com) and use your email address and password to log in.

![CCM_5.png](https://cdn.us.document360.io/c3bd85d2-4ad8-4d85-9f60-f1c168a3aad9/Images/Documentation/360092844791.png)

**Figure 2: Log In Page**

### 3.2 Select an Account

To select an account, click **SELECT ACCOUNT**.

![Quickstart17.png](https://cdn.us.document360.io/c3bd85d2-4ad8-4d85-9f60-f1c168a3aad9/Images/Documentation/360092848031.png)

**Figure 2: Select an Account**

### 3.3 Create a Group

1. Navigate to the **Groups** menu item from the CCM UI left navigation panel and click **+ ADD GROUP** to add a group.

![group-landing-screen.png](https://cdn.us.document360.io/c3bd85d2-4ad8-4d85-9f60-f1c168a3aad9/Images/Documentation/21580083917460.png)

**Figure 3: Add group**
2. Click **ADD GROUP** to create a new group.
3. Enter the required **Name** for the group and add **Labels** with **Key:Value** pairs.
4. Click **CREATE GROUP**.

The group is successfully created.

### 3.4 Create an Application

To create an application using Fortanix CCM UI, navigate to the **Applications** menu item in the CCM UI left navigation panel and click **+ APPLICATION** to create a new application.

![Fig-5-application-landing-screen.png](https://cdn.us.document360.io/c3bd85d2-4ad8-4d85-9f60-f1c168a3aad9/Images/Documentation/23041035514772.png)

**Figure 4: Create an Application**

Now, in the **Add application** form, add the details of the application.

![](https://cdn.us.document360.io/c3bd85d2-4ad8-4d85-9f60-f1c168a3aad9/Images/Documentation/1(4).png)

**Figure 5: Configure an application**

### 3.5 Create an Image

In the detailed view of the application, click **+IMAGES** to create an image.

![image-1.png](https://cdn.us.document360.io/c3bd85d2-4ad8-4d85-9f60-f1c168a3aad9/Images/Documentation/21580083927572.png)

**Figure 6: Create an Image**

Enter the **REGISTRY CREDENTIALS** for the **Output image** name. Registry Credentials are the credentials to access the private Docker registry where the image will be pushed. The **Input image** does not require credentials since it is a public registry. Also, provide the image tag. Click **CREATE** to proceed.

![](https://cdn.us.document360.io/c3bd85d2-4ad8-4d85-9f60-f1c168a3aad9/Images/Documentation/2(3).png)

**Figure 7: Create an image**

### 3.6 Approve Application Build

From the CCM UI left navigation panel, select the **Tasks** menu item. On the Tasks page, to approve the application build, click on the task and then click **APPROVE**.

![image-approved-tab.png](https://cdn.us.document360.io/c3bd85d2-4ad8-4d85-9f60-f1c168a3aad9/Images/Documentation/21580083938964.png)

**Figure 8: View and Approve the Application Build**

## 4.0 Option 2: Build an Enclave OS Application Using REST API Calls

In this section of the guide, we will walk through the steps of converting your Docker application into an Enclave OS application that can run securely inside a Trusted Execution Environment, using the [Fortanix CCM REST API](https://fortanix.com/api/ccm/).

### 4.1 Authenticate to Fortanix CCM

Before you can issue any requests, you first need to authenticate to Fortanix CCM using the following commands:

```bash
cpath=$(mktemp -p "/tmp" -t "fortanix_ccm_cookie.XXXXX")
curl -u <username>:<password> -c $cpath -X POST https://ccm.fortanix.com/v1/sys/auth
```

Where `&lt;username&gt; `and `&lt;password&gt;` are to be replaced with the email address and password of your Fortanix CCM account.

> [!NOTE]
> NOTE
> 
> Authentication session tokens are short-lived. If you ever get the response **{"message":"Forbidden","code":"FORBIDDEN"}** you can run the following command to refresh the session token.
> 
> ```bash
> curl -b $cpath -c $cpath -H "X-CSRF-Header:true" -X POST https://ccm.fortanix.com/v1/sys/session/refresh
> ```

### 4.2 Select an Account Using an API Call

Once you have successfully authenticated to Fortanix CCM, you need to select an account. First, you can list all accounts available using the following command:

```bash
curl -b $cpath -c $cpath -H "X-CSRF-Header:true" https://ccm.fortanix.com/v1/accounts
```

This command will return a JSON string of the following form:

```bash
{"name":"My account","acct_id":"26eaa328-5eb4-41c7-b09b-8a3e0a0f65c7", ...}, ...
```

To select an account, you need to copy the account ID of the account you are interested in (the string `26eaa328-5eb4-41c7-b09b-8a3e0a0f65c7` in the example above), let us call it, and run:

```bash
curl -b $cpath -c $cpath -H "X-CSRF-Header:true" -X POST https://ccm.fortanix.com/v1/sys/session/select_account/<account_id>
```

### 4.3 Create an Application Using an API Call

Next, to create a new application, create a file called `app.json` whose contents are shown below. Make sure to replace the `output_image_name` with your private registry.

```json
{
    "name":"Python Flask Server",
    "description":"",
    "input_image_name":"fortanix/python-flask",
    "output_image_name":"fortanix-private/python-flask-nitro",
    "default_build_settings": {
        "sgx": {},
        "nitro_enclaves": {
            "cpu_count": 2,
            "mem_size": 1024,
            "enable_overlay_filesystem_persistence": true
        }
    },
    "group_id": "a8e8395e-096d-4eb8-9017-2098f2ab8327",
    "allowed_domains": [],
    "advanced_settings": {
        "entrypoint": [],
        "manifestEnv": [],
        "encryptedDirs": [],
        "rw_dirs": [],
        "certificate": {}
    },
    "custom_metadata": {
        "app_type": "ENCLAVE_OS"
    }
}
```

Then, create an application using the following API call:

```bash
curl -b $cpath -c $cpath -H "X-CSRF-Header:true" -H "Content-Type: application/json" -d @app.json -X POST https://ccm.fortanix.com/v1/apps
```

This will print information about the newly created application, including its :

```bash
{"name":"Python Flask Server","app_id":"cc386097-dcf7-4813-880a-ddacdafb48a2",...}
```

### 4.4 Create an Image Using an API Call

Once the application has been created, you can similarly create an image by following these steps. First, create a file called `build.json` as shown below. Replace `&lt;app_id&gt;` with the ID of your newly created application. The `&lt;username&gt;` and `&lt;password&gt;` are the credentials of the registry where you want the converted image to be stored at. This was specified above as `output_image_name`.

```json
{
  "app_id":"<app_id>",
  "input_docker_version":"latest",
  "output_docker_version":"latest",
  "outputAuthConfig":{
    "username":"<username>",
    "password":"<password>"
  }
}
```

> [!NOTE]
> NOTE
> 
> *For more information on how to set up registry credentials to avoid including credentials in this file, refer to the* [*Quickstart Guide*](/v1/docs/quickstart-guide-1) *.*

Now you can create the image using the following command:

```bash
curl -b $cpath -c $cpath -H "X-CSRF-Header:true" -H "Content-Type: application/json" -d @build.json -X POST https://ccm.fortanix.com/v1/builds/convert-app
```

This returns the output that shows the `&lt;task_id&gt;` (`f0d815b6-9520-4ce4-b4f4-6a82a718bb7e` in this example), among other information:

```bash
{"build_name":"fortanix-private/python-flask-nitro:latest","pending_task_id":"f0d815b6-9520-4ce4-b4f4-6a82a718bb7e",...}
```

Finally, you can approve the image using its `&lt;task_id&gt;` and the following command:

```bash
curl -b $cpath -c $cpath -H "X-CSRF-Header:true" -H "Content-Type: application/json" -d '{"status":"APPROVED"}' -X PATCH https://ccm.fortanix.com/v1/tasks/<task_id>
```

## 5.0 Run the Application

Whether you chose to create your application using the UI or the API option, you should now have converted and whitelisted an application image and can run the application on a Nitro compute node.

Run the application using the following commands:

```bash
docker run --privileged --volume /dev:/dev -v /var/run/aesmd/aesm.socket:/var/run/aesmd/aesm.socket -e NODE_AGENT=http://52.152.206.164:9092/v1/ fortanix-private/python-flask-nitro:latest
```

Where,

- `9092` is the default port on which Node Agent listens to.
- `52.152.206.164` is the IP address of your compute node.
- `fortanix-private/python-flask-nitro:latest` is the converted app.

> [!NOTE]
> NOTE
> 
> - Use your own inputs for Node IP, Port, and Converted Image in the above format. The information in the example above is just a sample.
> - Add the following flag along with the command to get more details:
>   - `-e ENCLAVEOS_LOG_LEVEL=debug` - to get debug log
>   - `-p 7622:80 -p 8038:443` - to map the application custom port to `80` or `443`

## Related

- [Fortanix CCM - Quickstart](/fortanix-ccm-quickstart-guide.md)
- [How does the attestation process guarantee code integrity?](/how-does-the-attestation-process-guarantee-code-integrity.md)
- [Bringing EDP Rust Apps to Confidential Computing Manager](/bringing-edp-rust-apps-to-fortanix-ccm.md)
