Skip to content

Harden releases: pin updates to the signing certificate, tag-only R2 mirror - #2

Merged
aryan1306 merged 2 commits into
mainfrom
chore/release-hardening
Sep 25, 2026
Merged

aryan1306 merged 2 commits into
mainfrom
chore/release-hardening

Conversation

@aryan1306

Copy link
Copy Markdown
Owner

Why

Follow-ups from #1.

  • Updater: the updater checked only that a download was validly signed, by anyone.
  • R2: a manual Build DMG run mirrored to R2 and overwrote latest/version.txt, so a test build could become the advertised latest version.
  • GitGuardian: it flagged the signing secret checks as hardcoded passwords. These were false positives; nothing secret was committed.

Changes

  • Updater: a certificate-signed LLMits now installs an update only if it meets the running app's code-signing requirement, i.e. it was signed with the same release certificate. Otherwise it shows "The update was not signed by the LLMits release certificate."
    • Ad-hoc builds (v1.1.0 and earlier) have no stable identity to pin, so they keep the existing check and can update to the first signed release.
    • Moving to Developer ID later needs one bridge release, signed with the current certificate, that also accepts the new one. A code comment notes this.
  • R2: the Cloudflare R2 mirror step now runs only for v* tag pushes. Manual runs only upload a workflow artifact.
  • GitGuardian: reworded the CODESIGN_P12_* checks in build-dmg.sh and release.yml so they no longer use the ${VAR:?message} form.

Verification

  • swift test: 59 tests pass, 1 skipped (the live update test). The new UpdateSignatureTests covers:
    • certificate-based requirements are pinned and ad-hoc ones are not;
    • an ad-hoc-signed binary meets its own requirement but not the release certificate's.
  • With real bundles, the certificate-signed LLMits.app meets the pinned requirement and an ad-hoc re-signed copy is rejected.
  • bash -n scripts/build-dmg.sh, workflow YAML parses, and git diff --check.

Manual Build DMG runs mirrored to R2 and overwrote latest/version.txt.
The signing secret checks used a :? form that GitGuardian flagged as a
hardcoded password.
A certificate-signed app now requires the downloaded update to satisfy
its own designated requirement. Ad-hoc builds have no stable identity to
pin and keep the existing signature check, so current installs can
still update to the first signed release.
@aryan1306
aryan1306 merged commit 0cb3e9d into main Sep 25, 2026
2 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant