From b9727b161ec956fbb41d10b728092c34b2a6adeb Mon Sep 17 00:00:00 2001 From: Pierre Jeanjacquot <26487010+PierreJeanjacquot@users.noreply.github.com> Date: Tue, 24 Jun 2025 13:06:45 +0200 Subject: [PATCH 1/9] feat: add sconify workflow --- .github/workflows/sconify.yml | 185 ++++++++++++++++++++++++++++++++++ sconify/README.md | 140 +++++++++++++++++++++++++ 2 files changed, 325 insertions(+) create mode 100644 .github/workflows/sconify.yml create mode 100644 sconify/README.md diff --git a/.github/workflows/sconify.yml b/.github/workflows/sconify.yml new file mode 100644 index 0000000..cbb1e58 --- /dev/null +++ b/.github/workflows/sconify.yml @@ -0,0 +1,185 @@ +name: Build, Test and Push Docker Image + +on: + workflow_call: + inputs: + image-name: + description: "Name of Docker Image to Sconify" + type: string + required: true + image-tag: + description: "Tag of Docker Image to Sconify" + type: string + required: true + docker-registry: + description: "Docker Registry of Docker Image to Sconify" + default: "docker.io" + type: string + sconify-version: + description: "Version of the Sconify Image to use" + type: string + required: true + fs-dir: + type: string + description: "File System Directory to Protect" + required: true + binary: + type: string + description: "Path to the Binary to Protect" + required: true + command: + type: string + description: "Command to Protect" + required: true + heap: + type: string + default: "1G" + description: "Enclave Heap size (default 1G)" + dlopen: + type: number + default: 1 + description: "dlopen mode (default 1)" + sconify-debug: + description: "Create Scone Debug image (default true)" + default: true + type: boolean + sconify-prod: + description: "Create Scone Production image (default true)" + default: true + type: boolean + docker-username: + type: string + description: "Docker Registry Username" + required: true + scontain-username: + type: string + description: "Scontain Registry Username" + required: true + secrets: + docker-password: + description: "Docker Registry Password or Token" + required: true + scontain-password: + description: "Scontain Registry Password or Token" + required: true + scone-signing-key: + description: "Signing Key for Scone Production (not required with `sconify-prod: false`)" + required: false + outputs: + debug-image: + description: "Debug Sconified Image" + value: ${{ jobs.build.outputs.debug-image }} + debug-mrenclave: + description: "Debug Sconified Image MrEnclave Fingerprint" + value: ${{ jobs.build.outputs.debug-mrenclave }} + debug-checksum: + description: "Debug Sconified Image Checksum" + value: ${{ jobs.build.outputs.debug-checksum }} + prod-image: + description: "Prod Sconified Image" + value: ${{ jobs.build.outputs.prod-image }} + prod-mrenclave: + description: "Prod Sconified Image MrEnclave Fingerprint" + value: ${{ jobs.build.outputs.prod-mrenclave }} + prod-checksum: + description: "Prod Sconified Image Checksum" + value: ${{ jobs.build.outputs.prod-checksum }} + +jobs: + build: + runs-on: ubuntu-latest + env: + FROM_IMAGE: ${{ inputs.docker-registry }}/${{ inputs.image-name }}:${{ inputs.image-tag }} + DEBUG_IMAGE: ${{ inputs.docker-registry }}/${{ inputs.image-name }}:${{ inputs.image-tag }}-scone-debug-${{ inputs.sconify-version }} + PROD_IMAGE: ${{ inputs.docker-registry }}/${{ inputs.image-name }}:${{ inputs.image-tag }}-scone-prod-${{ inputs.sconify-version }} + outputs: + debug-image: ${{ steps.push-debug.outputs.image }} + debug-mrenclave: ${{ steps.push-debug.outputs.mrenclave }} + debug-checksum: ${{ steps.push-debug.outputs.checksum }} + prod-image: ${{ steps.push-prod.outputs.image }} + prod-mrenclave: ${{ steps.push-prod.outputs.mrenclave }} + prod-checksum: ${{ steps.push-prod.outputs.checksum }} + steps: + - name: Login to Docker Registry + uses: docker/login-action@v3 + with: + registry: ${{ inputs.docker-registry }} + username: ${{ inputs.docker-username }} + password: ${{ secrets.docker-password }} + + - name: Login to Scontain Docker Registry + uses: docker/login-action@v3 + with: + registry: "registry.scontain.com" + username: ${{ inputs.scontain-username }} + password: ${{ secrets.scontain-password }} + + - name: Pull Image to Sconify + run: docker pull ${{ inputs.docker-registry }}/${{ inputs.image-name }}:${{ inputs.image-tag }} + + - name: Pull Sconify Image + run: docker pull registry.scontain.com/scone-production/iexec-sconify-image:${{ inputs.sconify-version }} + + - name: Sconify Image Debug + if: ${{ inputs.sconify-debug }} + run: | + docker run \ + --rm \ + -v /var/run/docker.sock:/var/run/docker.sock \ + registry.scontain.com/scone-production/iexec-sconify-image:${{ inputs.sconify-version }} \ + sconify_iexec \ + --from=$FROM_IMAGE \ + --to=$DEBUG_IMAGE \ + --binary-fs \ + --fs-dir=${{ inputs.fs-dir }} \ + --host-path=/etc/hosts \ + --host-path=/etc/resolv.conf \ + --binary=${{ inputs.binary }} \ + --heap=${{ inputs.heap }} \ + --dlopen=${{ inputs.dlopen }} \ + --no-color \ + --verbose \ + --command="${{ inputs.command }}" + + - name: Push Debug Image + if: ${{ inputs.sconify-debug }} + id: push-debug + run: | + docker push $DEBUG_IMAGE + echo "image=$DEBUG_IMAGE" >> "$GITHUB_OUTPUT" + echo "checksum=$(docker image inspect $DEBUG_IMAGE | jq .[0].RepoDigests[0] | sed 's/"//g' | awk -F '@sha256:' '{print $2}')" >> "$GITHUB_OUTPUT" + echo "mrenclave=$(docker run --rm -e SCONE_HASH=1 $DEBUG_IMAGE)" >> "$GITHUB_OUTPUT" + + - name: Sconify Image Prod + if: ${{ inputs.sconify-prod }} + run: | + mkdir -p $HOME/sig + echo "${{ secrets.scone-signing-key }}" > $HOME/sig/enclave-key.pem + docker run \ + --rm \ + -v /var/run/docker.sock:/var/run/docker.sock \ + -v $HOME/sig/enclave-key.pem:/sig/enclave-key.pem \ + registry.scontain.com/scone-production/iexec-sconify-image:${{ inputs.sconify-version }} \ + sconify_iexec \ + --from=$FROM_IMAGE \ + --to=$PROD_IMAGE \ + --binary-fs \ + --fs-dir=${{ inputs.fs-dir }} \ + --host-path=/etc/hosts \ + --host-path=/etc/resolv.conf \ + --binary=${{ inputs.binary }} \ + --heap=${{ inputs.heap }} \ + --dlopen=${{ inputs.dlopen }} \ + --no-color \ + --verbose \ + --command="${{ inputs.command }}" \ + --scone-signer=/sig/enclave-key.pem + + - name: Push Prod Image + if: ${{ inputs.sconify-prod }} + id: push-prod + run: | + docker push $PROD_IMAGE + echo "image=$PROD_IMAGE" >> "$GITHUB_OUTPUT" + echo "checksum=$(docker image inspect $PROD_IMAGE | jq .[0].RepoDigests[0] | sed 's/"//g' | awk -F '@sha256:' '{print $2}')" >> "$GITHUB_OUTPUT" + echo "mrenclave=$(docker run --rm -e SCONE_HASH=1 $PROD_IMAGE)" >> "$GITHUB_OUTPUT" diff --git a/sconify/README.md b/sconify/README.md new file mode 100644 index 0000000..60bea01 --- /dev/null +++ b/sconify/README.md @@ -0,0 +1,140 @@ +# Sconify - Reusable Workflow Documentation 🚀 + +## Overview 🌟 + +This reusable GitHub Actions workflow automates the process of sconifying a Docker image. It is configurable via inputs for the Sconification options and secrets for docker registries credentials and production enclave signing key. + +The workflow performs the following actions: + +- **Login to Docker Registry** +- **Login to Scontain Docker Registry** +- **Pull Image to Sconify** from Docker Registry +- **Pull Sconify Image** from Scontain Docker Registry +- [unless input `sconify-debug: false`] + - **Sconify Image Debug** + - **Push Debug Image** to Docker Registry and prepare outputs (`debug-image`,`debug-mrenclave`,`debug-checksum`) +- [unless input `sconify-prod: false`] + - **Sconify Image Prod** + - **Push Prod Image** to Docker Registry and prepare outputs (`prod-image`,`prod-mrenclave`,`prod-checksum`) + +## Workflow Inputs đŸ› ī¸ + +| **Input** | **Description** | **Required** | **Default** | +| --------------------- | ------------------------------------------ | ------------ | ----------- | +| **docker-username** | Docker Registry Username | Yes | - | +| **scontain-username** | Scontain Registry Username | Yes | - | +| **image-name** | Name of Docker Image to Sconify | Yes | - | +| **image-tag** | Tag of Docker Image to Sconify | Yes | - | +| **docker-registry** | Docker Registry of Docker Image to Sconify | No | docker.io | +| **sconify-version** | Version of the Sconify Image to use | Yes | - | +| **fs-dir** | File System Directory to Protect | Yes | - | +| **binary** | Path to the Binary to Protect | Yes | - | +| **command** | Command to Protect | Yes | - | +| **heap** | Enclave Heap size | No | 1G | +| **dlopen** | dlopen mode | No | 1 | +| **sconify-debug** | Create Scone Debug image | No | true | +| **sconify-prod** | Create Scone Production image | No | true | + +### Secrets 🔐 + +| **Secret** | **Description** | **Required** | +| --------------------- | ----------------------------------------------- | --------------------------------------- | +| **docker-password** | Docker Registry Password or Token | Yes | +| **scontain-password** | Scontain Registry Password or Token | Yes | +| **scone-signing-key** | Signing Key for Scone Production (PEM RSA-3072) | Yes unless `inputs.sconify-prod: false` | + +### Outputs 📤 + +| **Output** | **Description** | +| ------------------- | ---------------------------------------------------------------------------------- | +| **debug-image** | Debug Sconified Image (unless `inputs.sconify-debug: false`) | +| **debug-mrenclave** | Debug Sconified Image MrEnclave Fingerprint (unless `inputs.sconify-debug: false`) | +| **debug-checksum** | Debug Sconified Image Checksum (unless `inputs.sconify-debug: false`) | +| **prod-image** | Prod Sconified Image (unless `inputs.sconify-prod: false`) | +| **prod-mrenclave** | Prod Sconified Image MrEnclave Fingerprint (unless `inputs.sconify-prod: false`) | +| **prod-checksum** | Prod Sconified Image Checksum (unless `inputs.sconify-prod: false`) | + +## How to Use This Reusable Workflow 🔄 + +1. **Save the Workflow File** + This workflow is already saved as `.github/workflows/sconify.yml` in the repository. 💾 + +2. **Call the Reusable Workflow** + In another workflow file (e.g., triggered manually or by a release), invoke this reusable workflow like so: + +```yaml +name: Sconify iApp + +on: + workflow_dispatch: + inputs: + image-name: + required: true + type: string + image-tag: + required: true + type: string + sconify-debug: + type: boolean + default: true + sconify-prod: + type: boolean + default: true + +jobs: + sconify: + uses: iExecBlockchainComputing/github-actions-workflows/.github/workflows/sconify.yml@feat/sconify + with: + image-name: ${{ inputs.image-name }} + image-tag: ${{ inputs.image-tag }} + sconify-debug: ${{ inputs.sconify-debug }} + sconify-prod: ${{ inputs.sconify-prod }} + docker-registry: docker.io + sconify-version: 5.9.0-v15 + fs-dir: /app + binary: /usr/local/bin/node + command: node /app/src/app.js + heap: 1G + dlopen: 1 + docker-username: ${{ vars.DOCKER_USERNAME }} + scontain-username: ${{ vars.SCONTAIN_USERNAME }} + secrets: + docker-password: ${{ secrets.DOCKER_TOKEN }} + scontain-password: ${{ secrets.SCONTAIN_TOKEN }} + scone-signing-key: ${{ secrets.SCONE_SIGNING_KEY }} + + use-sconify-output: + # usually you want to deploy the sconified image as an iExec app using the sconify job outputs + runs-on: ubuntu-latest + needs: sconify + steps: + - run: | + echo "DEBUG IMAGE INFO: image=${{ needs.sconify.outputs.debug-image }} | checksum=${{ needs.sconify.outputs.debug-checksum }} | mrenclave=${{ needs.sconify.outputs.debug-mrenclave }}" + echo "PROD IMAGE INFO: image=${{ needs.sconify.outputs.prod-image }} | checksum=${{ needs.sconify.outputs.prod-checksum }} | mrenclave=${{ needs.sconify.outputs.prod-mrenclave }}" +``` + +3. **Configure Variables** + Ensure that the following variables are added to your repository's settings: + + - `DOCKER_USERNAME`: Your Docker Registry username + - `SCONTAIN_USERNAME`: Your Scontain username + + NB: Beware if you choose to use secrets to store registries usernames; + registries usernames can appear in sconified image names outputted as `outputs.debug-image` and `outputs.prod-image`, in such a case GitHub Actions blanks the outputs with this waring: + + > Skip output 'prod-image' since it may contain secret. + + > Skip output 'debug-image' since it may contain secret. + +4. **Configure Secrets** + Ensure that the following secrets are added to your repository's settings: + - `DOCKER_PASSWORD`: Your Docker Registry password or access token + - `SCONTAIN_PASSWORD`: Your Scontain password or access token + - `SCONE_SIGNING_KEY`: The key to use for signing Scone Prod applications + +## Prerequisites 📋 + +1. **Read/Write access to the image to sconify** + +2. **Read access to Scontain's `iexec-sconify-image` image**: + - You must have a Scontain account with access to the `scone-production/iexec-sconify-image` image. From 423b627cebe231ecae016540451ac507d8d069d3 Mon Sep 17 00:00:00 2001 From: Pierre Jeanjacquot <26487010+PierreJeanjacquot@users.noreply.github.com> Date: Tue, 24 Jun 2025 15:12:49 +0200 Subject: [PATCH 2/9] fix: app checksum expect leading 0x --- .github/workflows/sconify.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/sconify.yml b/.github/workflows/sconify.yml index cbb1e58..df77527 100644 --- a/.github/workflows/sconify.yml +++ b/.github/workflows/sconify.yml @@ -147,7 +147,7 @@ jobs: run: | docker push $DEBUG_IMAGE echo "image=$DEBUG_IMAGE" >> "$GITHUB_OUTPUT" - echo "checksum=$(docker image inspect $DEBUG_IMAGE | jq .[0].RepoDigests[0] | sed 's/"//g' | awk -F '@sha256:' '{print $2}')" >> "$GITHUB_OUTPUT" + echo "checksum=0x$(docker image inspect $DEBUG_IMAGE | jq .[0].RepoDigests[0] | sed 's/"//g' | awk -F '@sha256:' '{print $2}')" >> "$GITHUB_OUTPUT" echo "mrenclave=$(docker run --rm -e SCONE_HASH=1 $DEBUG_IMAGE)" >> "$GITHUB_OUTPUT" - name: Sconify Image Prod @@ -181,5 +181,5 @@ jobs: run: | docker push $PROD_IMAGE echo "image=$PROD_IMAGE" >> "$GITHUB_OUTPUT" - echo "checksum=$(docker image inspect $PROD_IMAGE | jq .[0].RepoDigests[0] | sed 's/"//g' | awk -F '@sha256:' '{print $2}')" >> "$GITHUB_OUTPUT" + echo "checksum=0x$(docker image inspect $PROD_IMAGE | jq .[0].RepoDigests[0] | sed 's/"//g' | awk -F '@sha256:' '{print $2}')" >> "$GITHUB_OUTPUT" echo "mrenclave=$(docker run --rm -e SCONE_HASH=1 $PROD_IMAGE)" >> "$GITHUB_OUTPUT" From 7808c6f5d11c92e8e63cb2309a53b045f406f2d2 Mon Sep 17 00:00:00 2001 From: Pierre Jeanjacquot <26487010+PierreJeanjacquot@users.noreply.github.com> Date: Tue, 24 Jun 2025 15:29:39 +0200 Subject: [PATCH 3/9] docs: update workflow tag --- sconify/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sconify/README.md b/sconify/README.md index 60bea01..efc42b3 100644 --- a/sconify/README.md +++ b/sconify/README.md @@ -83,7 +83,7 @@ on: jobs: sconify: - uses: iExecBlockchainComputing/github-actions-workflows/.github/workflows/sconify.yml@feat/sconify + uses: iExecBlockchainComputing/github-actions-workflows/.github/workflows/sconify.yml@sconify-v1.0.0 with: image-name: ${{ inputs.image-name }} image-tag: ${{ inputs.image-tag }} From 330fd0131b633ce4e921ede10fce348add17b28a Mon Sep 17 00:00:00 2001 From: Pierre Jeanjacquot <26487010+PierreJeanjacquot@users.noreply.github.com> Date: Wed, 25 Jun 2025 10:51:33 +0200 Subject: [PATCH 4/9] fix: clean enclave-key from workspace --- .github/workflows/sconify.yml | 13 ++++++++++--- sconify/README.md | 4 +++- 2 files changed, 13 insertions(+), 4 deletions(-) diff --git a/.github/workflows/sconify.yml b/.github/workflows/sconify.yml index df77527..6ddd471 100644 --- a/.github/workflows/sconify.yml +++ b/.github/workflows/sconify.yml @@ -100,6 +100,9 @@ jobs: prod-mrenclave: ${{ steps.push-prod.outputs.mrenclave }} prod-checksum: ${{ steps.push-prod.outputs.checksum }} steps: + - name: Create Temporary Directory + run: mkdir -p ${{github.workspace}}/tmp + - name: Login to Docker Registry uses: docker/login-action@v3 with: @@ -153,12 +156,12 @@ jobs: - name: Sconify Image Prod if: ${{ inputs.sconify-prod }} run: | - mkdir -p $HOME/sig - echo "${{ secrets.scone-signing-key }}" > $HOME/sig/enclave-key.pem + mkdir -p ${{github.workspace}}/tmp/sig + echo "${{ secrets.scone-signing-key }}" > ${{github.workspace}}/tmp/sig/enclave-key.pem docker run \ --rm \ -v /var/run/docker.sock:/var/run/docker.sock \ - -v $HOME/sig/enclave-key.pem:/sig/enclave-key.pem \ + -v ${{github.workspace}}/tmp/sig/enclave-key.pem:/sig/enclave-key.pem \ registry.scontain.com/scone-production/iexec-sconify-image:${{ inputs.sconify-version }} \ sconify_iexec \ --from=$FROM_IMAGE \ @@ -183,3 +186,7 @@ jobs: echo "image=$PROD_IMAGE" >> "$GITHUB_OUTPUT" echo "checksum=0x$(docker image inspect $PROD_IMAGE | jq .[0].RepoDigests[0] | sed 's/"//g' | awk -F '@sha256:' '{print $2}')" >> "$GITHUB_OUTPUT" echo "mrenclave=$(docker run --rm -e SCONE_HASH=1 $PROD_IMAGE)" >> "$GITHUB_OUTPUT" + + - name: Clean Temporary Directory + if: always() + run: rm -rf ${{github.workspace}}/tmp diff --git a/sconify/README.md b/sconify/README.md index efc42b3..33801fa 100644 --- a/sconify/README.md +++ b/sconify/README.md @@ -6,6 +6,7 @@ This reusable GitHub Actions workflow automates the process of sconifying a Dock The workflow performs the following actions: +- **Create Temporary Directory** - **Login to Docker Registry** - **Login to Scontain Docker Registry** - **Pull Image to Sconify** from Docker Registry @@ -14,8 +15,9 @@ The workflow performs the following actions: - **Sconify Image Debug** - **Push Debug Image** to Docker Registry and prepare outputs (`debug-image`,`debug-mrenclave`,`debug-checksum`) - [unless input `sconify-prod: false`] - - **Sconify Image Prod** + - **Sconify Image Prod** using scone-signing-key stored in the Temporary Directory - **Push Prod Image** to Docker Registry and prepare outputs (`prod-image`,`prod-mrenclave`,`prod-checksum`) +- **Clean Temporary Directory** always ## Workflow Inputs đŸ› ī¸ From c3fc392635fc443f6cc55c3638d61ec8fb77b270 Mon Sep 17 00:00:00 2001 From: Pierre Jeanjacquot <26487010+PierreJeanjacquot@users.noreply.github.com> Date: Wed, 25 Jun 2025 11:24:42 +0200 Subject: [PATCH 5/9] feat: allow custom runner --- .github/workflows/sconify.yml | 6 +++++- sconify/README.md | 31 ++++++++++++++++--------------- 2 files changed, 21 insertions(+), 16 deletions(-) diff --git a/.github/workflows/sconify.yml b/.github/workflows/sconify.yml index 6ddd471..f836553 100644 --- a/.github/workflows/sconify.yml +++ b/.github/workflows/sconify.yml @@ -55,6 +55,10 @@ on: type: string description: "Scontain Registry Username" required: true + runner: + type: string + description: "Runner to use (overrides `runs-on`) âš ī¸ the specified runner must feature Ubuntu OS and docker CE" + default: "ubuntu-latest" secrets: docker-password: description: "Docker Registry Password or Token" @@ -87,7 +91,7 @@ on: jobs: build: - runs-on: ubuntu-latest + runs-on: ${{ inputs.runner }} env: FROM_IMAGE: ${{ inputs.docker-registry }}/${{ inputs.image-name }}:${{ inputs.image-tag }} DEBUG_IMAGE: ${{ inputs.docker-registry }}/${{ inputs.image-name }}:${{ inputs.image-tag }}-scone-debug-${{ inputs.sconify-version }} diff --git a/sconify/README.md b/sconify/README.md index 33801fa..f126883 100644 --- a/sconify/README.md +++ b/sconify/README.md @@ -21,21 +21,22 @@ The workflow performs the following actions: ## Workflow Inputs đŸ› ī¸ -| **Input** | **Description** | **Required** | **Default** | -| --------------------- | ------------------------------------------ | ------------ | ----------- | -| **docker-username** | Docker Registry Username | Yes | - | -| **scontain-username** | Scontain Registry Username | Yes | - | -| **image-name** | Name of Docker Image to Sconify | Yes | - | -| **image-tag** | Tag of Docker Image to Sconify | Yes | - | -| **docker-registry** | Docker Registry of Docker Image to Sconify | No | docker.io | -| **sconify-version** | Version of the Sconify Image to use | Yes | - | -| **fs-dir** | File System Directory to Protect | Yes | - | -| **binary** | Path to the Binary to Protect | Yes | - | -| **command** | Command to Protect | Yes | - | -| **heap** | Enclave Heap size | No | 1G | -| **dlopen** | dlopen mode | No | 1 | -| **sconify-debug** | Create Scone Debug image | No | true | -| **sconify-prod** | Create Scone Production image | No | true | +| **Input** | **Description** | **Required** | **Default** | +| --------------------- | ------------------------------------------------------------------------------------------------ | ------------ | ------------- | +| **docker-username** | Docker Registry Username | Yes | - | +| **scontain-username** | Scontain Registry Username | Yes | - | +| **image-name** | Name of Docker Image to Sconify | Yes | - | +| **image-tag** | Tag of Docker Image to Sconify | Yes | - | +| **docker-registry** | Docker Registry of Docker Image to Sconify | No | docker.io | +| **sconify-version** | Version of the Sconify Image to use | Yes | - | +| **fs-dir** | File System Directory to Protect | Yes | - | +| **binary** | Path to the Binary to Protect | Yes | - | +| **command** | Command to Protect | Yes | - | +| **heap** | Enclave Heap size | No | 1G | +| **dlopen** | dlopen mode | No | 1 | +| **sconify-debug** | Create Scone Debug image | No | true | +| **sconify-prod** | Create Scone Production image | No | true | +| **runner** | Runner to use (overrides `runs-on`) âš ī¸ the specified runner must feature Ubuntu OS and docker CE | No | ubuntu-latest | ### Secrets 🔐 From 6520eea6b051207c8a4a5abd14132232bdc1f58c Mon Sep 17 00:00:00 2001 From: Pierre Jeanjacquot <26487010+PierreJeanjacquot@users.noreply.github.com> Date: Wed, 25 Jun 2025 11:28:54 +0200 Subject: [PATCH 6/9] docs: add custom runner in example --- sconify/README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/sconify/README.md b/sconify/README.md index f126883..e5d1fb7 100644 --- a/sconify/README.md +++ b/sconify/README.md @@ -88,6 +88,7 @@ jobs: sconify: uses: iExecBlockchainComputing/github-actions-workflows/.github/workflows/sconify.yml@sconify-v1.0.0 with: + # runner: your-runner-here âš ī¸ control the runner used in the workflow to match your requirements image-name: ${{ inputs.image-name }} image-tag: ${{ inputs.image-tag }} sconify-debug: ${{ inputs.sconify-debug }} From f91690196c108ab305748851c673936f1967d673 Mon Sep 17 00:00:00 2001 From: Pierre Jeanjacquot <26487010+PierreJeanjacquot@users.noreply.github.com> Date: Wed, 25 Jun 2025 16:08:35 +0200 Subject: [PATCH 7/9] fix: get closer to Scone cli options --- .github/workflows/sconify.yml | 154 +++++++++++++++++++--------------- sconify/README.md | 45 ++++++---- 2 files changed, 115 insertions(+), 84 deletions(-) diff --git a/.github/workflows/sconify.yml b/.github/workflows/sconify.yml index f836553..9977e1a 100644 --- a/.github/workflows/sconify.yml +++ b/.github/workflows/sconify.yml @@ -3,61 +3,69 @@ name: Build, Test and Push Docker Image on: workflow_call: inputs: + docker-registry: + description: "Docker registry of docker image to sconify" + default: "docker.io" + type: string + docker-username: + description: "Docker registry username" + type: string + required: true image-name: - description: "Name of Docker Image to Sconify" + description: "Name of docker image to sconify" type: string required: true image-tag: - description: "Tag of Docker Image to Sconify" + description: "Tag of docker image to sconify " type: string required: true - docker-registry: - description: "Docker Registry of Docker Image to Sconify" - default: "docker.io" - type: string - sconify-version: - description: "Version of the Sconify Image to use" + scontain-username: + description: "Scontain registry username" type: string required: true - fs-dir: + sconify-version: + description: "Version of the sconify image to use" type: string - description: "File System Directory to Protect" required: true binary: + description: "Path of the binary to use" type: string - description: "Path to the Binary to Protect" required: true command: + description: "Command to execute (default: ENTRYPOINT + CMD of native image)" + type: string + binary-fs: + description: "Embed the file system into the binary via Scone binary file system (default: false)" + type: boolean + default: false + fs-dir: + description: "Path of directories to add to the binary file system (use multiline to add multiple directories)" + type: string + fs-file: + description: "Path of files to add to the binary file system (use multiline to add multiple files)" + type: string + host-path: + description: "Host path, served directly from the host file system (use multiline to add multiple path)" type: string - description: "Command to Protect" - required: true heap: + description: "Enclave heap size (default 1G)" type: string default: "1G" - description: "Enclave Heap size (default 1G)" dlopen: + description: "Scoen dlopen mode (default 1)" type: number default: 1 - description: "dlopen mode (default 1)" sconify-debug: - description: "Create Scone Debug image (default true)" - default: true + description: "Create Scone debug image (default true)" type: boolean - sconify-prod: - description: "Create Scone Production image (default true)" default: true + sconify-prod: + description: "Create Scone production image (default true)" type: boolean - docker-username: - type: string - description: "Docker Registry Username" - required: true - scontain-username: - type: string - description: "Scontain Registry Username" - required: true + default: true runner: - type: string description: "Runner to use (overrides `runs-on`) âš ī¸ the specified runner must feature Ubuntu OS and docker CE" + type: string default: "ubuntu-latest" secrets: docker-password: @@ -92,10 +100,6 @@ on: jobs: build: runs-on: ${{ inputs.runner }} - env: - FROM_IMAGE: ${{ inputs.docker-registry }}/${{ inputs.image-name }}:${{ inputs.image-tag }} - DEBUG_IMAGE: ${{ inputs.docker-registry }}/${{ inputs.image-name }}:${{ inputs.image-tag }}-scone-debug-${{ inputs.sconify-version }} - PROD_IMAGE: ${{ inputs.docker-registry }}/${{ inputs.image-name }}:${{ inputs.image-tag }}-scone-prod-${{ inputs.sconify-version }} outputs: debug-image: ${{ steps.push-debug.outputs.image }} debug-mrenclave: ${{ steps.push-debug.outputs.mrenclave }} @@ -107,6 +111,46 @@ jobs: - name: Create Temporary Directory run: mkdir -p ${{github.workspace}}/tmp + - name: Prepare Sconify Command + id: prepare-command + run: | + FROM_IMAGE=${{ inputs.docker-registry }}/${{ inputs.image-name }}:${{ inputs.image-tag }} + DEBUG_IMAGE=$FROM_IMAGE-scone-debug-${{ inputs.sconify-version }} + echo "debug-image=$DEBUG_IMAGE" + echo "debug-image=$DEBUG_IMAGE" >> "$GITHUB_OUTPUT" + PROD_IMAGE=$FROM_IMAGE-scone-prod-${{ inputs.sconify-version }} + echo "prod-image=$PROD_IMAGE" + echo "prod-image=$PROD_IMAGE" >> "$GITHUB_OUTPUT" + SCONIFY_CMD="sconify_iexec" + # REQUIRED: + # --from + SCONIFY_CMD+=" --from=$FROM_IMAGE" + # --to will be added later on + # --binary + SCONIFY_CMD+=" --binary=${{ inputs.binary }}" + # OPTIONAL: + # --command option + [[ -n '${{ inputs.command }}' ]] && SCONIFY_CMD+=" --command=${{ inputs.command }}" + # --host-path variadic option + while IFS= read -r line; do [[ -n "$line" ]] && SCONIFY_CMD+=" --host-path=$line" ; done <<< '${{ inputs.host-path }}' + # BINARY FILE SYSTEM (binary fs): + # --binary-fs option + if ${{ inputs.binary-fs }}; then SCONIFY_CMD+=" --binary-fs"; fi + # --fs-dir variadic option + while IFS= read -r line; do [[ -n "$line" ]] && SCONIFY_CMD+=" --fs-dir=$line" ; done <<< '${{ inputs.fs-dir }}' + # --fs-file variadic option + while IFS= read -r line; do [[ -n "$line" ]] && SCONIFY_CMD+=" --file=$line" ; done <<< '${{ inputs.fs-file }}' + # SCONE ENV VARS: + # --heap option + [[ -n '${{ inputs.heap }}' ]] && SCONIFY_CMD+=" --heap=${{ inputs.heap }}" + # --dlopen option + [[ -n '${{ inputs.dlopen }}' ]] && SCONIFY_CMD+=" --dlopen=${{ inputs.dlopen }}" + # DEBUG + # --verbose --no-color options + SCONIFY_CMD+=" --verbose --no-color" + echo "sconify-base-command=$SCONIFY_CMD" + echo "sconify-base-command=$SCONIFY_CMD" >> "$GITHUB_OUTPUT" + - name: Login to Docker Registry uses: docker/login-action@v3 with: @@ -134,28 +178,17 @@ jobs: --rm \ -v /var/run/docker.sock:/var/run/docker.sock \ registry.scontain.com/scone-production/iexec-sconify-image:${{ inputs.sconify-version }} \ - sconify_iexec \ - --from=$FROM_IMAGE \ - --to=$DEBUG_IMAGE \ - --binary-fs \ - --fs-dir=${{ inputs.fs-dir }} \ - --host-path=/etc/hosts \ - --host-path=/etc/resolv.conf \ - --binary=${{ inputs.binary }} \ - --heap=${{ inputs.heap }} \ - --dlopen=${{ inputs.dlopen }} \ - --no-color \ - --verbose \ - --command="${{ inputs.command }}" + ${{ steps.prepare-command.outputs.sconify-base-command }} \ + --to=${{ steps.prepare-command.outputs.debug-image }} - name: Push Debug Image if: ${{ inputs.sconify-debug }} id: push-debug run: | - docker push $DEBUG_IMAGE - echo "image=$DEBUG_IMAGE" >> "$GITHUB_OUTPUT" - echo "checksum=0x$(docker image inspect $DEBUG_IMAGE | jq .[0].RepoDigests[0] | sed 's/"//g' | awk -F '@sha256:' '{print $2}')" >> "$GITHUB_OUTPUT" - echo "mrenclave=$(docker run --rm -e SCONE_HASH=1 $DEBUG_IMAGE)" >> "$GITHUB_OUTPUT" + docker push ${{ steps.prepare-command.outputs.debug-image }} + echo "image=${{ steps.prepare-command.outputs.debug-image }}" >> "$GITHUB_OUTPUT" + echo "checksum=0x$(docker image inspect ${{ steps.prepare-command.outputs.debug-image }} | jq .[0].RepoDigests[0] | sed 's/"//g' | awk -F '@sha256:' '{print $2}')" >> "$GITHUB_OUTPUT" + echo "mrenclave=$(docker run --rm -e SCONE_HASH=1 ${{ steps.prepare-command.outputs.debug-image }})" >> "$GITHUB_OUTPUT" - name: Sconify Image Prod if: ${{ inputs.sconify-prod }} @@ -167,29 +200,18 @@ jobs: -v /var/run/docker.sock:/var/run/docker.sock \ -v ${{github.workspace}}/tmp/sig/enclave-key.pem:/sig/enclave-key.pem \ registry.scontain.com/scone-production/iexec-sconify-image:${{ inputs.sconify-version }} \ - sconify_iexec \ - --from=$FROM_IMAGE \ - --to=$PROD_IMAGE \ - --binary-fs \ - --fs-dir=${{ inputs.fs-dir }} \ - --host-path=/etc/hosts \ - --host-path=/etc/resolv.conf \ - --binary=${{ inputs.binary }} \ - --heap=${{ inputs.heap }} \ - --dlopen=${{ inputs.dlopen }} \ - --no-color \ - --verbose \ - --command="${{ inputs.command }}" \ + ${{ steps.prepare-command.outputs.sconify-base-command }} \ + --to=${{ steps.prepare-command.outputs.prod-image }} \ --scone-signer=/sig/enclave-key.pem - name: Push Prod Image if: ${{ inputs.sconify-prod }} id: push-prod run: | - docker push $PROD_IMAGE - echo "image=$PROD_IMAGE" >> "$GITHUB_OUTPUT" - echo "checksum=0x$(docker image inspect $PROD_IMAGE | jq .[0].RepoDigests[0] | sed 's/"//g' | awk -F '@sha256:' '{print $2}')" >> "$GITHUB_OUTPUT" - echo "mrenclave=$(docker run --rm -e SCONE_HASH=1 $PROD_IMAGE)" >> "$GITHUB_OUTPUT" + docker push ${{ steps.prepare-command.outputs.prod-image }} + echo "image=${{ steps.prepare-command.outputs.prod-image }}" >> "$GITHUB_OUTPUT" + echo "checksum=0x$(docker image inspect ${{ steps.prepare-command.outputs.prod-image }} | jq .[0].RepoDigests[0] | sed 's/"//g' | awk -F '@sha256:' '{print $2}')" >> "$GITHUB_OUTPUT" + echo "mrenclave=$(docker run --rm -e SCONE_HASH=1 ${{ steps.prepare-command.outputs.prod-image }})" >> "$GITHUB_OUTPUT" - name: Clean Temporary Directory if: always() diff --git a/sconify/README.md b/sconify/README.md index e5d1fb7..ec2afff 100644 --- a/sconify/README.md +++ b/sconify/README.md @@ -21,22 +21,27 @@ The workflow performs the following actions: ## Workflow Inputs đŸ› ī¸ -| **Input** | **Description** | **Required** | **Default** | -| --------------------- | ------------------------------------------------------------------------------------------------ | ------------ | ------------- | -| **docker-username** | Docker Registry Username | Yes | - | -| **scontain-username** | Scontain Registry Username | Yes | - | -| **image-name** | Name of Docker Image to Sconify | Yes | - | -| **image-tag** | Tag of Docker Image to Sconify | Yes | - | -| **docker-registry** | Docker Registry of Docker Image to Sconify | No | docker.io | -| **sconify-version** | Version of the Sconify Image to use | Yes | - | -| **fs-dir** | File System Directory to Protect | Yes | - | -| **binary** | Path to the Binary to Protect | Yes | - | -| **command** | Command to Protect | Yes | - | -| **heap** | Enclave Heap size | No | 1G | -| **dlopen** | dlopen mode | No | 1 | -| **sconify-debug** | Create Scone Debug image | No | true | -| **sconify-prod** | Create Scone Production image | No | true | -| **runner** | Runner to use (overrides `runs-on`) âš ī¸ the specified runner must feature Ubuntu OS and docker CE | No | ubuntu-latest | +| **Input** | **Description** | **Required** | **Default** | +| --------------------- | -------------------------------------------------------------------------------------------------------- | ------------ | -------------------------------- | +| **docker-registry** | Docker registry of docker image to sconify | No | docker.io | +| **docker-username** | Docker registry username | Yes | - | +| **image-name** | Name of docker image to sconify | Yes | - | +| **image-tag** | Tag of docker image to sconify | Yes | - | +| **scontain-username** | Scontain registry username | Yes | - | +| **sconify-version** | Version of the sconify image to use | Yes | - | +| **binary** | [SCONE] Path of the binary to use | Yes | - | +| **command** | [SCONE] Command to execute | No | ENTRYPOINT + CMD of native image | +| **binary-fs** | [SCONE] Embed the file system into the binary via Scone binary file system | No | false | +| **fs-dir** | [SCONE] Path of directories to add to the binary file system (use multiline to add multiple directories) | No | - | +| **fs-file** | [SCONE] Path of files to add to the binary file system (use multiline to add multiple files) | No | - | +| **host-path** | [SCONE] Host path, served directly from the host file system (use multiline to add multiple path) | No | - | +| **heap** | [SCONE] Enclave heap size | No | 1G | +| **dlopen** | [SCONE] Scone dlopen mode (0:disable; 1:enable and require authentication; 2:debug only) | No | 1 | +| **sconify-debug** | Create Scone debug image | No | true | +| **sconify-prod** | Create Scone production image | No | true | +| **runner** | Runner to use (overrides `runs-on`) âš ī¸ the specified runner must feature Ubuntu OS and docker CE | No | ubuntu-latest | + +> â„šī¸ for more details about [SCONE] options see [Scone's documentation](https://sconedocs.github.io/ee_sconify_image/#all-supported-options) ### Secrets 🔐 @@ -86,7 +91,7 @@ on: jobs: sconify: - uses: iExecBlockchainComputing/github-actions-workflows/.github/workflows/sconify.yml@sconify-v1.0.0 + uses: iExecBlockchainComputing/github-actions-workflows/.github/workflows/sconify.yml@feat/sconify with: # runner: your-runner-here âš ī¸ control the runner used in the workflow to match your requirements image-name: ${{ inputs.image-name }} @@ -95,9 +100,13 @@ jobs: sconify-prod: ${{ inputs.sconify-prod }} docker-registry: docker.io sconify-version: 5.9.0-v15 - fs-dir: /app binary: /usr/local/bin/node command: node /app/src/app.js + host-path: | + /etc/hosts + /etc/resolv.conf + binary-fs: true + fs-dir: /app heap: 1G dlopen: 1 docker-username: ${{ vars.DOCKER_USERNAME }} From d0bdc82e5ed0d79225a2c6a7e563abb6d2e78b47 Mon Sep 17 00:00:00 2001 From: Pierre Jeanjacquot <26487010+PierreJeanjacquot@users.noreply.github.com> Date: Wed, 25 Jun 2025 16:19:43 +0200 Subject: [PATCH 8/9] fix: fix dlopen default and add mprotect --- .github/workflows/sconify.yml | 12 +++++++++--- sconify/README.md | 11 +++++++---- 2 files changed, 16 insertions(+), 7 deletions(-) diff --git a/.github/workflows/sconify.yml b/.github/workflows/sconify.yml index 9977e1a..22245b0 100644 --- a/.github/workflows/sconify.yml +++ b/.github/workflows/sconify.yml @@ -16,7 +16,7 @@ on: type: string required: true image-tag: - description: "Tag of docker image to sconify " + description: "Tag of docker image to sconify" type: string required: true scontain-username: @@ -51,10 +51,14 @@ on: description: "Enclave heap size (default 1G)" type: string default: "1G" + mprotect: + description: "Scone mprotect mode (0:disable; 1:enable; default 0)" + type: number + default: 0 dlopen: - description: "Scoen dlopen mode (default 1)" + description: "Scone dlopen mode (0:disable; 1:enable; default 0)" type: number - default: 1 + default: 0 sconify-debug: description: "Create Scone debug image (default true)" type: boolean @@ -145,6 +149,8 @@ jobs: [[ -n '${{ inputs.heap }}' ]] && SCONIFY_CMD+=" --heap=${{ inputs.heap }}" # --dlopen option [[ -n '${{ inputs.dlopen }}' ]] && SCONIFY_CMD+=" --dlopen=${{ inputs.dlopen }}" + # --mprotect option + [[ -n '${{ inputs.mprotect }}' ]] && SCONIFY_CMD+=" --mprotect=${{ inputs.mprotect }}" # DEBUG # --verbose --no-color options SCONIFY_CMD+=" --verbose --no-color" diff --git a/sconify/README.md b/sconify/README.md index ec2afff..917481b 100644 --- a/sconify/README.md +++ b/sconify/README.md @@ -36,10 +36,12 @@ The workflow performs the following actions: | **fs-file** | [SCONE] Path of files to add to the binary file system (use multiline to add multiple files) | No | - | | **host-path** | [SCONE] Host path, served directly from the host file system (use multiline to add multiple path) | No | - | | **heap** | [SCONE] Enclave heap size | No | 1G | -| **dlopen** | [SCONE] Scone dlopen mode (0:disable; 1:enable and require authentication; 2:debug only) | No | 1 | -| **sconify-debug** | Create Scone debug image | No | true | -| **sconify-prod** | Create Scone production image | No | true | -| **runner** | Runner to use (overrides `runs-on`) âš ī¸ the specified runner must feature Ubuntu OS and docker CE | No | ubuntu-latest | +| **dlopen** | [SCONE] Scone dlopen mode (0:disable; 1:enable) | No | 0 | +| **mprotect** | [SCONE] Scone mprotect mode (0:disable; 1:enable) | No | 0 | + +| **sconify-debug** | Create Scone debug image | No | true | +| **sconify-prod** | Create Scone production image | No | true | +| **runner** | Runner to use (overrides `runs-on`) âš ī¸ the specified runner must feature Ubuntu OS and docker CE | No | ubuntu-latest | > â„šī¸ for more details about [SCONE] options see [Scone's documentation](https://sconedocs.github.io/ee_sconify_image/#all-supported-options) @@ -109,6 +111,7 @@ jobs: fs-dir: /app heap: 1G dlopen: 1 + mprotect: 1 docker-username: ${{ vars.DOCKER_USERNAME }} scontain-username: ${{ vars.SCONTAIN_USERNAME }} secrets: From 8560766537e5da93f9dab92b3d70411095d5751e Mon Sep 17 00:00:00 2001 From: Pierre Jeanjacquot <26487010+PierreJeanjacquot@users.noreply.github.com> Date: Wed, 25 Jun 2025 16:36:01 +0200 Subject: [PATCH 9/9] docs: update readme --- sconify/README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/sconify/README.md b/sconify/README.md index 917481b..be5324b 100644 --- a/sconify/README.md +++ b/sconify/README.md @@ -7,6 +7,7 @@ This reusable GitHub Actions workflow automates the process of sconifying a Dock The workflow performs the following actions: - **Create Temporary Directory** +- **Prepare Sconify Command** and args - **Login to Docker Registry** - **Login to Scontain Docker Registry** - **Pull Image to Sconify** from Docker Registry