Skip to content
Open
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
85 changes: 85 additions & 0 deletions .github/workflows/key-provider-release.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
# SPDX-FileCopyrightText: © 2025 Phala Network <dstack@phala.network>
#
# SPDX-License-Identifier: Apache-2.0

name: Key Provider Release

on:
workflow_dispatch:
push:
tags:
- 'key-provider-v*'
permissions:
attestations: write
id-token: write
contents: write
packages: write

jobs:
build-and-release:
runs-on: ubuntu-latest
steps:
- name: Checkout repository
uses: actions/checkout@v4

- name: Parse version from tag
run: |
# Extract version from tag (e.g., key-provider-v1.2.3 -> 1.2.3)
VERSION=${GITHUB_REF#refs/tags/key-provider-v}
echo "VERSION=$VERSION" >> $GITHUB_ENV
echo "Parsed version: $VERSION"

- name: Log in to Docker Hub
uses: docker/login-action@v3
with:
username: ${{ vars.DOCKERHUB_USERNAME }}
password: ${{ secrets.DOCKERHUB_TOKEN }}

- name: Log in to GHCR
uses: docker/login-action@v3
with:
registry: ghcr.io
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}

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

- name: Get Git commit timestamps
run: |
echo "TIMESTAMP=$(git log -1 --pretty=%ct)" >> $GITHUB_ENV
echo "GIT_REV=$(git rev-parse HEAD)" >> $GITHUB_ENV

- name: Build and push Docker image
id: build-and-push
uses: docker/build-push-action@v5
env:
SOURCE_DATE_EPOCH: ${{ env.TIMESTAMP }}
with:
context: key-provider-build
push: true
tags: |
${{ vars.DOCKERHUB_ORG }}/dstack-gramine-key-provider:${{ env.VERSION }}
ghcr.io/dstack-tee/dstack/dstack-gramine-key-provider:${{ env.VERSION }}
platforms: linux/amd64
provenance: false

- name: Generate artifact attestation
uses: actions/attest-build-provenance@v1
with:
subject-name: "docker.io/${{ vars.DOCKERHUB_ORG }}/dstack-gramine-key-provider"
subject-digest: ${{ steps.build-and-push.outputs.digest }}
push-to-registry: true

- name: GitHub Release
uses: softprops/action-gh-release@v1
with:
name: "Key Provider Release v${{ env.VERSION }}"
body: |
## Docker Image Information

**Image**: `docker.io/${{ vars.DOCKERHUB_ORG }}/dstack-gramine-key-provider:${{ env.VERSION }}`

**Digest (SHA256)**: `${{ steps.build-and-push.outputs.digest }}`

