Skip to content

Getting Started

Welcome to Cosmian Enclave deployment tutorial

To launch your first Cosmian Enclave, follow this tutorial in your favorite terminal. Note that you first need to setup your Intel SGX machine based on the Server Installation section.

Cosmian Enclave was formerly called MSE Home

There are quite a few locations where the old MSE name is still in use.

Install the Cosmian Enclave CLI

The Cosmian Enclave CLI requires at least Python 3.8 and OpenSSL 1.1.1 series. It is recommended to use pyenv to manage different Python interpreters if needed.

$ pip3 install mse-cli
usage: mse home [-h]
                {encrypt,decrypt,evidence,scaffold,list,logs,package,restart,run,status,seal,unseal,spawn,stop,test,localtest,verify}
                ...

options:
  -h, --help            show this help message and exit

operations:
  {encrypt,decrypt,evidence,scaffold,list,logs,package,restart,run,status,seal,unseal,spawn,stop,test,localtest,verify}
    encrypt             encrypt a file using Fernet symmetric encryption
    decrypt             decrypt a file using Fernet symmetric encryption
    evidence            collect the evidences to verify on offline mode the application and the enclave
    scaffold            create a new boilerplate MSE application
    list                list the running MSE applications
    logs                print the MSE docker logs
    package             generate a package containing the Docker image and the code to run on MSE
    restart             restart an stopped MSE docker
    run                 finalise the configuration of the application docker and run the application
                        code
    status              print the MSE docker status
    seal                seal file using NaCl's Seal Box.Recipient is either raw X25519 public key or
                        extracted from RA-TLS certificate with enclave's public key in REPORT_DATA field
                        of SGX quote
    unseal              unseal file using NaCl's Seal Box
    spawn               spawn a MSE docker
    stop                stop and optionally remove a running MSE docker
    test                Test a deployed MSE app
    localtest           test locally a MSE app in a development context
    verify              verify the trustworthiness of a running MSE web application and get the RA-TLS
                        certificate

Docker configuration

Before deploying the app, verify that Docker service is up and your current user is part of docker group. See Manage Docker as a non-root user.

Scaffold your app

User

This command is for the Code Provider role

$ mse home scaffold example
$ tree -a example
example/
├── mse.toml
├── Dockerfile
├── mse_src
    ├── app.py
│   └── .mseignore
├── README.md
├── secrets.json
├── secrets_to_seal.json
└── tests
    ├── conftest.py
    └── test_app.py

2 directories, 9 files

The mse_src is your application directory designed to be started by mse home cli.

The Dockerfile should be based on mse-docker-base image and include all dependencies required to run your app. The build docker image will be used by the SGX operator.

The file app.py is a basic HelloWorld Flask application. Adapt by addind your own Python code in this boilerplate.

from http import HTTPStatus
from flask import Flask, Response

app = Flask(__name__)


@app.get("/health")
def health_check():
    """Health check of the application."""
    return Response(response="OK", status=HTTPStatus.OK)


@app.route('/')
def hello():
    """Get a simple example."""
    return "Hello world"

# other endpoints
# ...

The configuration to run your application is done in a TOML file mse.toml which will be used by the CLI:

name = "example"
python_application = "app:app"
healthcheck_endpoint = "/health"
tests_cmd = "pytest"
tests_requirements = [
    "cryptography",
    "intel-sgx-ra",
    "pytest==7.2.0",
]

This project also contains a test directory enabling you to test your project locally but also enabling the SGX operator to test on the host if code is unencrypted. It might help to debug and detect runtime errors before running your code in a Cosmian Enclave.

Compatibility with WSGI/ASGI

To be compliant with Cosmian Enclave your Python application must use a compatible web framework based on ASGI or WSGI. Flask and FastAPI are the most popular Python web frameworks. It’s not possible to deploy a standalone Python program.

Examples

See Cosmian Enclave App Examples to find sample applications.

Test your app, your docker and your configuration

User

This command is for the code provider role

$ mse home localtest --code example/mse_src/ \
                     --dockerfile example/Dockerfile \
                     --config example/mse.toml \
                     --test example/tests/

or more concisely with default arguments:

mse home localtest --project example

Testing your code before sending it to the SGX operator is recommended. Note that any error will require to restart the deployment flow from scratch.

Create the application package with the code and the docker image

User

This command is for the code provider role

This command generates a tarball named package_<app_name>_<timestamp>.tar which can be send to to the SGX operator:

