-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
0 parents
commit 09b438e
Showing
9 changed files
with
851 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,65 @@ | ||
name: Cosmian Enclave base container image | ||
|
||
on: | ||
# Only run when pull request is closed and merged into main/develop | ||
pull_request: | ||
branches: | ||
- main | ||
types: | ||
- closed | ||
# Do not run on push | ||
push: | ||
branches-ignore: | ||
- "**" | ||
tags-ignore: | ||
- "**" | ||
|
||
env: | ||
REGISTRY: ghcr.io | ||
|
||
jobs: | ||
build: | ||
name: Build | ||
runs-on: ubuntu-22.04 | ||
permissions: | ||
packages: write | ||
contents: read | ||
env: | ||
IMAGE: ghcr.io/cosmian/cenclave-base | ||
|
||
steps: | ||
- name: Build date | ||
id: build_date | ||
run: | | ||
echo "BUILD_DATE=$(date -u +'%Y%m%d%H%M%S')" >> $GITHUB_OUTPUT | ||
- name: Checkout | ||
uses: actions/checkout@v3 | ||
|
||
- name: Login to GitHub Packages | ||
uses: docker/login-action@v2 | ||
with: | ||
registry: ${{ env.REGISTRY }} | ||
username: ${{ github.actor }} | ||
password: ${{ secrets.GITHUB_TOKEN }} | ||
|
||
- name: Docker metadata | ||
id: meta | ||
uses: docker/metadata-action@v4 | ||
with: | ||
images: ${{ env.IMAGE }} | ||
tags: | | ||
type=ref,event=branch | ||
type=ref,event=pr | ||
type=semver,pattern={{version}} | ||
type=semver,pattern={{major}}.{{minor}} | ||
- name: Build and push | ||
uses: docker/build-push-action@v3 | ||
with: | ||
context: . | ||
push: ${{ contains(github.ref, 'main') }} | ||
tags: | | ||
${{ env.IMAGE }}:${{ github.sha }} | ||
${{ env.IMAGE }}:${{ steps.build_date.outputs.BUILD_DATE }} | ||
labels: ${{ steps.meta.outputs.labels }} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,56 @@ | ||
name: Cosmian Enclave base container image BETA | ||
|
||
on: | ||
push: | ||
# Run on every branches which will be merged | ||
branches-ignore: | ||
- master | ||
- main | ||
- release | ||
- develop | ||
tags-ignore: | ||
- "**" | ||
|
||
env: | ||
REGISTRY: ghcr.io | ||
|
||
jobs: | ||
build: | ||
name: Build | ||
runs-on: ubuntu-22.04 | ||
permissions: | ||
packages: write | ||
contents: read | ||
env: | ||
IMAGE: ghcr.io/cosmian/cenclave-base-beta | ||
|
||
steps: | ||
- name: Checkout | ||
uses: actions/checkout@v3 | ||
|
||
- name: Login to GitHub Packages | ||
uses: docker/login-action@v2 | ||
with: | ||
registry: ${{ env.REGISTRY }} | ||
username: ${{ github.actor }} | ||
password: ${{ secrets.GITHUB_TOKEN }} | ||
|
||
- name: Docker metadata | ||
id: meta | ||
uses: docker/metadata-action@v4 | ||
with: | ||
images: ${{ env.IMAGE }} | ||
tags: | | ||
type=ref,event=branch | ||
type=ref,event=pr | ||
type=semver,pattern={{version}} | ||
type=semver,pattern={{major}}.{{minor}} | ||
- name: Build and push | ||
uses: docker/build-push-action@v3 | ||
with: | ||
context: . | ||
push: true | ||
tags: | | ||
${{ env.IMAGE }}:${{ github.sha }} | ||
labels: ${{ steps.meta.outputs.labels }} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,68 @@ | ||
FROM ubuntu:22.04 | ||
|
||
USER root | ||
ENV DEBIAN_FRONTEND=noninteractive | ||
ENV TS=Etc/UTC | ||
ENV LANG=C.UTF-8 | ||
ENV LC_ALL=C.UTF-8 | ||
ENV PYTHONDONTWRITEBYTECODE=1 | ||
ENV PYTHONPYCACHEPREFIX=/tmp | ||
ENV PYTHONUNBUFFERED=1 | ||
|
||
RUN echo 'APT::Install-Suggests "0";' >> /etc/apt/apt.conf.d/00-docker | ||
RUN echo 'APT::Install-Recommends "0";' >> /etc/apt/apt.conf.d/00-docker | ||
RUN apt-get update && apt-get install -y \ | ||
git \ | ||
build-essential \ | ||
pkg-config \ | ||
curl \ | ||
python3 \ | ||
python3-pip \ | ||
python3-venv \ | ||
gnupg \ | ||
ca-certificates \ | ||
curl \ | ||
tzdata \ | ||
wget && \ | ||
rm -rf /var/lib/apt/lists/* | ||
|
||
# Gramine APT repository | ||
RUN curl -fsSLo /usr/share/keyrings/gramine-keyring.gpg https://packages.gramineproject.io/gramine-keyring.gpg && \ | ||
echo "deb [arch=amd64 signed-by=/usr/share/keyrings/gramine-keyring.gpg] https://packages.gramineproject.io/ jammy main" \ | ||
| tee /etc/apt/sources.list.d/gramine.list | ||
|
||
# Intel SGX APT repository | ||
RUN curl -fsSLo /usr/share/keyrings/intel-sgx-deb.asc https://download.01.org/intel-sgx/sgx_repo/ubuntu/intel-sgx-deb.key && \ | ||
echo "deb [arch=amd64 signed-by=/usr/share/keyrings/intel-sgx-deb.asc] https://download.01.org/intel-sgx/sgx_repo/ubuntu jammy main" \ | ||
| tee /etc/apt/sources.list.d/intel-sgx.list | ||
|
||
# Install Intel SGX dependencies and Gramine | ||
RUN apt-get update && apt-get install -y \ | ||
libsgx-launch \ | ||
libsgx-urts \ | ||
libsgx-quote-ex \ | ||
libsgx-epid \ | ||
libsgx-dcap-ql \ | ||
libsgx-dcap-quote-verify \ | ||
linux-base-sgx \ | ||
libsgx-dcap-default-qpl \ | ||
libsgx-aesm-quote-ex-plugin \ | ||
gramine && \ | ||
rm -rf /var/lib/apt/lists/* | ||
|
||
# Configure virtualenv | ||
ENV GRAMINE_VENV=/opt/venv | ||
RUN python3 -m venv $GRAMINE_VENV | ||
|
||
# Install Cosmian Enclave SGX library | ||
RUN . "$GRAMINE_VENV/bin/activate" && \ | ||
python3 -m pip install -U pip setuptools && \ | ||
python3 -m pip install -U cenclave-lib-sgx==1.0.0a1 | ||
|
||
WORKDIR /root | ||
|
||
COPY Makefile . | ||
COPY python.manifest.template . | ||
COPY cenclave-run.sh /usr/local/bin/cenclave-run | ||
COPY cenclave-test.sh /usr/local/bin/cenclave-test | ||
COPY cenclave-memory.py /usr/local/bin/cenclave-memory |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,44 @@ | ||
ARCH_LIBDIR ?= /lib/$(shell $(CC) -dumpmachine) | ||
|
||
SGX_SIGNER_KEY ?= $(HOME)/.config/gramine/enclave-key.pem | ||
ifeq ($(DEBUG),1) | ||
GRAMINE_LOG_LEVEL = debug | ||
else | ||
GRAMINE_LOG_LEVEL = error | ||
endif | ||
|
||
.PHONY: all | ||
all: python.manifest | ||
ifeq ($(SGX),1) | ||
all: python.manifest.sgx python.sig | ||
endif | ||
|
||
%.manifest: %.manifest.template | ||
gramine-manifest \ | ||
-Dlog_level=$(GRAMINE_LOG_LEVEL) \ | ||
-Darch_libdir=$(ARCH_LIBDIR) \ | ||
-Denclave_size=$(ENCLAVE_SIZE) \ | ||
-Dapp_dir=$(APP_DIR) \ | ||
-Dhome_dir=$(HOME_DIR) \ | ||
-Dkey_dir=$(KEY_DIR) \ | ||
-Dcode_dir=$(CODE_DIR) \ | ||
-Dentrypoint=$(realpath $(shell sh -c "command -v python3")) \ | ||
$< > $@ | ||
|
||
# Make on Ubuntu <= 20.04 doesn't support "Rules with Grouped Targets" (`&:`), | ||
# we need to hack around. | ||
python.sig python.manifest.sgx: sgx_outputs | ||
@: | ||
|
||
.INTERMEDIATE: sgx_outputs | ||
sgx_outputs: python.manifest | ||
@test -s $(SGX_SIGNER_KEY) || \ | ||
{ echo "SGX signer private key was not found, please specify SGX_SIGNER_KEY!"; exit 1; } | ||
gramine-sgx-sign \ | ||
--key $(SGX_SIGNER_KEY) \ | ||
--output python.manifest.sgx \ | ||
--manifest python.manifest | ||
|
||
.PHONY: clean | ||
clean: | ||
$(RM) *.token *.sig *.manifest.sgx *.manifest |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,156 @@ | ||
# Cosmian Enclave Image Base | ||
|
||
## Overview | ||
|
||
Base image used for Python web application launched with [Cosmian Enclave](https://docs.cosmian.com/compute/cosmian_enclave/overview/). | ||
|
||
The image is built and released with GitHub Actions as below: | ||
|
||
```console | ||
$ export BUILD_DATE="$(date "+%Y%m%d%H%M%S")" | ||
$ docker build -t cenclave-base:$BUILD_DATE . | ||
``` | ||
|
||
It is recommended to use images released on [pkgs/cenclave-base](https://github.com/Cosmian/cenclave-image-base/pkgs/container/cenclave-base) as base layer. | ||
|
||
## Extend the image with your dependencies | ||
|
||
As an example, `cenclave-base` can be extended with [Flask](https://flask.palletsprojects.com/en/stable/): | ||
|
||
``` | ||
FROM ghcr.io/cosmian/cenclave-base:LAST_DATE_ON_GH_PACKAGES | ||
RUN pip3 install "flask==3.1.0" | ||
``` | ||
|
||
replace `LAST_DATE_ON_GH_PACKAGES` with the last one on [pkgs/cenclave-base](https://github.com/Cosmian/cenclave-image-base/pkgs/container/cenclave-base), then: | ||
|
||
```console | ||
$ docker build -t cenclave-flask:3.1.0 | ||
``` | ||
|
||
## Run with SGX | ||
|
||
First compress your Python flask application: | ||
|
||
```console | ||
$ tree src/ | ||
src | ||
└── app.py | ||
|
||
0 directories, 2 files | ||
$ cat src/app.py | ||
from flask import Flask | ||
|
||
app = Flask(__name__) | ||
|
||
@app.route('/') | ||
def hello(): | ||
return "Hello World!" | ||
$ tar -cvf /tmp/app.tar --directory=src app.py | ||
``` | ||
|
||
then generate a signer RSA key for the enclave: | ||
|
||
```console | ||
$ openssl genrsa -3 -out enclave-key.pem 3072 | ||
``` | ||
|
||
and finally run the Docker container with: | ||
|
||
- Enclave signer key mounted to `/root/.config/gramine/enclave-key.pem` | ||
- Tar of the python application mounted anywhere (`/tmp/app.tar` can be used) | ||
- `cenclave-run` binary as entrypoint | ||
- Enclave size in `--size` (could be `2G`, `4G`, `8G`) | ||
- Path of the tar file with the Python application in `--code` | ||
- Module path of your web application in `--application` (usually `app:app`) | ||
- Random UUID v4 in `--uuid` | ||
- Expiration date of the certificate as unix epoch time in `--self-signed` | ||
|
||
```console | ||
$ docker run -p 8080:443 \ | ||
--device /dev/sgx_enclave \ | ||
--device /dev/sgx_provision \ | ||
--device /dev/sgx/enclave \ | ||
--device /dev/sgx/provision \ | ||
-v /var/run/aesmd:/var/run/aesmd \ | ||
-v "$(realpath enclave-key.pem)":/root/.config/gramine/enclave-key.pem \ | ||
-v /tmp/app.tar:/tmp/app.tar \ | ||
--entrypoint cenclave-run \ | ||
cenclave-flask:3.1.0 --size 8G \ | ||
--code /tmp/app.tar \ | ||
--host localhost \ | ||
--application app:app \ | ||
--uuid 533a2b83-4bc5-4a9c-955e-208c530bfd15 \ | ||
--self-signed 1769155711 | ||
``` | ||
|
||
## Check your web application | ||
|
||
```console | ||
$ # get self-signed certificate with OpenSSL | ||
$ openssl s_client -showcerts -connect localhost:8080 </dev/null 2>/dev/null | openssl x509 -outform PEM >/tmp/cert.pem | ||
$ # force self-signed certificate as CA bundle | ||
$ curl https://localhost:8080 --cacert /tmp/cert.pem | ||
``` | ||
|
||
## Compute MRENCLAVE without SGX | ||
|
||
The integrity of the application running in `cenclave-flask` is reflected in the `MRENCLAVE` value which is a SHA-256 hash digest of code, data, heap, stack, and other attributes of an enclave. | ||
|
||
Use `--dry-run` parameter with the exact same other parameters as above to output `MRENCLAVE` value: | ||
|
||
```console | ||
$ docker run --rm \ | ||
-v /tmp/app.tar:/tmp/app.tar \ | ||
--entrypoint cenclave-run \ | ||
cenclave-flask:3.1.0 --size 8G \ | ||
--code /tmp/app.tar \ | ||
--host localhost \ | ||
--application app:app \ | ||
--uuid 533a2b83-4bc5-4a9c-955e-208c530bfd15 \ | ||
--self-signed 1769155711 \ | ||
--dry-run | ||
``` | ||
|
||
__Note__: `MRSIGNER` value should be ignored because it is randomly generated at each dry run. | ||
|
||
## Testing Docker environment | ||
|
||
If you want to test that your docker image contains all the dependencies needed, `cenclave-test` entrypoint wraps `flask run` command for you if you mount your code directory to `/app`: | ||
|
||
```console | ||
$ docker run --rm -ti \ | ||
--entrypoint cenclave-test \ | ||
--net host \ | ||
-v src:/app \ | ||
cenclave-flask:3.1.0 \ | ||
--application app:app \ | ||
--debug | ||
$ # default host and port of flask developement server | ||
$ curl http://127.0.0.1:5000 | ||
``` | ||
|
||
To use your `secrets.json`, just add `-v secrets.json:/root/.cache/cenclave/secrets.json` to mount the file. | ||
|
||
|
||
## Determine the enclave memory size of your image | ||
|
||
Some files contained in the image are mounted into the enclave: libs, etc. | ||
These files takes some memory spaces from the enclave size you have declared. The remaining space is the effective memory your app can use. | ||
|
||
You can compute the effective memory by adding `--memory` in the previous commands: | ||
|
||
```console | ||
$ docker run --rm \ | ||
-v /tmp/app.tar:/tmp/app.tar \ | ||
--entrypoint cenclave-run \ | ||
cenclave-flask:3.1.0 --size 8G \ | ||
--code /tmp/app.tar \ | ||
--host localhost \ | ||
--application app:app \ | ||
--uuid 533a2b83-4bc5-4a9c-955e-208c530bfd15 \ | ||
--self-signed 1769155711 \ | ||
--dry-run \ | ||
--memory | ||
``` |
Oops, something went wrong.