From 8cca8913a7f4eb6856ee31717a44440644bee055 Mon Sep 17 00:00:00 2001 From: Richard Alpe Date: Tue, 23 Sep 2025 11:15:15 +0200 Subject: [PATCH 1/2] .github: add bitSign workflow for signing releases This is currently a standalone workflow that needs manual trigger via workflow_dispatch, but the end goal here is to chain it to the release job. Signed-off-by: Richard Alpe --- .github/workflows/bitsign.yml | 215 ++++++++++++++++++++++++++++++++++ 1 file changed, 215 insertions(+) create mode 100644 .github/workflows/bitsign.yml diff --git a/.github/workflows/bitsign.yml b/.github/workflows/bitsign.yml new file mode 100644 index 000000000..7af7e6ffe --- /dev/null +++ b/.github/workflows/bitsign.yml @@ -0,0 +1,215 @@ +name: bitSign Infix Release + +on: + workflow_dispatch: + inputs: + release_version: + description: 'Release version (e.g., v25.08.0)' + required: true + type: string + push: + branches: [ sign-with-bitsign ] + +jobs: + sign-infix-release: + runs-on: ubuntu-latest + + steps: + - name: Checkout repository + uses: actions/checkout@v4 + + - name: Validate release version format + id: validate + run: | + # Use default version for push events, input version for manual dispatch + if [ "${{ github.event_name }}" = "push" ]; then + VERSION="v25.08.0" + echo "Using default version for push trigger: $VERSION" + else + VERSION="${{ inputs.release_version }}" + echo "Using input version for manual trigger: $VERSION" + fi + + # Check if version starts with 'v' and has proper format + if ! echo "$VERSION" | grep -qE '^v[0-9]+\.[0-9]+(\.[0-9]+)?(-alpha[0-9]*|-beta[0-9]*|-rc[0-9]*)?$'; then + echo "❌ Invalid version format. Expected format: vYY.MM(.PP)(-alphaN|-betaN|-rcN)" + echo "Examples: v25.08.0, v25.08.0-alpha1, v25.08.0-rc1" + exit 1 + fi + + # Extract version without 'v' prefix for filename + FILE_VERSION="${VERSION#v}" + FILENAME="infix-x86_64-${FILE_VERSION}.tar.gz" + RELEASE_URL="https://github.com/kernelkit/infix/releases/download/${VERSION}/${FILENAME}" + + echo "✅ Version format valid" + echo "file_version=${FILE_VERSION}" >> $GITHUB_OUTPUT + echo "filename=${FILENAME}" >> $GITHUB_OUTPUT + echo "release_url=${RELEASE_URL}" >> $GITHUB_OUTPUT + + - name: Download Infix release + run: | + RELEASE_URL="${{ steps.validate.outputs.release_url }}" + FILENAME="${{ steps.validate.outputs.filename }}" + + echo "Downloading Infix release: $FILENAME" + echo "From: $RELEASE_URL" + + if ! curl -L "$RELEASE_URL" -o "$FILENAME" --fail --show-error --progress-bar; then + echo "❌ Failed to download release file from: $RELEASE_URL" + echo "Please verify that the release version exists and contains the x86_64 build." + echo "You can check available releases at: https://github.com/kernelkit/infix/releases" + exit 1 + fi + + # Verify download + if [ -f "$FILENAME" ] && [ -s "$FILENAME" ]; then + FILE_SIZE=$(ls -lh "$FILENAME" | awk '{print $5}') + echo "✅ Successfully downloaded: $FILENAME ($FILE_SIZE)" + else + echo "❌ Failed to download release file" + exit 1 + fi + + - name: Create signing request + id: create_request + run: | + FILENAME="${{ steps.validate.outputs.filename }}" + FILE_VERSION="${{ steps.validate.outputs.file_version }}" + RELEASE="infix-x86_64-${FILE_VERSION}" + + echo "Creating signing request for $FILENAME..." + echo "RELEASE parameter: $RELEASE" + + # Create signing request using bitSign API + RESPONSE=$(curl -s -X POST "https://portal.bitsign.se/api/v1/requests" \ + -H "Authorization: Bearer ${{ secrets.BITSIGN_API_KEY }}" \ + -F "file=@$FILENAME" \ + -F "key=bit42-Demo1" \ + -F "job=Infix-x86" \ + -F "parameters={\"RELEASE\": \"$RELEASE\"}") + + echo "API Response: $RESPONSE" + + # Check if request was successful + if echo "$RESPONSE" | jq -e '.success == true' > /dev/null; then + REQUEST_ID=$(echo "$RESPONSE" | jq -r '.requestId') + echo "✅ Request created successfully with ID: $REQUEST_ID" + echo "request_id=$REQUEST_ID" >> $GITHUB_OUTPUT + else + echo "❌ Failed to create signing request" + echo "$RESPONSE" | jq -r '.error // .message // "Unknown error"' + exit 1 + fi + + - name: Wait for signing completion + id: wait_completion + run: | + REQUEST_ID="${{ steps.create_request.outputs.request_id }}" + echo "Waiting for signing completion for request: $REQUEST_ID" + + # Poll status for up to 10 minutes (600 seconds) - longer timeout for larger files + MAX_WAIT=600 + WAITED=0 + + while [ $WAITED -lt $MAX_WAIT ]; do + RESPONSE=$(curl -s -X GET "https://portal.bitsign.se/api/v1/requests/$REQUEST_ID/status" \ + -H "Authorization: Bearer ${{ secrets.BITSIGN_API_KEY }}") + + STATUS=$(echo "$RESPONSE" | jq -r '.status') + echo "Current status: $STATUS (waited ${WAITED}s)" + + if [ "$STATUS" = "completed" ]; then + echo "✅ Signing completed successfully!" + break + elif [ "$STATUS" = "failed" ]; then + echo "❌ Signing failed" + echo "$RESPONSE" | jq -r '.error // .message // "Unknown error"' + exit 1 + fi + + sleep 10 + WAITED=$((WAITED + 10)) + done + + if [ $WAITED -ge $MAX_WAIT ]; then + echo "❌ Timeout: Signing did not complete within ${MAX_WAIT} seconds" + exit 1 + fi + + - name: Download signed file + id: download_signed + run: | + REQUEST_ID="${{ steps.create_request.outputs.request_id }}" + FILENAME="${{ steps.validate.outputs.filename }}" + FILE_VERSION="${{ steps.validate.outputs.file_version }}" + SIGNED_FILENAME="infix-x86_64-${FILE_VERSION}-signed.tar.gz" + + echo "Downloading signed file for request: $REQUEST_ID" + echo "Expected signed filename: $SIGNED_FILENAME" + + # Download the signed file + curl -X GET "https://portal.bitsign.se/api/v1/requests/$REQUEST_ID/download" \ + -H "Authorization: Bearer ${{ secrets.BITSIGN_API_KEY }}" \ + -o "$SIGNED_FILENAME" \ + --fail --show-error + + if [ -f "$SIGNED_FILENAME" ] && [ -s "$SIGNED_FILENAME" ]; then + FILE_SIZE=$(ls -lh "$SIGNED_FILENAME" | awk '{print $5}') + echo "Successfully downloaded signed file: $SIGNED_FILENAME ($FILE_SIZE)" + echo "signed_filename=$SIGNED_FILENAME" >> $GITHUB_OUTPUT + + # Calculate SHA256 checksums for both files + ORIGINAL_SHA256=$(sha256sum "$FILENAME" | cut -d' ' -f1) + SIGNED_SHA256=$(sha256sum "$SIGNED_FILENAME" | cut -d' ' -f1) + echo "original_sha256=$ORIGINAL_SHA256" >> $GITHUB_OUTPUT + echo "signed_sha256=$SIGNED_SHA256" >> $GITHUB_OUTPUT + else + echo "Failed to download signed file" + exit 1 + fi + + - name: Upload signed artifacts + uses: actions/upload-artifact@v4 + with: + name: signed-infix-${{ steps.validate.outputs.file_version }} + path: ${{ steps.download_signed.outputs.signed_filename }} + retention-days: 90 + + - name: Summary + run: | + # Determine the actual version used (could be from push or input) + if [ "${{ github.event_name }}" = "push" ]; then + ACTUAL_VERSION="v25.08.0" + else + ACTUAL_VERSION="${{ inputs.release_version }}" + fi + + cat >> $GITHUB_STEP_SUMMARY << EOF + # bitSign Infix Release Signing Complete + + The Infix release has been successfully signed using the bitSign API. + + ## Signing Details + + | Property | Value | + |----------|-------| + | 📦 **Original File** | \`${{ steps.validate.outputs.filename }}\` (\`${{ steps.download_signed.outputs.original_sha256 }}\`) | + | ✍️ **Signed File** | \`${{ steps.download_signed.outputs.signed_filename }}\` (\`${{ steps.download_signed.outputs.signed_sha256 }}\`) | + | 🔑 **Signing Key** | \`bit42-Demo1\` | + | ⚙️ **Job Type** | \`Infix-x86\` | + | 🆔 **Request ID** | \`${{ steps.create_request.outputs.request_id }}\` | + | 📋 **Release Version** | \`\$ACTUAL_VERSION\` | + | 🌐 **API Endpoint** | \`portal.bitsign.se\` | + + ## Download Files + + > **The signed release file is available as a workflow artifact:** + > **\`signed-infix-${{ steps.validate.outputs.file_version }}\`** + > + > The artifact contains the signed file: \`${{ steps.download_signed.outputs.signed_filename }}\` + + --- + + **Next Steps:** The signed release can now be distributed with cryptographic verification of authenticity. + EOF \ No newline at end of file From 03f4a8d04468e5e4ca17da2347f0631ab12d6840 Mon Sep 17 00:00:00 2001 From: Richard Alpe Date: Tue, 23 Sep 2025 16:31:32 +0200 Subject: [PATCH 2/2] doc: mention bitSign code signing in main README Signed-off-by: Richard Alpe --- README.md | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/README.md b/README.md index 3745ad6f4..fefe4c819 100644 --- a/README.md +++ b/README.md @@ -135,12 +135,21 @@ for reliability you can trust: - **Hardware Acceleration**: Linux switchdev support for wire-speed packet processing - **Container Integration**: Docker support with flexible network and hardware access - **Memory Efficient**: Runs comfortably on devices with as little as 256 MB RAM +- **Code Signing**: All releases are cryptographically signed for integrity verification Perfect for everything from resource-constrained edge devices to high-throughput network appliances. > Check the *[Latest Build][]* for bleeding-edge features. + + + + + bitSign - Code Signing + + + ---