fix(release): publish signing certificate and verify releases the way an operator does #41

Merged
ochenstarik-ui merged 3 commits from integration/release-signing-consistency into main 2026-08-15 06:23:13 +00:00
ochenstarik-ui commented 2026-08-15 06:17:03 +00:00 (Migrated from github.com)

Integrates PR #40 and fixes three inconsistencies around it, so that release signing works on the path an operator actually takes.

What #40 got right, kept as is

Keyless cosign signing produces an ephemeral certificate, not a static key. Until now only manifest.sig was published, so cosign verify-blob had nothing to verify against and the signature on v0.1.0-alpha.12 and v0.1.0-alpha.13 cannot be checked at all. #40 publishes server-monitor-manager-manifest.pem, threads it through verify_manifest and verify_archive, and updates the Desktop updater and the release policy.

Fixed here

gh fought the isolation it runs inside. The verification scripts fetched assets with gh release download, while the isolation step removes .git on purpose so the install comes from the release and not the source tree. gh resolves the repository from that git context, which is why the first runs failed. An operator has neither gh nor a token, so the scripts now use public curl, sha256sum and cosign only. verify-assets.sh keeps gh: it runs before isolation and only lists assets.

The monitor check pointed at a user that does not exist. The bootstrap creates ochenstarik-monitor with /var/lib/ochenstarik-monitor; the script used ochenstarik-smm-monitor under the Control state directory, so that section could never have passed. It now asserts the forced command is pinned in authorized_keys before running it, and quotes the command instead of splitting it on whitespace.

The expected asset list lacked the certificate, so a correct release would have been reported as having an unexpected asset.

Added

  • negative case: an archive published without its certificate must be rejected;
  • docs/linux-bootstrap.md now lists manifest, signature and certificate among the files to download, because verify-release requires all three beside the archive and the previous list stopped being sufficient;
  • drafting comments that quoted the task text removed from the committed scripts.

Verification

bash -n on every changed script. BOOTSTRAP_CONTRACT=PASS, RELEASE_CONTRACT=PASS locally. test-manifest-verification.sh needs cosign and runs in CI.

Not verified locally: the release-verification workflow itself, which only runs against a published release.

🤖 Generated with Claude Code

Integrates PR #40 and fixes three inconsistencies around it, so that release signing works on the path an operator actually takes. ## What #40 got right, kept as is Keyless cosign signing produces an ephemeral certificate, not a static key. Until now only `manifest.sig` was published, so `cosign verify-blob` had nothing to verify against and the signature on `v0.1.0-alpha.12` and `v0.1.0-alpha.13` cannot be checked at all. #40 publishes `server-monitor-manager-manifest.pem`, threads it through `verify_manifest` and `verify_archive`, and updates the Desktop updater and the release policy. ## Fixed here **`gh` fought the isolation it runs inside.** The verification scripts fetched assets with `gh release download`, while the isolation step removes `.git` on purpose so the install comes from the release and not the source tree. `gh` resolves the repository from that git context, which is why the first runs failed. An operator has neither `gh` nor a token, so the scripts now use public `curl`, `sha256sum` and `cosign` only. `verify-assets.sh` keeps `gh`: it runs before isolation and only lists assets. **The monitor check pointed at a user that does not exist.** The bootstrap creates `ochenstarik-monitor` with `/var/lib/ochenstarik-monitor`; the script used `ochenstarik-smm-monitor` under the Control state directory, so that section could never have passed. It now asserts the forced command is pinned in `authorized_keys` before running it, and quotes the command instead of splitting it on whitespace. **The expected asset list lacked the certificate**, so a correct release would have been reported as having an unexpected asset. ## Added - negative case: an archive published without its certificate must be rejected; - `docs/linux-bootstrap.md` now lists manifest, signature and certificate among the files to download, because `verify-release` requires all three beside the archive and the previous list stopped being sufficient; - drafting comments that quoted the task text removed from the committed scripts. ## Verification `bash -n` on every changed script. `BOOTSTRAP_CONTRACT=PASS`, `RELEASE_CONTRACT=PASS` locally. `test-manifest-verification.sh` needs cosign and runs in CI. Not verified locally: the release-verification workflow itself, which only runs against a published release. 🤖 Generated with [Claude Code](https://claude.com/claude-code)
Sign in to join this conversation.
No reviewers
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference: ochenstarik/server-monitor-manager#41
No description provided.