**Verification**: [Verify on Sigstore](https://search.sigstore.dev/?hash=${{ steps.build-and-push.outputs.digest }})
55 changes: 55 additions & 0 deletions key-provider-build/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
# SPDX-FileCopyrightText: © 2024-2025 Phala Network <dstack@phala.network>
#
# SPDX-License-Identifier: Apache-2.0

# Stage 1: Build
FROM gramineproject/gramine:1.9-jammy@sha256:84b3d222e0bd9ab941f0078a462af0dbc5518156b99b147c10a7b83722ac0c38 AS builder

RUN apt-get update && apt-get install -y \
git \
build-essential \
&& rm -rf /var/lib/apt/lists/*

RUN curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- --default-toolchain 1.85 -y
ENV PATH="/root/.cargo/bin:${PATH}"

ENV SGX=1 DEBUG=0 DEV_MODE=0 RUST_LOG=info

RUN git clone https://github.com/MoeMahhouk/gramine-sealing-key-provider && \
cd gramine-sealing-key-provider && \
git checkout 180ff4691dce5aae7cd7d6c1344c3e1ec872f174

WORKDIR /gramine-sealing-key-provider
COPY Cargo.lock .

RUN make target/release/gramine-sealing-key-provider && \
gramine-sgx-gen-private-key && \
make RUST_LOG=info

# Stage 2: Runtime
# Same base image = same /lib/x86_64-linux-gnu/ (except libgcc-s1 from build-essential)
FROM gramineproject/gramine:1.9-jammy@sha256:84b3d222e0bd9ab941f0078a462af0dbc5518156b99b147c10a7b83722ac0c38

# libgcc-s1: only /lib/x86_64-linux-gnu/ addition from build-essential, needed for manifest hash match
# libsgx-dcap-default-qpl: not in base image, needed by aesmd for DCAP
RUN curl -fsSL https://download.01.org/intel-sgx/sgx_repo/ubuntu/intel-sgx-deb.key \
| gpg --dearmor -o /usr/share/keyrings/intel-sgx-deb.gpg && \
echo 'deb [arch=amd64 signed-by=/usr/share/keyrings/intel-sgx-deb.gpg] https://download.01.org/intel-sgx/sgx_repo/ubuntu jammy main' \
> /etc/apt/sources.list.d/intel-sgx.list && \
apt-get update && apt-get install -y \
libgcc-s1 \
libsgx-dcap-default-qpl \
&& rm -rf /var/lib/apt/lists/*

COPY --from=builder /gramine-sealing-key-provider/target/release/gramine-sealing-key-provider /gramine-sealing-key-provider/target/release/gramine-sealing-key-provider
COPY --from=builder /gramine-sealing-key-provider/gramine-sealing-key-provider.manifest.sgx /gramine-sealing-key-provider/
COPY --from=builder /gramine-sealing-key-provider/gramine-sealing-key-provider.sig /gramine-sealing-key-provider/

WORKDIR /gramine-sealing-key-provider

COPY entrypoint.sh /entrypoint.sh
RUN chmod +x /entrypoint.sh

EXPOSE 3443

ENTRYPOINT ["/entrypoint.sh"]
30 changes: 30 additions & 0 deletions key-provider-build/dstack-key-provider.service
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
# SPDX-FileCopyrightText: © 2025 Phala Network <dstack@phala.network>
#
# SPDX-License-Identifier: Apache-2.0

[Unit]
Description=Gramine Sealing Key Provider
After=docker.service
Requires=docker.service

[Service]
Type=simple
ExecStart=/bin/bash -c '\
if /usr/bin/docker inspect gramine-sealing-key-provider >/dev/null 2>&1; then \
/usr/bin/docker start -a gramine-sealing-key-provider; \
else \
/usr/bin/docker run \
--name gramine-sealing-key-provider \
--privileged \
--device /dev/sgx_enclave:/dev/sgx_enclave \
--device /dev/sgx_provision:/dev/sgx_provision \
-v /etc/dstack-key-provider/sgx_default_qcnl.conf:/etc/sgx_default_qcnl.conf \
-p 127.0.0.1:3443:3443 \
dstacktee/dstack-gramine-key-provider:0.1.0; \
fi'
ExecStop=/usr/bin/docker stop gramine-sealing-key-provider
Restart=on-failure
RestartSec=5

[Install]
WantedBy=multi-user.target
39 changes: 39 additions & 0 deletions key-provider-build/entrypoint.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
#!/bin/sh

# SPDX-FileCopyrightText: © 2025 Phala Network <dstack@phala.network>
#
# SPDX-License-Identifier: Apache-2.0

set -e

# Start AESM service in background
echo "Starting AESM service..."
mkdir -p /var/run/aesmd
chmod 755 /var/run/aesmd
export AESM_PATH=/opt/intel/sgx-aesm-service/aesm
export LD_LIBRARY_PATH=/opt/intel/sgx-aesm-service/aesm
/opt/intel/sgx-aesm-service/aesm/aesm_service --no-daemon &
AESM_PID=$!

# Clean up aesmd on exit
trap 'kill "$AESM_PID" 2>/dev/null; exit' INT TERM EXIT

# Wait for AESM socket
echo "Waiting for AESM socket..."
AESM_SOCKET="/var/run/aesmd/aesm.socket"
while [ ! -S "$AESM_SOCKET" ]; do
if ! kill -0 "$AESM_PID" 2>/dev/null; then
echo "Error: AESM service exited unexpectedly"
exit 1
fi
sleep 1
done
echo "AESM socket is available."

# Show enclave info
echo "Enclave info:"
gramine-sgx-sigstruct-view --output-format json gramine-sealing-key-provider.sig

# Replace shell with gramine-sgx so it receives signals directly as PID 1
echo "Starting Gramine Sealing Key Provider"
exec gramine-sgx gramine-sealing-key-provider
Loading