|
| 1 | +--- |
| 2 | +title: Build Your First Application with Scone Framework |
| 3 | +description: |
| 4 | + Learn how to build and run Confidential Computing applications with the Scone |
| 5 | + TEE framework for secure, privacy-preserving computation |
| 6 | +--- |
| 7 | + |
| 8 | +# Build your first application with Scone framework |
| 9 | + |
| 10 | +In this tutorial, you will learn how to build and run a Confidential Computing |
| 11 | +application with the Scone TEE framework. |
| 12 | + |
| 13 | +::: warning |
| 14 | + |
| 15 | +Before going any further, make sure you managed to |
| 16 | +[Build your first application](./build-your-first-app). |
| 17 | + |
| 18 | +::: |
| 19 | + |
| 20 | +::: tip Prerequisites: |
| 21 | + |
| 22 | +- [Docker](https://docs.docker.com/install/) 17.05 or higher on the daemon and |
| 23 | + client. |
| 24 | +- [iExec SDK](https://www.npmjs.com/package/iexec) 8.0.0 or higher. |
| 25 | + [Install the iExec SDK](./quick-start-for-developers.md#install-the-iexec-sdk) |
| 26 | +- Familiarity with the basic concepts of |
| 27 | + [Intel® SGX](/get-started/protocol/tee/intel-sgx) and |
| 28 | + [SCONE](https://scontain.com) framework. |
| 29 | + |
| 30 | +::: |
| 31 | + |
| 32 | +In order to follow this tutorial, you will need to register a |
| 33 | +[free SCONE Account](https://scontain.com) to access SCONE build tools and |
| 34 | +curated images from the [SCONE registry](https://gitlab.scontain.com/). |
| 35 | + |
| 36 | +Once your account is activated, you need to |
| 37 | +[request access to the SCONE build tools for iExec ](mailto:[email protected][email protected]&subject=iExec%20Build%20Tools&body=Hi%20SCONE%20Team%2C%0D%0A%0D%0AI%20would%20like%20to%20get%20access%20to%20the%20SCONE%20build%20tools%20for%20iExec:%0A%20-%20scone-production/iexec-sconify-image%0A%20-%20sconecuratedimages%20%28all%20curated%20images%20such%20as%20nodejs%2C%20python...%29%0A%0AMy%20DockerID%20is%20...%0A%0ABest%20regards%0A%0A...). |
| 38 | + |
| 39 | +```bash |
| 40 | +# when your account is ready, run `docker login` to connect the SCONE registry |
| 41 | +docker login registry.scontain.com |
| 42 | +``` |
| 43 | + |
| 44 | +## Prepare your application |
| 45 | + |
| 46 | +Before going further, your `<docker-hub-user>/hello-world:1.0.0` image built |
| 47 | +previously is required. |
| 48 | + |
| 49 | +If you missed that part, please go back to |
| 50 | +[Build your first application](./build-your-first-app). |
| 51 | + |
| 52 | +For this tutorial, you can reuse the same directory tree or create a new one. |
| 53 | + |
| 54 | +To create a new directory tree, execute the following commands in |
| 55 | +`~/iexec-projects/`. |
| 56 | + |
| 57 | +```bash |
| 58 | +cd ~/iexec-projects |
| 59 | +mkdir tee-hello-world-app && cd tee-hello-world-app |
| 60 | +iexec init --skip-wallet |
| 61 | +mkdir src |
| 62 | +touch Dockerfile |
| 63 | +touch sconify.sh |
| 64 | +chmod +x sconify.sh |
| 65 | +``` |
| 66 | + |
| 67 | +## Build the TEE docker image |
| 68 | + |
| 69 | +Before wrapping your iExec confidential application with Scone, you need to |
| 70 | +generate a custom signing key. This key is used for the sconification process. |
| 71 | + |
| 72 | +Generate your enclave signing key with: |
| 73 | + |
| 74 | +```bash |
| 75 | +openssl genrsa -3 -out enclave-key.pem 3072 |
| 76 | +``` |
| 77 | + |
| 78 | +This will create an `enclave-key.pem` file in your current directory. You will |
| 79 | +use this file in the sconify Docker command to sign your TEE image. |
| 80 | + |
| 81 | +We will use the following script to wrap the sconification process, copy the |
| 82 | +`sconify.sh` script in the current directory: |
| 83 | + |
| 84 | +::: code-group |
| 85 | + |
| 86 | +```bash [Javascript] |
| 87 | +#!/bin/bash |
| 88 | + |
| 89 | +# Declare image related variables |
| 90 | +IMG_FROM=<docker-hub-user>/hello-world:1.0.0 |
| 91 | +IMG_TO=<docker-hub-user>/tee-scone-hello-world:1.0.0 |
| 92 | + |
| 93 | +# Run the sconifier to build the TEE image based on the non-TEE image |
| 94 | +docker run -it --rm \ |
| 95 | + -v $PWD/enclave-key.pem:/sig/enclave-key.pem \ |
| 96 | + -v /var/run/docker.sock:/var/run/docker.sock \ |
| 97 | + registry.scontain.com/scone-production/iexec-sconify-image:5.9.1-v16\ |
| 98 | + sconify_iexec \ |
| 99 | + --from=${IMG_FROM} \ |
| 100 | + --to=${IMG_TO} \ |
| 101 | + --binary-fs \ |
| 102 | + --fs-dir=/app \ |
| 103 | + --host-path=/etc/hosts \ |
| 104 | + --host-path=/etc/resolv.conf \ |
| 105 | + --binary=/usr/local/bin/node \ |
| 106 | + --heap=1G \ |
| 107 | + --dlopen=1 \ |
| 108 | + --verbose \ |
| 109 | + && echo -e "\n------------------\n" \ |
| 110 | + && echo "successfully built TEE docker image => ${IMG_TO}" \ |
| 111 | + && echo "application mrenclave.fingerprint is $(docker run --rm -e SCONE_HASH=1 ${IMG_TO})" |
| 112 | +``` |
| 113 | + |
| 114 | +```bash [Python] |
| 115 | +#!/bin/bash |
| 116 | + |
| 117 | +# Declare image related variables |
| 118 | +IMG_FROM=<docker-hub-user>/hello-world:1.0.0 |
| 119 | +IMG_TO=<docker-hub-user>/tee-scone-hello-world:1.0.0 |
| 120 | + |
| 121 | +# Run the sconifier to build the TEE image based on the non-TEE image |
| 122 | +docker run -it --rm \ |
| 123 | + -v $PWD/enclave-key.pem:/sig/enclave-key.pem \ |
| 124 | + -v /var/run/docker.sock:/var/run/docker.sock \ |
| 125 | + registry.scontain.com/scone-production/iexec-sconify-image:5.9.1-v16\ |
| 126 | + sconify_iexec \ |
| 127 | + --from=${IMG_FROM} \ |
| 128 | + --to=${IMG_TO} \ |
| 129 | + --binary-fs \ |
| 130 | + --fs-dir=/app \ |
| 131 | + --host-path=/etc/hosts \ |
| 132 | + --host-path=/etc/resolv.conf \ |
| 133 | + --binary=/usr/local/bin/python3 \ |
| 134 | + --heap=1G \ |
| 135 | + --dlopen=1 \ |
| 136 | + --verbose \ |
| 137 | + && echo -e "\n------------------\n" \ |
| 138 | + && echo "successfully built TEE docker image => ${IMG_TO}" \ |
| 139 | + && echo "application mrenclave.fingerprint is $(docker run --rm -e SCONE_HASH=1 ${IMG_TO})" |
| 140 | +``` |
| 141 | + |
| 142 | +::: |
| 143 | + |
| 144 | +Run the `sconify.sh` script to build the Scone TEE application: |
| 145 | + |
| 146 | +```bash |
| 147 | +./sconify.sh |
| 148 | +``` |
| 149 | + |
| 150 | +Push your image on DockerHub: |
| 151 | + |
| 152 | +```bash |
| 153 | +docker push <docker-hub-user>/tee-scone-hello-world:1.0.0 |
| 154 | +``` |
| 155 | + |
| 156 | +Congratulations, you just built your Scone TEE application. |
| 157 | + |
| 158 | +## Test your app on iExec |
| 159 | + |
| 160 | +At this stage, your application is ready to be tested on iExec. The process is |
| 161 | +similar to testing any type of application on the platform, with these minor |
| 162 | +exceptions: |
| 163 | + |
| 164 | +### Deploy the TEE app on iExec |
| 165 | + |
| 166 | +TEE applications require some additional information to be filled in during |
| 167 | +deployment. |
| 168 | + |
| 169 | +```bash |
| 170 | +# prepare the TEE application template |
| 171 | +iexec app init --tee |
| 172 | +``` |
| 173 | + |
| 174 | +Edit `iexec.json` and fill in the standard keys and the `mrenclave` object: |
| 175 | + |
| 176 | +```json |
| 177 | +{ |
| 178 | + ... |
| 179 | + "app": { |
| 180 | + "owner": "<your-wallet-address>", // starts with 0x |
| 181 | + "name": "tee-scone-hello-world", // application name |
| 182 | + "type": "DOCKER", |
| 183 | + "multiaddr": "docker.io/<docker-hub-user>/tee-scone-hello-world:1.0.0", // app image |
| 184 | + "checksum": "<checksum>", // starts with 0x, update it with your own image digest |
| 185 | + "mrenclave": { |
| 186 | + "framework": "SCONE", // TEE framework (keep default value) |
| 187 | + "version": "v5.9", // Scone version (keep default value) |
| 188 | + "entrypoint": "node /app/app.js" OR "python3 /app/app.py", // update it with your own image entrypoint |
| 189 | + "heapSize": 1073741824, // heap size in bytes, update it with --heap option value used in sconify.sh script during TEE image build |
| 190 | + "fingerprint": "<mrenclave>" // fingerprint of the enclave code (mrenclave), without 0x prefix, see how to retrieve it below |
| 191 | + } |
| 192 | + }, |
| 193 | + ... |
| 194 | +} |
| 195 | +``` |
| 196 | + |
| 197 | +::: info |
| 198 | + |
| 199 | +See |
| 200 | +[Create your identity on the blockchain](./quick-start-for-developers.md#create-your-identity-on-the-blockchain) |
| 201 | +to retrieve `<your-wallet-address>` value. |
| 202 | + |
| 203 | +See |
| 204 | +[Deploy your app on iExec](./build-your-first-app.md#deploy-your-app-on-iexec) |
| 205 | +to retrieve your image `<checksum>`. |
| 206 | + |
| 207 | +Run your TEE image with `SCONE_HASH=1` to get the enclave fingerprint |
| 208 | +(mrenclave): |
| 209 | + |
| 210 | +```bash |
| 211 | +docker run --rm -e SCONE_HASH=1 <docker-hub-user>/tee-scone-hello-world:1.0.0 |
| 212 | +``` |
| 213 | + |
| 214 | +::: |
| 215 | + |
| 216 | +Deploy the app with the standard command: |
| 217 | + |
| 218 | +```bash twoslash |
| 219 | +iexec app deploy --chain {{chainName}} |
| 220 | +``` |
| 221 | + |
| 222 | +### Run the TEE app |
| 223 | + |
| 224 | +Specify the tag `--tag tee,scone` in `iexec app run` command to run a tee app. |
| 225 | + |
| 226 | +One last thing, in order to run a **TEE** app you will also need to select a |
| 227 | +workerpool, use the iexec workerpool `{{workerpoolAddress}}`. |
| 228 | + |
| 229 | +You are now ready to run the app |
| 230 | + |
| 231 | +```bash twoslash |
| 232 | +iexec app run --chain {{chainName}} --tag tee,scone --workerpool {{workerpoolAddress}} --watch |
| 233 | +``` |
| 234 | + |
| 235 | +::: info |
| 236 | + |
| 237 | +Remember, you can access task and app logs by following the instructions on page |
| 238 | +[Debug your tasks](/guides/build-iapp/debugging). |
| 239 | + |
| 240 | +::: |
| 241 | + |
| 242 | +## Next step? |
| 243 | + |
| 244 | +In this tutorial, you learned how to leverage your application with the power of |
| 245 | +Trusted Execution Environments using iExec. But according to your use case, you |
| 246 | +may need to use some confidential data to get the full potential of the |
| 247 | +**Confidential Computing** paradigm. Check out next chapters to see how: |
| 248 | + |
| 249 | +- [Access confidential assets from your app](access-confidential-assets.md) |
| 250 | +- [Protect the result](./protect-the-result.md) |
| 251 | + |
| 252 | +<script setup> |
| 253 | +import { computed } from 'vue'; |
| 254 | +import useUserStore from '@/stores/useUser.store'; |
| 255 | +import {getChainById} from '@/utils/chain.utils'; |
| 256 | + |
| 257 | +// Get current chain info |
| 258 | +const userStore = useUserStore(); |
| 259 | +const selectedChain = computed(() => userStore.getCurrentChainId()); |
| 260 | + |
| 261 | +const chainData = computed(() => getChainById(selectedChain.value)); |
| 262 | +const chainName = computed(() => chainData.value.chainName); |
| 263 | +const workerpoolAddress = computed(() => chainData.value.workerpoolAddress); |
| 264 | +</script> |
0 commit comments