Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
134 changes: 134 additions & 0 deletions .github/workflows/build-enclave-eif.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,134 @@
# Builds the secure-enclave EIF and pushes the carrier image to GHCR.
# Pull requests build without publishing.
name: Build Enclave EIF Image

on:
pull_request:
paths:
- "secure-enclave/**"
- "shared/**"
- "Cargo.toml"
- "Cargo.lock"
- "rust-toolchain.toml"
- "scripts/build-eif.sh"
- ".github/workflows/build-enclave-eif.yml"
push:
branches:
- main
tags:
- "v*"
workflow_dispatch:
inputs:
version:
description: "Version tag to publish (including v prefix, e.g. v0.1.0)"
required: false
type: string

permissions:
contents: read

env:
NITRO_CLI_VERSION: v1.4.2

jobs:
build-enclave-eif:
name: Build enclave EIF + carrier image
runs-on: ubuntu-latest
permissions:
contents: read
id-token: write
packages: write
attestations: write
steps:
- name: Checkout code
uses: actions/checkout@11d5960a326750d5838078e36cf38b85af677262 # v4

- name: Install Rust toolchain
uses: dtolnay/rust-toolchain@4cda84d5c5c54efe2404f9d843567869ab1699d4 # stable

- name: Cache nitro-cli build
uses: actions/cache@0057852bfaa89a56745cba8c7296529d2fc39830 # v4
with:
path: target/eif/aws-nitro-enclaves-cli-${{ env.NITRO_CLI_VERSION }}
key: nitro-cli-${{ runner.os }}-${{ env.NITRO_CLI_VERSION }}

- name: Resolve version
id: version
if: github.ref_type == 'tag' || inputs.version != ''
env:
INPUT_VERSION: ${{ inputs.version }}
run: |
if [[ -n "$INPUT_VERSION" ]]; then
VERSION="$INPUT_VERSION"
else
VERSION="$GITHUB_REF_NAME"
fi
echo "version=$VERSION" >> "$GITHUB_OUTPUT"
if [[ "$VERSION" =~ ^v[0-9]+\.[0-9]+\.[0-9]+$ ]]; then
echo "is_stable=true" >> "$GITHUB_OUTPUT"
else
echo "is_stable=false" >> "$GITHUB_OUTPUT"
fi

- name: Prepare nitro-cli log directory
run: sudo install -d -m 1777 /var/log/nitro_enclaves

- name: Build EIF and PCRs
run: scripts/build-eif.sh target/eif

- name: Publish PCR measurements
run: |
{
echo '### Enclave PCR measurements'
echo '```json'
cat target/eif/pcrs.json
echo '```'
} >> "$GITHUB_STEP_SUMMARY"

- name: Upload PCR measurements
uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4
with:
name: enclave-pcrs
path: target/eif/pcrs.json
if-no-files-found: error

- name: Docker meta
id: meta
uses: docker/metadata-action@c299e40c65443455700f0fdfc63efafe5b349051 # v5
with:
images: ghcr.io/${{ github.repository }}-enclave-eif
tags: |
type=raw,value=latest,enable=${{ github.ref == 'refs/heads/main' || steps.version.outputs.is_stable == 'true' }}
type=sha
type=raw,value=${{ steps.version.outputs.version }},enable=${{ steps.version.outputs.version != '' }}

- name: Set up Docker Buildx
uses: docker/setup-buildx-action@8d2750c68a42422c14e847fe6c8ac0403b4cbd6f # v3

- name: Login to GitHub Container Registry
if: github.event_name != 'pull_request'
uses: docker/login-action@c94ce9fb468520275223c153574b00df6fe4bcc9 # v3
with:
registry: ghcr.io
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}

- name: Build and push carrier image
id: build
uses: docker/build-push-action@10e90e3645eae34f1e60eeb005ba3a3d33f178e8 # v6
with:
# Context is the EIF output dir so the .eif is always included.
context: target/eif
file: secure-enclave/Dockerfile.eif
push: ${{ github.event_name != 'pull_request' }}
tags: ${{ steps.meta.outputs.tags }}
labels: ${{ steps.meta.outputs.labels }}
platforms: linux/amd64

- name: Attest build provenance
if: github.event_name != 'pull_request'
uses: actions/attest-build-provenance@ef244123eb79f2f7a7e75d99086184180e6d0018 # v1
with:
push-to-registry: true
subject-name: ghcr.io/${{ github.repository }}-enclave-eif
subject-digest: ${{ steps.build.outputs.digest }}
54 changes: 54 additions & 0 deletions scripts/build-eif.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
#!/bin/bash
set -euo pipefail

# Build the secure-enclave EIF and emit its PCR measurements. Needs Linux
# x86_64 + Docker; Nitro hardware is only required to run the enclave, not
# build it.
#
# Usage: scripts/build-eif.sh [output-dir] (default: target/eif)
# Outputs: embedding-verifier-enclave.eif, pcrs.json
# Env: NITRO_CLI_VERSION (default v1.4.2), ENCLAVE_IMAGE_TAG

if [ "$(uname -s)" != "Linux" ] || [ "$(uname -m)" != "x86_64" ]; then
echo "[ERROR] EIF builds require Linux x86_64 (got $(uname -s)/$(uname -m))." >&2
exit 1
fi

