This document describes how releases are created, signed, notarized, and verified.
Back to README | See also: CHANGELOG | Versioning
Releases are a two-phase process:
- CI (automated) — GitHub Actions builds the universal macOS binary, signs it with Sigstore, and creates a draft release with the binary named
stepsecurity-dev-machine-guard-VERSION-darwin_unnotarized. - Apple notarization (manual) — Download the binary, sign and notarize it with an Apple Developer account, upload the notarized binary to the draft release, and publish.
Update Version in internal/buildinfo/version.go:
const Version = "1.9.1"Update CHANGELOG.md. Commit and push to main.
- Go to Actions > Release
- Click Run workflow on the
mainbranch
The workflow will:
- Create a git tag (
v1.9.1) - Build a universal macOS binary (amd64 + arm64) via GoReleaser
- Sign with Sigstore cosign (keyless)
- Upload as
stepsecurity-dev-machine-guard-VERSION-darwin_unnotarizedto a draft release - Record the SHA256 of the unnotarized binary in the release notes
- Generate SLSA build provenance attestation
On a Mac with the Apple Developer certificate installed:
VERSION="1.9.1"
# Download the unnotarized binary
gh release download "v${VERSION}" --repo step-security/dev-machine-guard \
--pattern "stepsecurity-dev-machine-guard-${VERSION}-darwin_unnotarized"
# Rename for signing
cp "stepsecurity-dev-machine-guard-${VERSION}-darwin_unnotarized" \
"stepsecurity-dev-machine-guard-${VERSION}-darwin"
# Sign with Apple Developer ID
codesign --sign "Developer ID Application: <COMPANY> (<TEAM_ID>)" \
--options runtime --timestamp "stepsecurity-dev-machine-guard-${VERSION}-darwin"
# Notarize with Apple (~5 min)
xcrun notarytool submit "stepsecurity-dev-machine-guard-${VERSION}-darwin" \
--apple-id <APPLE_ID_EMAIL> --team-id <TEAM_ID> \
--password <APP_SPECIFIC_PASSWORD> --wait
# Upload the notarized binary to the draft release
gh release upload "v${VERSION}" "stepsecurity-dev-machine-guard-${VERSION}-darwin" \
--repo step-security/dev-machine-guardgh release edit "v${VERSION}" --repo step-security/dev-machine-guard \
--draft=false --latestEach release includes:
| Artifact | Description |
|---|---|
stepsecurity-dev-machine-guard-VERSION-darwin |
Notarized universal macOS binary (amd64 + arm64) |
stepsecurity-dev-machine-guard-VERSION-darwin_unnotarized |
Original CI-built binary (for provenance verification) |
stepsecurity-dev-machine-guard-VERSION-darwin_unnotarized.bundle |
Sigstore cosign bundle for the unnotarized binary |
stepsecurity-dev-machine-guard.sh |
Legacy shell script |
stepsecurity-dev-machine-guard.sh.bundle |
Sigstore cosign bundle for the shell script |
VERSION="1.9.1"
# Download release artifacts
gh release download "v${VERSION}" --repo step-security/dev-machine-guard \
--pattern "stepsecurity-dev-machine-guard-${VERSION}-darwin*"
# Verify Apple signature and notarization
codesign --verify --deep --strict "stepsecurity-dev-machine-guard-${VERSION}-darwin"
spctl --assess --type execute "stepsecurity-dev-machine-guard-${VERSION}-darwin"
# Verify Sigstore signature on the unnotarized binary
cosign verify-blob "stepsecurity-dev-machine-guard-${VERSION}-darwin_unnotarized" \
--bundle "stepsecurity-dev-machine-guard-${VERSION}-darwin_unnotarized.bundle" \
--certificate-oidc-issuer "https://token.actions.githubusercontent.com" \
--certificate-identity-regexp "github.com/.*/dev-machine-guard"
# Verify build provenance
gh attestation verify "stepsecurity-dev-machine-guard-${VERSION}-darwin_unnotarized" \
--repo step-security/dev-machine-guard- Draft → publish flow — binaries are uploaded to a draft release, notarized manually, then published. Once published, the release is immutable.
- Sigstore transparency log — the unnotarized binary signature is recorded in the public Rekor transparency log.
- SLSA build provenance — attestation links the artifact to the exact workflow run, commit SHA, and build environment.
- Duplicate tag check — the release workflow fails if the tag already exists.
- CHANGELOG.md — release history
- VERSIONING.md — versioning scheme
- Sigstore documentation — how keyless signing works
- SLSA — supply chain integrity framework