1.0 Introduction
This article describes how to create and deploy an Enclave OS Nginx application that uses HTTPS for communication. The application uses a certificate issued by Fortanix Confidential Computing Manager (CCM) to establish HTTPS communication and is deployed on an Azure virtual machine.
2.0 Prerequisites
Ensure that the following prerequisites are met:
A Fortanix Armor account.
A Microsoft Azure account.
Fortanix Node Agent deployed from the Azure Marketplace as described in Enroll a Compute Node (Bare Metal or VM) - SGX.
Docker installed on the virtual machine.
Install Docker using the following command:
sudo apt install docker.io
3.0 Deploy an Nginx Enclave OS Application Using CLI
3.1 Authenticate to Fortanix Armor
Before you can issue any requests, you must authenticate to Fortanix Armor using the following commands:
cpath=$(mktemp -p "/tmp" -t "fortanix_ccm_cookie.XXXXX")NOTE
Session tokens are short-lived. If you receive the response
{"message":"Forbidden","code":"FORBIDDEN"}, refresh the session token using the following command:curl -b $cpath -c $cpath -H "X-CSRF-Header:true" -X POST https://ccm.fortanix.com/v1/sys/session/refresh
TIP
For security reasons, avoid entering credentials directly in the terminal. Instead, store the credentials in a file and provide the file to curl.
Create a file containing the credentials:
machine ccm.fortanix.com login <username> password <password>Replace <username> and <password> with the email address and password of your Fortanix Armor account.
Authenticate using the following command:
curl --netrc-file access-file -c $cpath -X POST https://ccm.fortanix.com/v1/sys/auth3.2 List Available Accounts
Run the following command to list all available accounts:
curl -b $cpath -c $cpath -H "X-CSRF-Header:true" -X GET https://ccm.fortanix.com/v1/accounts3.3 Select an Account
If multiple accounts are available, the response contains information for each account, including the account name and account ID (acct_id). For example,
{ "name":"fortanix-test", "acct_id":"e5fd5441-4ffc-4a4c-af63-bddb488524c2", "created_at":1609863607000, "roles":["MANAGER"], "status":"ACTIVE", "features":["workflows"], "approval_state":"APPROVED" }Select the account by specifying the appropriate acct_id :
curl -b $cpath -c $cpath -H "X-CSRF-Header:true" -X POST https://ccm.fortanix.com/v1/sys/session/select_account/<acct_id>Before creating the CCM application, create an SSL-enabled Nginx Docker image and push it to a registry.
3.4 Create an Nginx Docker Image
3.4.1 Create an Nginx Configuration File
Create a default.conf file with the following contents:
server {
listen 443;
ssl on;
ssl_certificate /etc/ssl/nginx.crt;
ssl_certificate_key /etc/ssl/nginx.key;
server_name localhost;
server_tokens off;
location / {
root /usr/share/nginx/html;
index index.html index.htm;
}
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root /usr/share/nginx/html;
}
}
#redirect server error pages to the static page /50x.html3.4.2 Create a Docker Container
Create a Dockerfile with the following contents:
FROM nginx:latest
COPY default.conf /etc/nginx/conf.d/The Dockerfile uses the latest Nginx image and replaces the default configuration with the SSL-enabled configuration.
Build the Docker image and push it to the registry:
docker build -t /nginx-ssl-nocert:latest .
docker push /nginx-ssl-nocertReplace <repository-prefix> with the public or private registry repository prefix.
3.4.3 Create an app.json File
Create an app.json file containing the application configuration:
{
"name":"nginx-ssl-fortanix-cert",
"description":"nginx web server app with SSL enabled.",
"input_image_name":"<registry>/nginx-ssl-nocert",
"output_image_name":"<registry>/nginx-ssl-fortanix-cert-eos",
"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":["fortanix-nginx.canadacentral.cloudapp.azure.com"],
"advanced_settings":
{
"entrypoint": [],
"manifestEnv": [],
"encryptedDirs": []
"rw_dirs": ["/var/cache/nginx", "/etc/ssl"],
"certificate":
{
"issuer":"MANAGER_CA",
"subject":"fortanix-nginx.canadacentral.cloudapp.azure.com",
"keyType":"RSA",
"keyParam":{"size":2048},
"keyPath":"/etc/ssl/nginx.key",
"certPath":"/etc/ssl/nginx.crt"
}
},
"custom_metadata": {
"app_type": "ENCLAVE_OS"
}
}NOTE
Replace
<registry>with the registry used to store the Nginx container image.During deployment, Fortanix CCM generates the certificate and private key. Enclave OS places the certificate and key in the configured Nginx paths.
Specify a domain name in
allowed_domains. The same domain is included in the certificate generated by Fortanix CCM.In this example, the domain is
fortanix-nginx.canadacentral.cloudapp.azure.com. You may use a different domain if required.Configure a DNS record that resolves the specified domain to the virtual machine.
3.4.5 Create an Application
Create the application using the following command:
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/appsNote the app_id returned in the response. This value is required when creating a build.
For example,
{ "app_id":"de40482c-2092-4a25-b9a2-635eb55c5d97" }3.5 Fetch Domain Approval Tasks
Run the following command to retrieve all domain approval tasks:
curl -b $cpath -c $cpath -H "X-CSRF-Header:true" -X GET https://ccm.fortanix.com/v1/tasks?task_type=DOMAIN_WHITELIST > all_domain_tasks.jsonThe tasks are stored in the all_domain_tasks.json file.
Identify the task_id associated with the application and use it to approve the task in the next step.
3.6 Approve a Domain Task
Approve the application-specific domain task using the corresponding task_id:
curl -b $cpath -c $cpath -H "X-CSRF-Header:true" -s -H "Content-Type: application/json" -d '{"status":"APPROVED"}' -X PATCH https://ccm.fortanix.com/v1/tasks/<task_id>3.7 Create a Build
Creating a build requires the following steps:
Create a
build.jsonfile.Convert the Nginx container image to an Enclave OS image.
3.7.1 Create a build.json File
Create a build.json file with the following contents:
{
"app_id": "${app_id}",
"inputAuthConfig":
{
"username": "<account-id>",
"password": "<password>"
},
"input_docker_version": "latest",
"outputAuthConfig":
{
"username": "<account-id>",
"password": "<password>"
}
"output_docker_version": "nitro"
}Replace:
<account-id>and<password>with the credentials for the input and output registries.${app_id}with the application ID created in the previous step.
If you did not record the application ID, retrieve it using the following command:
curl -b $cpath -c $cpath -H "X-CSRF-Header:true" -X GET https://ccm.fortanix.com/v1/apps3.7.2 Convert the Application Build
Convert the build using the following command:
curl -b $cpath -c $cpath -H "X-CSRF-Header:true" -s -H "Content-Type: application/json" -d @build.json -X POST https://ccm.fortanix.com/v1/builds/convert-appVerify that the converted image is available in the Docker registry.
Before the build can run in attested mode, it must be approved. This ensures that only approved builds can run on compute nodes enrolled with Fortanix CCM.
3.8 Fetch Build Approval Tasks
Retrieve all build approval tasks using the following command:
curl -b $cpath -c $cpath -H "X-CSRF-Header:true" -X GET https://ccm.fortanix.com/v1/tasks?task_type=BUILD_WHITELISTThe tasks are stored in the all_build_tasks.json file.
Identify the build-specific task_id and use it to approve the build.
3.9 Approve the Build
Approve the build using the following command:
curl -b $cpath -c $cpath -H "X-CSRF-Header:true" -s -H "Content-Type: application/json" -d '{"status":"APPROVED"}' -X PATCH https://ccm.fortanix.com/v1/tasks/<task_id>The build is now approved and ready to run.
3.10 Run the Application
Log in to the virtual machine where Node Agent is deployed and run the application using the following command:
docker run -it --privileged -v /run/nitro_enclaves:/run/nitro_enclaves -e NODE_AGENT=http://<node-agent-ip>:9092/v1/ -p <port-mapping> <converted-image-id>For example,
docker run -it --privileged -v /run/nitro_enclaves:/run/nitro_enclaves -e NODE_AGENT=http://<node-agent-ip>:9092/v1/ -p 8121:443 <registry-prefix>/nginx-ssl-fortanix-cert-eos:nitroWhere:
<node-agent-ip>is the IP address of the compute node enrolled with Fortanix CCM.9092is the port used by Node Agent and Enclave OS for communication.<converted-image-id>is the converted Enclave OS image.
4.0 Test the Nginx Enclave OS Application
Verify that the application is running and using the CCM-issued certificate.
Method 1: Verify Using curl
Log in to the compute node where Node Agent and the Nginx application are running and execute the following command:
curl --verbose -k https://fortanix-nginx.canadacentral.cloudapp.azure.com:8121You can also use localhost:
curl -verbose -k https://localhost:8121However, using localhost results in a certificate warning because the certificate was issued for a specific domain.
The response includes:
Certificate information issued by Fortanix CCM.
The Nginx HTML page.
An HTTP
200 OKresponse.
Method 2: Verify Using a Browser
Open the following URL in a browser: https://fortanix-nginx.canadacentral.cloudapp.azure.com:8121.

