envcas provides a convenient way to launch a native subprocess with
- environment variables und arguments populated from SCONE CAS,
- configuration files automatically generated and populated from SCONE CAS.
The tool is inspired by
envcas runs as a confidential application and we perform an attestation of
envcas first. Hence, one can even require an OTP (One Time Password) to be able to execution of
envcas with the help of the policy of
envcas takes its environment variables and its arguments and execute a given native program.
envcas is controlled by the following configuration file
/etc/envcas/config.yamlis the configuration file. It contains the following sections:
program: path/to/native/binary injected_file: - from: /etc/envcas/original_injected_file1 to: /path/to/injected_file1 - from: /etc/envcas/original_injected_file2 to: /path/to/injected_file2
The program is the binary that should be executed and the injected files, the
from is the file injected by CAS into
envcas and that is copied to a certain location indicated by
to. We assume that all directories on the
to path exists, i.e.,
envcas will fail to write the files in case the path does not exists.
This configuration files is typically defined within the policy of
In the envcas example repository there is a runnable example on how to use
envcas for a native Python3.9 app. It includes an example of how to get normal environment variables in addition to those included in the security policy.
An example policy that creates two configuration files:
/work/out1that contains ASCII secret
/work/out2that contains binary secret
- sets one environment variable
-c 'cat /work/out1'
We show once how to configure a native application with and without an OTP (One Time Password:
- see service
envcasin the policy for how to configure without an OTP
- see service
with_otpto see how to configure with an OTP. The OTP secret can be defined as a secret. We explicitly define it in the session. Typically, we would import this secret from another session to limit who can see the secret in the clear.
Our policy (
session.yaml) could look as follows:
name: $SESSION version: "0.3.10" security: attestation: tolerate: [debug-mode,hyperthreading, outdated-tcb] ignore_advisories: "*" images: - name: envcas_image injection_files: - path: /etc/envcas/config.yaml content: | program: /bin/bash injection_files: - from: /etc/envcas/injected_file1 to: /work/out1 - from: /etc/envcas/injected_file2 to: /work/out2 - path: /etc/envcas/injected_file1 content: | Secret="$$SCONE::example_secret$$" - path: /etc/envcas/injected_file2 content: | Secret=$$SCONE::example2_secret$$ services: - name: envcas image_name: envcas_image mrenclaves: [$MRENCLAVE] command: envcas -c 'cat /work/out1' environment: SCONE_MODE: hw SCONE_LOG: ERROR pwd: / - name: with_otp image_name: envcas_image attestation: mrenclave: "$MRENCLAVE" one_time_password_shared_secret: $$SCONE::otp_secret$$ command: envcas -c 'cat /work/out1' environment: SCONE_MODE: hw SCONE_LOG: ERROR pwd: / secrets: - name: example_secret kind: ascii size: 32 - name: example2_secret kind: binary size: 64 - name: otp_secret kind: ascii value: JJBFGV2ZGNCFARKIKBFTGUCYKBNFKVQK
One can instantiate the environment variables in
session.yaml and then upload this policy as follows:
cd /work export SCONE_CAS_ADDR=edge.scone-cas.cf export SCONE_LAS_ADDR=172.17.0.1 export SESSION=envcas-example-$RANDOM-$RANDOM export MRENCLAVE=$(docker run --rm -v $PWD:/work registry.scontain.com/edge/envcas sh -c "SCONE_HASH=1 /bin/envcas") scone cas attest $SCONE_CAS_ADDR --only_for_testing-trust-any --only_for_testing-debug --only_for_testing-ignore-signer -C -G -S scone session create -e SESSION=$SESSION -e MRENCLAVE=$MRENCLAVE session.yaml SCONE_CONFIG_ID=$SESSION/envcas /bin/envcas
envcas is part of image
registry.scontain.com/edge/envcas. You can run it as follows:
In this example, we would output the generated secret, i.e., the output could look as follows:
A runnable example can be found in here.
To require an OTP, you would define a service like
with_otp. Note. In this case, you would not define service
envcas to avoid that one can circumvent using an OTP.
The OTP is enabled by defining the key
one_time_password_shared_secret in the service description:
The OTP secret is defined in the secret section. In this example, we define with an explicit value. As we mentioned above, our recommendation is to import this from another session to limit visibility of this secret.
To run binary
envcas as service
with_otp, we need to add an OTP to the `SCONE_CONFIG_ID':
export OTP=... # define OTP using an authenticator SCONE_CONFIG_ID=$SESSION/with_otp@$OTP /bin/envcas
If the OTP is correct, the output might look as follows:
If the OTP would be incorrect or already used, the output might look as follows:
[SCONE|FATAL] src/process/init.c:302:__scone_prepare_secure_config(): Could not initialize enclave state: Attestation failed Caused by: CAS sent an attestation/configuration error: Failed to retrieve service attestation configuration Caused by: A One-time Password was already used within this time-step. Please try again in the next time-step Note: Connecting to CAS at edge.scone-cas.cf (port 18765) using service ID envcas-example-31925-25152/with_otp@964428 [SCONE|ERROR] tools/starter/signal.c:70:die_by_signal(): Enclave terminated due to signal: Aborted Aborted (core dumped)
The example for OTP usage is in the same policy as the Bash one, in here.