iExec Protocol
v8
Search
K

Attach a secret to your app

In this tutorial, you will learn how to leverage an application developer secret by using the IEXEC_APP_DEVELOPER_SECRET environment variable in your application code.
Before going any further, make sure you managed to Build with a TEE framework.
Prerequisites:
Trusted Execution Environments offer a huge advantage from a security perspective. They guarantee that the behavior of execution does not change even when launched on an untrusted remote machine. The data inside this type of environment is also protected, which allows its monetization while preventing leakage.
With iExec, it is possible to securely associate an application developer secret to the runtime of an application. This association is performed through the usage of environment variables which cannot leak outside of the enclave memory.
The app developer secret is only exposed to your app inside authorized enclaves and never leaves them.
Your secrets are transferred with the SDK from your machine to the SMS over a TLS channel.
Let's see how to do all of that!

Prepare your application

For demo purposes, we omitted some development best practices in these examples.
Make sure to check your field's best practices before going to production.
We will use the API countapi.xyz. This service keeps a count of hits on any couple of namespace/key (ex: https://api.countapi.xyz/hit/foo/bar).
In this example, we will use an app developer secret to set namespace/key.
Let's create a directory tree for this app in ~/iexec-projects/.
cd ~/iexec-projects
mkdir tee-developer-secret-app && cd tee-developer-secret-app
iexec init --skip-wallet
mkdir src
touch Dockerfile
touch sconify.sh
chmod +x sconify.sh
Depending on the TEE framework you are using, make sure your chain.json content is correct:
The application uses the developer secret to make a call to a secret endpoint of countapi.xyz and writes the result in a file:
Copy the following content in src/ .
Javascript
Python
src/app.js
const fsPromises = require("fs").promises;
const axios = require("axios");
(async () => {
try {
const iexecOut = process.env.IEXEC_OUT;
// get the secret endpoint from app developer secret
const secret = process.env.IEXEC_APP_DEVELOPER_SECRET;
if (!secret) {
console.log("missing IEXEC_APP_DEVELOPER_SECRET");
process.exit(1);
}
// get the hit count from countapi
const hitCount = await axios
.get(`https://api.countapi.xyz/hit/iexec/${secret}`)
.then(({ data }) => data.value);
const result = `endpoint hit ${hitCount} times`;
console.log(result);
// write the result
await fsPromises.writeFile(`${iexecOut}/result.txt`, result);
// declare everything is computed
const computedJsonObj = {
"deterministic-output-path": `${iexecOut}/result.txt`,
};
await fsPromises.writeFile(
`${iexecOut}/computed.json`,
JSON.stringify(computedJsonObj)
);
} catch (e) {
// do not log anything that could reveal the app developer secret!
console.log("something went wrong");
process.exit(1);
}
})();
src/app.py
import os
import json
import requests
try:
iexec_out = os.environ["IEXEC_OUT"]
# get the secret endpoint from app developer secret
try:
secret = os.environ["IEXEC_APP_DEVELOPER_SECRET"]
except Exception:
print("missing IEXEC_APP_DEVELOPER_SECRET")
exit(1)
# get the hit count from countapi
response = requests.request("GET", "https://api.countapi.xyz/hit/iexec/" + secret)
json_response = response.json()
hit_count = json_response["value"]
result = "endpoint hit " + str(hit_count) + " times"
print(result)
# write the result
with open(iexec_out + "/result.txt", "w+") as fout:
fout.write(result)
# declare everything is computed
with open(iexec_out + "/computed.json", "w+") as f:
json.dump({ "deterministic-output-path" : iexec_out + "/result.txt" }, f)
except Exception:
# do not log anything that could reveal the app developer secret!
print("something went wrong")
exit(1)
As seen above, a single slot is dedicated to store the application developer secret. If you want to use multiple secrets, feel free to pack your secrets into a single one and unpack them when reading the IEXEC_APP_DEVELOPER_SECRET environment variable from the application code.

Build a Confidential Computing application

Build the docker image

Scone
Gramine
In this section, you will:
Create the Dockerfile
For a Javascript application:
# Starting from a base image supported by SCONE
FROM node:14-alpine3.11
# install your dependencies
RUN mkdir /app && cd /app && npm install axios
COPY ./src /app
ENTRYPOINT [ "node", "/app/app.js"]
For a Python application:
FROM python:3.7.3-alpine3.10
RUN pip3 install requests
COPY ./src /app
ENTRYPOINT ["python3", "/app/app.py"]
Build the docker image.
docker build . --tag <docker-hub-user>/count-api:1.0.0
Follow the steps described in Build Scone app > Build the TEE docker image.
Update the sconify.sh script with the variables as follow:
# Declare image related variables
IMG_NAME=tee-scone-count-api
IMG_FROM=<docker-hub-user>/count-api:1.0.0
IMG_TO=<docker-hub-user>/${IMG_NAME}:1.0.0-debug
Run the sconify.sh script to build the Scone TEE application:
./sconify.sh
In this section, you will create a Dockerfile and create your Gramine TEE application as we saw in Build Gramine app > Prepare your application.
You need to copy the Dockerfile, then update its RUN statements to install required dependencies for your application:
For a Javascript application:
# Install required node dependencies
RUN npm install axios
For a Python application:
# Install required Python dependencies
RUN pip3 install requests
Build the docker image.
docker build . --tag <docker-hub-user>/tee-gramine-count-api:1.0.0

Push the image on Docker Hub

Scone
Gramine
docker push <docker-hub-user>/tee-scone-count-api:1.0.0-debug
docker push <docker-hub-user>/tee-gramine-count-api:1.0.0

Test your app on iExec

At this stage, your application is ready to be tested on iExec with the following steps:

Deploy the TEE app on iExec

Push an application developer secret to the SMS

iexec app push-secret --chain bellecour

Check the secret exists in the SMS

iexec app check-secret --chain bellecour

Run the TEE app

Next step?

Thanks to the explained confidential computing workflow, you now know how to use an app developer secret in a Confidential Computing application.
To go further, check out how to: