envcas
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 envconsul
, envdir
and envchain
. However, 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
.
Configuration
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.yaml
is 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 envcas
.
Python Example
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.
Bash Example
An example policy that creates two configuration files:
/work/out1
that contains ASCII secretexample_secret
/work/out2
that contains binary secretexample2_secret
- sets one environment variable
SECRET_ENV
, and - executes
bash
with arguments-c 'cat /work/out1'
We show once how to configure a native application with and without an OTP (One Time Password:
- see service
envcas
in the policy for how to configure without an OTP - see service
with_otp
to 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
The binary envcas
is part of image registry.scontain.com/edge/envcas
. You can run it as follows:
SCONE_CONFIG_ID=$SESSION/envcas /bin/envcas
In this example, we would output the generated secret, i.e., the output could look as follows:
Secret="`Y'/c'fV],=G9JJHdJz9(6HaZ>>t}x}Y"
A runnable example can be found in here.
Using OTPs
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:
one_time_password_shared_secret: $$SCONE::otp_secret$$
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:
Secret="=0r|GdtX9lGS*HtR/U'^U'PPH)H^\T<{"
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.