$ mse home package --code example/mse_src/ \
                   --dockerfile example/Dockerfile \
                   --config example/mse.toml \
                   --test example/tests/ \
                   --output code_provider/

or more concisely with default arguments:

$ mse home package --project example \
                   --output code_provider/

Add --encrypt argument if you want to encrypt your code.

Spawn the application docker image

User

This command is for the SGX operator role

The spawn command will run a new Cosmian enclave with your code loaded but it will stay in an intermediate state called the configuration server. Configuration server is waiting additional information such as the decryption key of the code or any other secrets needed by your application.

$ mse home spawn --host 0.0.0.0 \
                 --port 9999 \
                 --size 4096 \
                 --package code_provider/package_<app_name>_<timestamp>.tar \
                 --output sgx_operator/ \
                 --san <EXTERNAL_IP_ADDR | DOMAIN_NAME | localhost>
                 app_name
  • host: usually 127.0.0.1 or 0.0.0.0
  • port: port used by your application
  • size: memory size (in MB) of the enclave to spawn (must be a power of 2 greater than 1024)
  • package: the application package containing the Docker images and the code
  • output: directory to write the evidence JSON file
  • san: Subject Alternative Name to use for routing with SSL pass-through (either domain name, external IP address or localhost)

The output file sgx_operator/evidence.json contains cryptographic proofs related to the enclave and be shared with anyone to interact with your enclave. It will be used by the code provider to verify the running app.

Collect the evidences to verify the application

User

This command is for the SGX operator role

$ mse home evidence --output sgx_operator/ app_name

This command collects cryptographic proofs related to the enclave and serialize them in a JSON file evidence.json.

You can choose another PCCS by specifying the --pccs parameter, by default it will determine the PCCS URL by parsing the aesmd service configuration file: /etc/sgx_default_qcnl.conf.

The file sgx_operator/evidence.json can be shared to any user of your application to allow them to do the remote attestation of your service.

Check the trustworthiness of the application

User

This command is for the SGX operator role

The trustworthiness is established by using 2 inputs:

  • the full code package (tarball file)
  • evidences captured from the running enclave (JSON file)
$ mse home verify --package code_provider/package_<app_name>_<timestamp>.tar \
                  --evidence sgx_operator/evidence.json \
                  --output /tmp

If the verification succeeds, the RA-TLS certificate is written as a file named ratls.pem, and you can now seal the code’s secret key to share it with the SGX operator.

Seal your secrets for your Cosmian Enclave

User

This command is for the code provider role

Using the unique enclave’s public key tied to your code, it’s possible to seal secrets which can only be decrypted by a specific Cosmian Enclave. The output of seal command is an encrypted file which can be sent to the SGX operator to start your application.

$ mse home seal --input example/secrets_to_seal.json \
                --receiver-enclave /tmp/ratls.pem \
                --output code_provider/secrets_to_seal.json.seal

Finalize the configuration and run the application

User

This command is for the SGX operator role

$ mse home run --sealed-secrets code_provider/secrets_to_seal.json.seal \
               --secrets example/secrets.json \
               app_name

If the command is successful, your application now running normally using a RA-TLS certificate.

Test the deployed application

User

This command is for the SGX operator role

$ mse home test --test sgx_operator/tests/ \
                --config sgx_operator/mse.toml \
                app_name

This command helps to check that the application is executed properly as the code provider expects.

Example of encryption on the application side

User

These commands are for the code provider role

If your are using the example from mse scaffold command, there are endpoints to show how to encrypt the body of an HTTP response with a key provided with sealed secrets at the start of your application.

Sealed secrets

The JSON file secrets_to_seal.json has been sent sealed to the enclave at step seal secrets. The JSON value corresponding to JSON key result_sk inserted in secrets_to_seal.json will be used to encrypt the response.

Remember that seal secrets can only be decrypted by the specific Cosmian Enclave used as receiver.

First collect the encrypted result:

curl --cacert /tmp/ratls.pem https://<IP_ADDR>:9999/result/sealed_secrets > result.enc

and decrypt the result with key.bin which contains the raw bytes of result_sk key (not encoded in Base64 such as in secrets_to_seal.json):

$ mse home decrypt --input result.enc
                   --key key.bin \
                   --output code_provider/result.plain
$ cat code_provider/result.plain
message using result_sk from SEALED_SECRETS

The decrypt command only supports Fernet algorithm. This is a toy example and we advise to use proper encryption methods such as AES-256 or XChacha20.

© Copyright 2018-2024 Cosmian. All rights reserved.