Building a service: Graphene

Running a Graphene app with Marblerun requires some changes to its manifest. These are explained in the following. See also the helloworld example.


First, get Graphene up and running. You can use either the Building or Cloud Deployment guide to build and initially setup Graphene.

Before running your application, make sure you got the prerequisites for ECDSA remote attestation installed on your system. You can collectively install them with the following command:

sudo apt install libsgx-quote-ex-dev


Entrypoint and argv

We provide the premain-graphene executable and shared library with the Marblerun Releases. It will contact the Coordinator, set up the environment, and run the actual application.

You can choose between the two, depending on your use case. The executable comes with the advantage of Marblerun being able to provision both, environment variables and argv arguments over its manifest, yet needs longer to load. The shared library allows for a quicker launch of your service, however it only allows Marblerun to define the environment variables, and requires you to specify the argv arguments during build time of your Graphene project.

  • premain-graphene: Set the premain executable as the entry point of the Graphene project and place the actual entry point in argv0:
    libos.entrypoint = "file:premain-graphene"
    sgx.trusted_files.premain = "file:premain-graphene"
    # argv0 needs to contain the name of your executable
    loader.argv0_override = "hello"

    After the premain is done running, it will automatically spawn your application.

  • Specify the shared library as a paramter for LD_PRELOAD, and set the entry point of the Graphene project to your executable:
    loader.env.LD_PRELOAD = "./"
    sgx.trusted_files.marblerun_premain = ""
    # argv can be provided via a file generated by Graphene's argv_serializer
    loader.argv_src_file = "file:hello.argv"
    sgx.trusted_files.argv = "file:hello.argv"

    Note that in this case Graphene determines the argv arguments to use, and the option in Marblerun’s manifest will be ignore. To set the argv arguments to use, it is recommended to set the arguments with the help of loader.argv_src_file, for which the source file can be generated with Graphene’s argv_serializer utility.

For a better illustration on the differences between the two premain variants, check out our “Hello World” sample on GitHub.

Host environment variables

The premain needs access to some host environment variables for configuration:

loader.insecure__use_host_env = 1

The premain will remove all other variables before the actual application is launched, so this is secure.

uuid file

The Marble must be able to store its uuid:

sgx.allowed_files.uuid = "file:uuid"

Remote attestation

The Marble will send an SGX quote to the Coordinator for remote attestation:

sgx.remote_attestation = 1

Enclave size and threads

The premain process is written in Go. The enclave needs to have enough resources for the Go runtime:

sgx.enclave_size = "1024M"
sgx.thread_num = 16

If your application has high memory demands, you may need to increase the size even further.

Secret files

A Marble’s secrets, e.g. a certificate and private key, can be provisioned as files. Ideally, these would be placed in the Marble’s in-memory filesystem. Graphene does not support this yet, but you can fall back on Graphene Protected Files instead:

sgx.protected_files.cert = "file:server.crt"
sgx.protected_files.privkey = "file:server.key"

You can specify the files' content in the Marblerun Manifest:

    "Parameters": {
        "Files": {
            "/dev/attestation/protected_files_key": "{{ hex .Marblerun.SealKey }}",
            "server.crt": "{{ pem .Secrets.server_cert.Cert }}",
            "server.key": "{{ pem .Secrets.server_cert.Private }}"

Note that Graphene requires to initialize the protected files key by writing it hex-encoded to the virtual protected_files_key device. This can be easily done through the above manifest configuration.

You can see this in action in the nginx example.


aesm_service returned error: 30

If you receive the following error message on launch:

aesm_service returned error: 30
load_enclave() failed with error -1

Make sure you installed the Intel AESM ECDSA plugins on your machine. You can do this by installing the libsgx-quote-dev package mentioned in the requirements above.