Skip to content
Draft
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
15 changes: 15 additions & 0 deletions .github/workflows/compile_c.yml
Original file line number Diff line number Diff line change
Expand Up @@ -136,3 +136,18 @@ jobs:
with:
name: executables-C-Musl-x64.zip
path: target/*

# Sign and notarize macOS binaries
sign-macos-c:
name: Sign and Notarize macOS C Binaries
needs: build-darwin
uses: ./.github/workflows/macos-sign-notarize.yml
with:
binary_path: target/
binary_name: executables-C-MacOS.zip
secrets:
APPLE_CERTIFICATE: ${{ secrets.APPLE_CERTIFICATE }}
APPLE_CERTIFICATE_PASSWORD: ${{ secrets.APPLE_CERTIFICATE_PASSWORD }}
APPLE_DEVELOPER_ID: ${{ secrets.APPLE_DEVELOPER_ID }}
APPLE_APP_PASSWORD: ${{ secrets.APPLE_APP_PASSWORD }}
APPLE_TEAM_ID: ${{ secrets.APPLE_TEAM_ID }}
15 changes: 15 additions & 0 deletions .github/workflows/compile_cplus.yml
Original file line number Diff line number Diff line change
Expand Up @@ -122,3 +122,18 @@ jobs:
with:
name: executable-Cplus-Musl-x64
path: target/*

# Sign and notarize macOS binaries
sign-macos-cplus:
name: Sign and Notarize macOS C++ Binaries
needs: build-darwin
uses: ./.github/workflows/macos-sign-notarize.yml
with:
binary_path: target/
binary_name: executable-CPlus-MacOS
secrets:
APPLE_CERTIFICATE: ${{ secrets.APPLE_CERTIFICATE }}
APPLE_CERTIFICATE_PASSWORD: ${{ secrets.APPLE_CERTIFICATE_PASSWORD }}
APPLE_DEVELOPER_ID: ${{ secrets.APPLE_DEVELOPER_ID }}
APPLE_APP_PASSWORD: ${{ secrets.APPLE_APP_PASSWORD }}
APPLE_TEAM_ID: ${{ secrets.APPLE_TEAM_ID }}
18 changes: 18 additions & 0 deletions .github/workflows/compile_dotnet.yml
Original file line number Diff line number Diff line change
Expand Up @@ -31,3 +31,21 @@ jobs:
with:
name: executable-dotnet-${{ matrix.runtime }}
path: /home/runner/work/wrongsecrets-binaries/wrongsecrets-binaries/dotnet/dotnetproject/bin/Release/net8.0/${{ matrix.runtime }}/publish/

# Sign and notarize macOS binaries
sign-macos-dotnet:
name: Sign and Notarize macOS .NET Binaries
needs: build
uses: ./.github/workflows/macos-sign-notarize.yml
strategy:
matrix:
runtime: ["osx-x64", "osx-arm64"]
with:
binary_path: /home/runner/work/wrongsecrets-binaries/wrongsecrets-binaries/dotnet/dotnetproject/bin/Release/net8.0/${{ matrix.runtime }}/publish/
binary_name: executable-dotnet-${{ matrix.runtime }}
secrets:
APPLE_CERTIFICATE: ${{ secrets.APPLE_CERTIFICATE }}
APPLE_CERTIFICATE_PASSWORD: ${{ secrets.APPLE_CERTIFICATE_PASSWORD }}
APPLE_DEVELOPER_ID: ${{ secrets.APPLE_DEVELOPER_ID }}
APPLE_APP_PASSWORD: ${{ secrets.APPLE_APP_PASSWORD }}
APPLE_TEAM_ID: ${{ secrets.APPLE_TEAM_ID }}
20 changes: 19 additions & 1 deletion .github/workflows/compile_golang.yml
Original file line number Diff line number Diff line change
Expand Up @@ -94,4 +94,22 @@ jobs:
uses: actions/upload-artifact@v4
with:
name: executable-Go-Windows
path: target/*
path: target/*

# Sign and notarize macOS binaries
sign-macos-golang:
name: Sign and Notarize macOS Golang Binaries
needs: build-darwin
uses: ./.github/workflows/macos-sign-notarize.yml
strategy:
matrix:
binary: ["executable-Go-MacOS"]
with:
binary_path: target/
binary_name: ${{ matrix.binary }}
secrets:
APPLE_CERTIFICATE: ${{ secrets.APPLE_CERTIFICATE }}
APPLE_CERTIFICATE_PASSWORD: ${{ secrets.APPLE_CERTIFICATE_PASSWORD }}
APPLE_DEVELOPER_ID: ${{ secrets.APPLE_DEVELOPER_ID }}
APPLE_APP_PASSWORD: ${{ secrets.APPLE_APP_PASSWORD }}
APPLE_TEAM_ID: ${{ secrets.APPLE_TEAM_ID }}
15 changes: 15 additions & 0 deletions .github/workflows/compile_rust.yml
Original file line number Diff line number Diff line change
Expand Up @@ -121,3 +121,18 @@ jobs:
with:
name: executable-Rust-Musl(x86)
path: rust/target/x86_64-unknown-linux-musl/release/rust

# Sign and notarize macOS binaries
sign-macos-rust:
name: Sign and Notarize macOS Rust Binary
needs: build-darwin
uses: ./.github/workflows/macos-sign-notarize.yml
with:
binary_path: rust/target/x86_64-apple-darwin/release/rust
binary_name: executable-Rust-MacOS
secrets:
APPLE_CERTIFICATE: ${{ secrets.APPLE_CERTIFICATE }}
APPLE_CERTIFICATE_PASSWORD: ${{ secrets.APPLE_CERTIFICATE_PASSWORD }}
APPLE_DEVELOPER_ID: ${{ secrets.APPLE_DEVELOPER_ID }}
APPLE_APP_PASSWORD: ${{ secrets.APPLE_APP_PASSWORD }}
APPLE_TEAM_ID: ${{ secrets.APPLE_TEAM_ID }}
15 changes: 15 additions & 0 deletions .github/workflows/compile_swift.yml
Original file line number Diff line number Diff line change
Expand Up @@ -84,4 +84,19 @@ jobs:
with:
name: wrongsecrets-swift-linux-musl
path: swift/.build/x86_64-swift-linux-musl/release/swift

# Sign and notarize macOS binaries
sign-macos-swift:
name: Sign and Notarize macOS Swift Binary
needs: build-non-musl
uses: ./.github/workflows/macos-sign-notarize.yml
with:
binary_path: swift/wrongsecrets-swift.universal
binary_name: wrongsecrets-swift
secrets:
APPLE_CERTIFICATE: ${{ secrets.APPLE_CERTIFICATE }}
APPLE_CERTIFICATE_PASSWORD: ${{ secrets.APPLE_CERTIFICATE_PASSWORD }}
APPLE_DEVELOPER_ID: ${{ secrets.APPLE_DEVELOPER_ID }}
APPLE_APP_PASSWORD: ${{ secrets.APPLE_APP_PASSWORD }}
APPLE_TEAM_ID: ${{ secrets.APPLE_TEAM_ID }}

141 changes: 141 additions & 0 deletions .github/workflows/macos-sign-notarize.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,141 @@
name: "macOS Code Sign and Notarize"

on:
workflow_call:
inputs:
binary_path:
description: 'Path to the binary file to sign and notarize'
required: true
type: string
binary_name:
description: 'Name of the binary (for output naming)'
required: true
type: string
secrets:
APPLE_CERTIFICATE:
description: 'Base64 encoded Apple Developer certificate (.p12)'
required: false
APPLE_CERTIFICATE_PASSWORD:
description: 'Password for the Apple Developer certificate'
required: false
APPLE_DEVELOPER_ID:
description: 'Apple Developer ID for notarization'
required: false
APPLE_APP_PASSWORD:
description: 'App-specific password for Apple ID'
required: false
APPLE_TEAM_ID:
description: 'Apple Developer Team ID'
required: false

jobs:
sign-and-notarize:
runs-on: macos-latest
steps:
- name: Check if signing is possible
id: check_secrets
run: |
if [[ -n "${{ secrets.APPLE_CERTIFICATE }}" && -n "${{ secrets.APPLE_CERTIFICATE_PASSWORD }}" ]]; then
echo "signing_available=true" >> $GITHUB_OUTPUT
else
echo "signing_available=false" >> $GITHUB_OUTPUT
echo "⚠️ Apple signing certificate not available - skipping code signing"
fi

if [[ -n "${{ secrets.APPLE_DEVELOPER_ID }}" && -n "${{ secrets.APPLE_APP_PASSWORD }}" && -n "${{ secrets.APPLE_TEAM_ID }}" ]]; then
echo "notarization_available=true" >> $GITHUB_OUTPUT
else
echo "notarization_available=false" >> $GITHUB_OUTPUT
echo "⚠️ Apple notarization credentials not available - skipping notarization"
fi

- name: Download binary
uses: actions/download-artifact@v4
with:
name: ${{ inputs.binary_name }}
path: ./binary

- name: Import signing certificate
if: steps.check_secrets.outputs.signing_available == 'true'
uses: Apple-Actions/import-codesign-certs@v3
with:
p12-file-base64: ${{ secrets.APPLE_CERTIFICATE }}
p12-password: ${{ secrets.APPLE_CERTIFICATE_PASSWORD }}

- name: Sign binary
if: steps.check_secrets.outputs.signing_available == 'true'
run: |
# Find the binary file
BINARY_FILE=$(find ./binary -type f -name "*" | head -1)

if [[ -z "$BINARY_FILE" ]]; then
echo "❌ No binary file found in artifact"
exit 1
fi

echo "🔐 Signing binary: $BINARY_FILE"

# Make binary executable
chmod +x "$BINARY_FILE"

# Sign the binary
codesign --force --sign "Developer ID Application" \
--options runtime \
--timestamp \
"$BINARY_FILE"

# Verify the signature
codesign --verify --verbose "$BINARY_FILE"
echo "✅ Binary signed successfully"

- name: Create ZIP for notarization
if: steps.check_secrets.outputs.signing_available == 'true' && steps.check_secrets.outputs.notarization_available == 'true'
run: |
BINARY_FILE=$(find ./binary -type f -name "*" | head -1)
BINARY_NAME=$(basename "$BINARY_FILE")

# Create a zip file for notarization
cd ./binary
zip -r "../${BINARY_NAME}.zip" *
cd ..

echo "📦 Created ZIP file for notarization: ${BINARY_NAME}.zip"

- name: Notarize binary
if: steps.check_secrets.outputs.signing_available == 'true' && steps.check_secrets.outputs.notarization_available == 'true'
run: |
BINARY_FILE=$(find ./binary -type f -name "*" | head -1)
BINARY_NAME=$(basename "$BINARY_FILE")
ZIP_FILE="${BINARY_NAME}.zip"

echo "🏃 Submitting ${ZIP_FILE} for notarization..."

# Submit for notarization using notarytool
xcrun notarytool submit "$ZIP_FILE" \
--apple-id "${{ secrets.APPLE_DEVELOPER_ID }}" \
--password "${{ secrets.APPLE_APP_PASSWORD }}" \
--team-id "${{ secrets.APPLE_TEAM_ID }}" \
--wait

echo "✅ Notarization completed"

- name: Staple notarization
if: steps.check_secrets.outputs.signing_available == 'true' && steps.check_secrets.outputs.notarization_available == 'true'
run: |
BINARY_FILE=$(find ./binary -type f -name "*" | head -1)

echo "📎 Stapling notarization to binary..."

# Staple the notarization ticket to the binary
xcrun stapler staple "$BINARY_FILE"

# Verify stapling
xcrun stapler validate "$BINARY_FILE"

echo "✅ Notarization stapled successfully"

- name: Upload signed binary
uses: actions/upload-artifact@v4
with:
name: ${{ inputs.binary_name }}-signed
path: ./binary/*
57 changes: 57 additions & 0 deletions docs/MACOS_SIGNING.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
# macOS Code Signing and Notarization

This document describes the macOS code signing and notarization process implemented for the wrongsecrets-binaries repository.

## Overview

All macOS binaries built in this repository are automatically signed and notarized for distribution. This process ensures that macOS users can run the binaries without security warnings.

## Required Secrets

To enable code signing and notarization, the following repository secrets must be configured:

### Code Signing
- `APPLE_CERTIFICATE`: Base64 encoded Apple Developer certificate (.p12 file)
- `APPLE_CERTIFICATE_PASSWORD`: Password for the certificate

### Notarization
- `APPLE_DEVELOPER_ID`: Apple ID (email) registered as a developer
- `APPLE_APP_PASSWORD`: App-specific password for the Apple ID
- `APPLE_TEAM_ID`: Apple Developer Team ID

## How It Works

1. **Conditional Execution**: The signing/notarization process only runs when the required secrets are available
2. **Code Signing**: Binaries are signed with the "Developer ID Application" certificate
3. **Notarization**: Signed binaries are submitted to Apple for automated security checks
4. **Stapling**: The notarization ticket is attached to the binary for offline verification

## Supported Languages

The following language workflows include macOS signing and notarization:

- Swift (universal binaries)
- Golang (Intel and ARM binaries)
- Rust (Intel binaries)
- C (Intel and ARM binaries)
- C++ (Intel and ARM binaries)
- .NET (osx-x64 and osx-arm64 binaries)

## Troubleshooting

If signing or notarization fails:

1. Check that all required secrets are properly configured
2. Verify that the Apple Developer certificate is valid and not expired
3. Ensure that the Apple ID has the necessary permissions for notarization
4. Check the workflow logs for specific error messages

## Manual Testing

To test the signing process locally:

1. Import your Developer ID certificate into Keychain
2. Sign a binary: `codesign --force --sign "Developer ID Application" --options runtime --timestamp your_binary`
3. Verify: `codesign --verify --verbose your_binary`
4. Notarize: `xcrun notarytool submit your_binary.zip --apple-id your@email.com --password your_app_password --team-id TEAM_ID --wait`
5. Staple: `xcrun stapler staple your_binary`