Using Fortanix Confidential Computing Manager to Build an Enclave OS Spring Application

Introduction

In this example, we will create a simple Spring Server application that stores information in a Mysql DB using Tomcat. The MySQL DB and the Spring Server Application will be run in Nitro environments using Fortanix Confidential Computing Manager (CCM) and the Compute Node.

Spring Server Application

Authenticate to Fortanix CCM

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

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

Get all Accounts

After authenticating, get all the accounts present using the following command:

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

Select the Account

Note the account_id of the account you want to select.

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

Create an Application

Create a Spring Server application using the configuration provided in the app.json file below.

Create Application

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

Create App.json Config File that Contains the Application Details

{
    "name":"spring-mysql-db",
    "description":"",
    "input_image_name":"fortanix/spring-mysql-db",
    "output_image_name":"/spring-mysql-db-converted",
    "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": ["MALLOC_ARENA_MAX=1"],
        "encryptedDirs": [],
        "rw_dirs": ["/etc","/var/lib/_mysql","/var/lib/mysql","/tmp","/run/mysqld"],
        "certificate": {}
    },
    "custom_metadata": {
        "app_type": "ENCLAVE_OS"
    }
}

Create an Image

Create an image of the application.

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

The build.json is as below.

{
        "app_id": <app_id>,
        "docker_version": <tag>,
        "inputAuthConfig":
            {"username": <username>,
             "password": <password>
            },
        "outputAuthConfig":
           {"username": <username>,
            "password": <password>
           }
}

NOTE

See the Fortanix CCM Quickstart guide on how to set up registry credentials to avoid including credentials in this file.

This returns the output that shows the <task_id> (f0d815b6-9520-4ce4-b4f4-6a82a718bb7e in this example), among other information:

Finally, you can approve the image using it's <task_id> and the following command:

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>

The image is created and whitelisted.
Next, run the following command on a machine running the compute node to run the application.

Run the Application

Run the application image using the following command:

docker run --privileged --volume /dev:/dev -v /var/run/aesmd/aesm.socket:/var/run/aesmd/aesm.socket -e NODE_AGENT_BASE_URL=http://<node agent ip>:9092/v1/ --network=host <spring mysql converted image>
  • <node-agent-ip> is the IP address of the compute node registered on Fortanix Confidential Computing Manager (CCM).

  • 9092 is the port on which Compute Node listens on.

  • converted-image-id is the converted app that can be found in the Images tab under Image Name column in the Images table.

NOTE

  • Please 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

Spring MySQL Application

Authenticate to Fortanix CCM

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

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

Get all Accounts

After authenticating, get all the accounts present using the following command

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

Select the Account

Note the account_id of the account you want to select.

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

Create an Application

Create a Spring MySQL application using the configuration provided in the app.json file below.

Create Application

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

Create App.json Config File that Contains the Application Details

{
     "name": "spring-mysql-app",
     "description": "",
     "input_image_name": "fortanix/spring-mysql-app",
     "output_image_name": "/spring-mysql-app-converted",
     "isvprodid": 1,
     "isvsvn": 1,
     "mem_size": 2048,
     "threads": 80,
     "advanced_settings": {
         "java_runtime":"OPENJDK",
         "rw_dirs":["/tmp","/etc","/usr/lib","/root/gs-accessing-data-mysql"],
     }
}

Create an Image

Create an image of the application.

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

The build.json is as below.

{
        "app_id": <app_id>,
        "docker_version": <tag>,
        "inputAuthConfig":
            {"username": <username>,
             "password": <password>
            },
        "outputAuthConfig":
           {"username": <username>,
            "password": <password>
           }
}

NOTE

See the Fortanix CCM Quickstart guide on how to set up registry credentials to avoid including credentials in this file.

This returns the output that shows the <task_id> (f0d815b6-9520-4ce4-b4f4-6a82a718bb7e in this example), among other information:

Finally, you can approve the image using it's <task_id> and the following command:

Approve the Image Whitelist Task

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>

The image is created and whitelisted.

Next, run the following command on a machine running the compute node to run the application.

Run the Application

For the node agent attestation type DCAP/EPID, run the application image using the following command:

docker run --privileged --volume /dev:/dev -v /var/run/aesmd/aesm.socket:/var/run/aesmd/aesm.socket -e DB_URL=<URL-Of-MySQL-DB> -e NODE_AGENT_BASE_URL=http://<node agent ip>:9092/v1/ --network=host <converted spring app image>

 Where, 

  • <URL-Of-MySQL-DB> is the URL of the server on which the Spring MySQL converted application is running.

  • <node-agent-ip> is the IP address of the compute node registered on Fortanix CCM.

  • 9092 is the port on which Compute Node listens on.

  • converted-image-id is the converted app that can be found in the Images tab under Image Name column in the Images table.

NOTE

  • Please 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

Once both the Spring Server application and Spring MySQL application are running, run the following commands to verify the functionality of TomCat.

  1. Enter some data in DB using TomCat:

    curl 'http://<node agent IP>:8080/demo/add?name=test&[email protected]'
  2. Fetch all the data entered:

    curl http://<node agent IP>:8080/demo/all