Figure 1: Test Nginx
NOTE
The browser may display a certificate warning because the root CA is not trusted by the browser. Proceed to the site to continue testing.
5.0 Deploy an Nginx Enclave OS Application Using the Fortanix CCM UI
5.1 Log in to Fortanix Armor
Sign up and Log in to Fortanix Armor. For detailed instructions, refer to Getting Started with Fortanix Armor.
5.2 Select an Account
Create or select a Fortanix Armor account. For detailed instructions, refer to Getting Started with Fortanix Armor.
5.3 Create a Group
Create a group in the Fortanix Armor Identity and Access Management solution. For detailed instructions, refer to Fortanix Armor Identity and Access Management.
5.4 Create an Application
Create an Nginx application using the configuration provided in the app.json file.
In the CCM left navigation panel, click Applications and then on the ACTIVE APPLICATIONS tab, click ADD APPLICATION.
In the Add Application dialog box, select Enclave OS and click NEXT.
In the Add Application form, enter the application details and click ADD APPLICATION.
For detailed instructions, refer to Add Application.
5.5 Create an Application Build
After creating the nginx-ssl-fortanix-cert-eos application, open the application details page.
In the application details page, go to BUILDS tab and click ADD BUILD.
In the Add Build form:
Enter the tag of the application input Docker image.
Enter the registry credentials for the output image. Registry credentials are used to access the private Docker registry where the image will be pushed. The input image does not require credentials because it is stored in a public registry.
Click ADD BUILD.
For detailed instructions, refer to Create Application Build.
5.6 View Approval Tasks
To view domain and build approval tasks, navigate to Tasks in the CCM UI.
5.7 Approve Tasks
Approve the domain and build approval tasks associated with the nginx-ssl-fortanix-cert-eos application.
Open the task.
Click APPROVE.
5.8 Run the Application
Run the application on the compute node using the following command:
docker run -it --privileged -v /run/nitro_enclaves:/run/nitro_enclaves -e NODE_AGENT=http://172.31.8.234:9092/v1/ -p <port-mapping> <registry-prefix>/<converted-image-id>For example,
docker run -it --privileged -v /run/nitro_enclaves:/run/nitro_enclaves -e NODE_AGENT=http://172.31.8.234:9092/v1/ -p 8121:443 <registry-prefix>/nginx-ssl-fortanix-cert-eos:nitroWhere:
<node-agent-ip>is the IP address of the compute node enrolled with Fortanix CCM.9092is the port on which Node Agent listens.<converted-image-id>is the converted application image available in the Images page.
NOTE
Replace the Node Agent IP address, port mapping, and converted image with values from your environment.
Add the following flags to the command for additional details:
-e ENCLAVEOS_LOG_LEVEL=debugto enable debug logging.
-p 7622:80 -p 8038:443to map the application custom ports to ports80and443.
5.9 Verify the Application
To verify and monitor the application:
Navigate to Applications.
Open the application details page.
Verify that a running application build is displayed for the application.