Docs

Adding a service

Adding a service to your application requires three steps, which are described in the following.

Step 1: Get your service ready for Marblerun

To get your service ready for Marblerun, you possibly need to adapt its code slightly and you need to rebuild it. Details are given in the following steps 1.1 and 1.2. Note that we are working on making these unnecessary in the future - at least for services written in Go.

Step 1.1: Make your service use the provided TLS credentials

Quick refresher: Marblerun’s Coordinator issues TLS credentials for each verified Marble (i.e., a service running in a secure enclave) as is described here.

The TLS X.509 certificate and the corresponding private key can be securely passed to a service through files, environments variables, or commandline arguments. This is defined in the Manifest as is described here.

For now, you just need to make sure that your service reads the certificate and the private key from arbitrary paths, environment variables, or commandline arguments, e.g., the file /tmp/mycert.cert or the environment variable MY_PRIVATE_KEY, and uses them at runtime for internal and external connections. If you’re lucky, your service already does this and you don’t need to change a thing in the code.

For services written in Go, we provide a convenience package called github.com/edgelesssys/ertgolib/marble. With it, a service can automatically get and use its Marblerun TLS credentials. The following gives an example.

func main() {
    serverCfg, err := marble.GetTLSConfig(false)
    if err != nil {
        log.Fatalf("Failed to retrieve server TLS config from ertgolib")
    }
    serverCreds := credentials.NewTLS(serverCfg)
    // use serverCreds, e.g., to create an HTTPS server
}

Step 1.2: Re-compile/build your service for Marblerun

Finally, you need to re-build your service for the enclave environment and include/link Marblerun-specific code. Please follow the build instructions for Go provided here or the build instructions for C++ provided here.

Step 2: Define your service in the Manifest

Now that your service is ready, you need to make two types of entries in the Manifest regarding its properties and parameters.

Step 2.1: Define the enclave software-package

As is described in more detail here, the Manifest contains a section Packages, in which allowed enclave software-packages are defined.

To add an entry for your service, run the oesign tool on the enclave file you built in the previous step as follows. (oesign is installed with Edgeless RT.)

oesign eradump -e enclave.signed

The tool’s output will look like the following.

{
    "UniqueID": "6b2822ac2585040d4b9397675d54977a71ef292ab5b3c0a6acceca26074ae585",
    "SignerID": "5826218dbe96de0d7b3b1ccf70ece51457e71e886a3d4c1f18b27576d22cdc74",
    "SecurityVersion": 1,
    "ProductID": 3
}

Use UniqueID (i.e., MRENCLAVE in Intel SGX speak) or the triplet of SignerID (i.e., MRSIGNER), SecurityVersion, and ProductID to add an entry in the Packages section.

Step 2.2: Define the parameters

Now you can define with which parameters (i.e., files, environments variables, and command line arguments) your service is allowed to run. This is done in the Marbles section of the Manifest as is described here. As discussed in Step #1.1, you need to make sure that the TLS credentials for your service (i.e., Marblerun.MarbleCert.Cert and Marblerun.MarbleCert.Private) are injected such that your service will find them at runtime. If your service is written in Go and you’re using the marble package, there is no need to inject these explicitly.

Step 3: Start your service

When you start your service, you need to pass in a couple of configuration parameters through environment variables. Here is an example:

EDG_MARBLE_COORDINATOR_ADDR=coordinator-mesh-api.marblerun:25554 EDG_MARBLE_TYPE=mymarble EDG_MARBLE_UUID_FILE=$PWD/uuid EDG_MARBLE_DNS_NAMES=localhost,myservice erthost enclave.signed

erthost is the generic host for Marbles, which will load your enclave.signed. The environment variables have the following purposes.

  • EDG_MARBLE_COORDINATOR_ADDR is the network address of the Coordinator’s API for Marbles. When you deploy the Coordinator using our Helm repository as is described here, the default address is coordinator-mesh-api.marblerun:25554.

  • EDG_MARBLE_TYPE needs to reference one entry from your Manifest’s Marbles section.

  • EDG_MARBLE_UUID_FILE is the local file path where the Marble stores its UUID. Every instance of a Marble has its unique and public UUID. The file is needed to allow a Marble to restart under its UUID.

  • EDG_MARBLE_DNS_NAMES is the list of DNS names the Coordinator will issue the Marble’s certificate for.

Typically, you will define these in a Kubernetes manifest or a Helm chart, for example:

spec:
    containers:
    - env:
    - name: EDG_MARBLE_COORDINATOR_ADDR
        value: coordinator-mesh-api.marblerun:25554
    - name: EDG_MARBLE_TYPE
        value: mymarble
    - name: EDG_MARBLE_DNS_NAMES
        value: "localhost,myservice"
    - name: EDG_MARBLE_UUID_FILE
        value: "$PWD/uuid"

Refer to our emojivoto app for Helm chart examples.