Skip to content

Secure Arguments and Environment Variables

We show how to pass arguments and environment variables in a secure fashion to an application with the help of CAS.

SCONE CAS Overview

SCONE CAS manages the keys of an application. The keys are unter complete control of the application: only services given explicit control by the application get access to the keys.


We assume that you already

We also assume that this example is executed in the context of Ubuntu. For other Linux variants, you might need to use a different cross-compiler image. Alternatively, you could execute this example in the crosscompiler container but you need to ensure that the container can establish https connections to CAS and LAS.

Simple Example

We create a simple C program to print the arguments as well as the environment variables:

cat > print-arg-env.c <<EOF
#include <stdio.h>

extern char **__environ;

int main (int argc, char **argv) {
    for (int i = 0; i < argc; i++) {
        printf(" %s", argv[i]);

    char** envp = __environ;
    while (*envp != NULL) {
        printf("%s\n", *envp);
    return 42;

We can compile this natively as follows:

gcc print-arg-env.c -g -O3 -o print-arg-env

And we can now run this with some some arguments and some environment variables:

ENV2=World ENV1=! ./print-arg-env Hello

This results in an output similar to this:

argv: ./print-arg-env Hello

Let's cross-compile this program to run inside of enclaves as follows:

docker run --device=/dev/isgx -it --privileged -v `pwd`:/work sconecuratedimages/crosscompilers:ubuntu16.04 scone-gcc /work/print-arg-env.c -g -O3 -o /work/scone-print-arg-env

We can now determine MRENCLAVE as follows:

export MRENCLAVE=`SCONE_HASH=1 ./scone-print-arg-env`
echo MRENCLAVE of scone-print-arg-env is $MRENCLAVE

We can now run the program inside of an enclave but not under the control of CAS as follows:

ENV2=World ENV1=! ./scone-print-arg-env Hello

This will result in the same output as before:

argv: ./print-arg-env Hello

Without CAS: No Confidentiality and Integrity of Arguments and Environment Variables

Note that neither the integrity nor the confidentiality of these arguments are protected. To protect these and to ensure that the program is indeed executed inside an enclave, we need to run the program in the context of CAS.**

Secure Arguments and Environment Variables

In the next step, we control the environment variables and the arguments with the help of CAS.

When does the SCONE runtime use CAS?

When environment variable SCONE_CONFIG_ID is not set, the SCONE runtime will not contact CAS. If it is set, we will contact SCONE_CAS_ADDR. If SCONE_CAS_ADDR is not set, we contact by default host „cas“. The SCONE runtime will also contact SCONE_LAS_ADDR for local attestation. If SCONE_LAS_ADDR is not set, we contact by default host „las“.

We assume that you already started a CAS in the background via docker-compose up -d cas on the local machine:


Alternatively, you can use the public CAS server at


We also assume that you already started a LAS in the background via docker-compose up -d las on the local machine:


We can now create a new session on cas as follows:

cat > session.yml <<EOF
name: secure-arguments-example
digest: somedigest

   - name: scone-print-arg-env
     mrenclaves: [$MRENCLAVE]
     tags: [thisissometag1]
     command: ./scone-print-arg-env arg1 arg2 arg3
        SCONE_MODE: hw
        env1: running
        env2: in
        env3: enclave
     pwd: /

Let's make sure that we have a client certificate to identify this client:

    mkdir -p conf
    if [[ ! -f conf/client.crt || ! -f conf/client-key.key  ]] ; then
      openssl req -x509 -newkey rsa:4096 -out conf/client.crt -keyout conf/client-key.key \
      -days 31 -nodes -sha256 \
      -subj "/C=US/ST=Dresden/L=Saxony/O=Scontain/OU=Org/" \
      -reqexts SAN -extensions SAN \
      -config <(cat /etc/ssl/openssl.cnf <(printf '[SAN]\'))

Next, we will upload this session to CAS:

curl -k -s --cert conf/client.crt --key conf/client-key.key --data-binary @session.yml -X POST https://$SCONE_CAS_ADDR:8081/session

This results in an output similar to this:

Created Session[id=ce81e4cd-eed4-4f12-9bfc-c93e3dd4b454, name=secure-arguments, status=Pending]c

Note that if you try to upload to a session that already exists, you will get an error code like this:

Could not create successor session. Invalid previous session digest: Some("5de101e4980f312527e1c308dfe6c7bc465660c0fea6b98983efa5baf94bf362") != None

In other words, if you want to update a session, you need to define a predecessor key in the session that specifies the current session. This is to ensure that a client does not overwrite a just updated session, i.e., it permits to detect write/write conflicts.

Executing Print-Arg-Env

Let us now execute scone-print-arg-env in the context of session secure-arguments-example. To do so, we need to pass in environment variable SCONE_CONFIG_ID which contains the name of the session and we need to set SCONE_CAS_ADDRas well as SCONE_LAS_ADDR as we have shown above.

SCONE_CONFIG_ID=secure-arguments-example/scone-print-arg-env ./scone-print-arg-env

This will print the following output:

argv: ./scone-print-arg-env arg1 arg2 arg3

Note that the environment variables - except those expected by the SCONE runtime to locate LAS, CAS and the session - are ignored. This means even if we pass additional arguments and environment variables, the output does not change. The execution of

IRGNORED_ENV=1 SCONE_CONFIG_ID=secure-arguments-example/scone-print-arg-env ./scone-print-arg-env IGNORED1 IGNORED2

results in the same output:

argv: ./scone-print-arg-env arg1 arg2 arg3

The SCONE variables provided by the environment are not protected in any way and we designed SCONE assuming that an attacker could modify these environment variables. This could lead to denial of service attacks but not to the exposure of any secrets.

Integrity of SCONE environment variables

An adversary could change SCONE_CONFIG_ID, SCONE_CAS_ADDR and SCONE_LAS_ADDR but in this case, the application does not start (attestation fails) up or it does not get access to the secrets and configuration variables to do its job.