NITRO_CLI_VERSION="${NITRO_CLI_VERSION:-v1.4.2}"
ENCLAVE_IMAGE_TAG="${ENCLAVE_IMAGE_TAG:-embedding-verifier-enclave:local}"

repo_root="$(git rev-parse --show-toplevel)"
cd "$repo_root"

out_dir="${1:-target/eif}"
mkdir -p "$out_dir"
out_dir="$(cd "$out_dir" && pwd)"

echo "[1/3] Building enclave container image ($ENCLAVE_IMAGE_TAG)..."
docker build -t "$ENCLAVE_IMAGE_TAG" -f secure-enclave/Dockerfile .

echo "[2/3] Building nitro-cli $NITRO_CLI_VERSION..."
nitro_cli_dir="$out_dir/aws-nitro-enclaves-cli-$NITRO_CLI_VERSION"
nitro_cli="$nitro_cli_dir/target/release/nitro-cli"
if [ ! -x "$nitro_cli" ]; then
rm -rf "$nitro_cli_dir"
git clone --depth 1 --branch "$NITRO_CLI_VERSION" \
https://github.com/aws/aws-nitro-enclaves-cli "$nitro_cli_dir"
cargo build --release --bin nitro-cli --manifest-path "$nitro_cli_dir/Cargo.toml"
fi

echo "[3/3] Converting to EIF..."
eif_path="$out_dir/embedding-verifier-enclave.eif"
build_json="$out_dir/build-enclave.json"
NITRO_CLI_BLOBS="$nitro_cli_dir/blobs/x86_64" \
NITRO_CLI_ARTIFACTS="$out_dir/artifacts" \
"$nitro_cli" build-enclave \
--docker-uri "$ENCLAVE_IMAGE_TAG" \
--output-file "$eif_path" | tee "$build_json"

jq '.Measurements' "$build_json" > "$out_dir/pcrs.json"

echo
echo "EIF: $eif_path"
echo "PCRs: $out_dir/pcrs.json"
jq . "$out_dir/pcrs.json"
32 changes: 32 additions & 0 deletions secure-enclave/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
# syntax=docker/dockerfile:1
# Enclave workload image, converted to an EIF by scripts/build-eif.sh.
#
# Base images are tag-pinned and the build is --locked. Before a PRODUCTION
# deploy, pin base images by digest + apt to a snapshot.debian.org timestamp so
# PCRs are reproducible, then register the real PCRs (dev runs --debug-mode,
# which zeroes PCRs and skips attestation).

FROM rust:1.97.0-bookworm AS builder

RUN apt-get update && apt-get install -y --no-install-recommends \
ca-certificates \
clang \
pkg-config \
&& rm -rf /var/lib/apt/lists/*

WORKDIR /src
COPY . .

RUN cargo build --release --locked --package secure-enclave --bin secure-enclave

FROM debian:bookworm-slim

RUN apt-get update && apt-get install -y --no-install-recommends \
ca-certificates \
&& rm -rf /var/lib/apt/lists/*

COPY --from=builder /src/target/release/secure-enclave /usr/local/bin/secure-enclave

ENV RUST_LOG=info

ENTRYPOINT ["/usr/local/bin/secure-enclave"]
Comment thread
kilianglas marked this conversation as resolved.
43 changes: 43 additions & 0 deletions secure-enclave/Dockerfile.eif
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
# syntax=docker/dockerfile:1
# Carrier image that launches the enclave EIF on Nitro-enabled nodes.
# Build context: target/eif/ (produced by scripts/build-eif.sh).

FROM public.ecr.aws/amazonlinux/amazonlinux:2023

RUN dnf install -y aws-nitro-enclaves-cli aws-nitro-enclaves-cli-devel jq && \
dnf clean all

COPY embedding-verifier-enclave.eif /home/embedding-verifier-enclave.eif

ENV EIF_PATH="/home/embedding-verifier-enclave.eif" \
ENCLAVE_CPU_COUNT=2 \
ENCLAVE_MEMORY_SIZE=1024 \
ENCLAVE_DEBUG_MODE=false

COPY <<'EOF' /home/run.sh
#!/bin/bash
set -euo pipefail

echo "[run.sh] Starting enclave: eif=${EIF_PATH} cpu=${ENCLAVE_CPU_COUNT} mem=${ENCLAVE_MEMORY_SIZE}MiB debug=${ENCLAVE_DEBUG_MODE}"

DEBUG_FLAG=""
if [[ "${ENCLAVE_DEBUG_MODE}" == "true" || "${ENCLAVE_DEBUG_MODE}" == "1" ]]; then
DEBUG_FLAG="--debug-mode"
fi

run_output=$(nitro-cli run-enclave \
--cpu-count "${ENCLAVE_CPU_COUNT}" \
--memory "${ENCLAVE_MEMORY_SIZE}" \
--eif-path "${EIF_PATH}" \
${DEBUG_FLAG})

enclave_id=$(echo "${run_output}" | jq -r '.EnclaveID')
echo "[run.sh] Enclave started: ${enclave_id}"

# Blocking — keeps the container alive.
nitro-cli console --enclave-id "${enclave_id}"
EOF

RUN chmod +x /home/run.sh

CMD ["/home/run.sh"]
Loading