Skip to content

Verifying Releases

Every Open Cowork release is published with tamper-evidence: a checksum manifest, a detached signature for it (on signed releases), per-platform code signatures, and GitHub build-provenance attestations. This page shows how to verify a download before trusting it.

The examples use joe-broadhead/open-cowork; replace the owner/repo for a downstream fork.

What ships with a release

Asset Purpose
Open-Cowork-<version>-<arch>.dmg / -mac.zip macOS installers
Open-Cowork-<version>-x64-setup.exe Windows NSIS installer
Open-Cowork-<version>-x64.AppImage / .deb Linux packages
latest-mac.yml, latest.yml, *.blockmap electron-updater feed metadata (signed macOS/Windows builds only)
SHA256SUMS.txt SHA-256 checksums for every asset
SHA256SUMS.txt.asc Detached GPG signature of the checksum file (signed releases)
sbom.cdx.json, sbom.spdx.json CycloneDX and SPDX software bill of materials
THIRD_PARTY_NOTICES.md, THIRD_PARTY_LICENSES.tar.gz Third-party attribution

1. Verify the checksum

Download your installer plus SHA256SUMS.txt into the same directory, then:

shasum -a 256 -c SHA256SUMS.txt --ignore-missing
$expected = (Select-String 'Open-Cowork-.*-setup.exe' SHA256SUMS.txt).Line.Split(' ')[0]
$actual = (Get-FileHash .\Open-Cowork-<version>-x64-setup.exe -Algorithm SHA256).Hash.ToLower()
if ($expected -eq $actual) { "OK" } else { throw "checksum mismatch" }

2. Verify the checksum signature (signed releases)

When SHA256SUMS.txt.asc is present, verify it before trusting the checksums. Import the project's release GPG public key (published in the release notes / SECURITY.md), then:

gpg --verify SHA256SUMS.txt.asc SHA256SUMS.txt

A good signature from the expected key means the checksum manifest — and by extension every asset it lists — is authentic.

3. Verify GitHub build provenance

Release assets carry a signed provenance attestation tying them to this repository's release workflow. With the GitHub CLI:

gh attestation verify ./Open-Cowork-<version>-x64-setup.exe \
  --repo joe-broadhead/open-cowork

Repeat for any asset (.dmg, .zip, .AppImage, .deb, .exe, SHA256SUMS.txt, the SBOMs). The signed latest.yml / latest-mac.yml update-feed metadata is attested too.

4. Verify the platform code signature

Gatekeeper checks this automatically on first launch. To verify manually that the app is signed, notarized, and stapled:

codesign --verify --deep --strict --verbose=2 /Applications/Open\ Cowork.app
spctl -a -vv -t exec /Applications/Open\ Cowork.app
xcrun stapler validate /Applications/Open\ Cowork.app

Confirm the installer's Authenticode signature is valid and note the publisher:

Get-AuthenticodeSignature .\Open-Cowork-<version>-x64-setup.exe |
  Format-List Status, SignerCertificate

Status must be Valid. The same publisher is what electron-updater checks before applying an in-app update.

Linux packages are not OS-code-signed. Trust is established by the checksum, its detached GPG signature, and GitHub provenance (steps 1–3). Verify all three before running the .AppImage or installing the .deb.

In-app updates

On macOS and Windows, signed builds can check for, download, and install updates from within the app (Settings → check for updates). The updater verifies the download against the sha512 in the feed metadata and, on Windows, against the code-signing publisher — so an update is only applied if it matches the same signing identity as the installed build. Linux uses the verified manual-download path above.

Downstream forks that host their own feed follow the identical steps against their own signing key and provenance; see Packaging and Releases.

Runtime component integrity

Beyond the installer signature, the app verifies the runtime components it executes (the bundled OpenCode CLI/SDK and the managed MCP servers) against a trusted manifest, so a tampered component inside an otherwise-valid install is detected before the managed runtime starts.

  • Trust anchor. A signed release ships resources/runtime-components.manifest.json that pins each component's build-time SHA-256 (sha256). At launch the runtime re-hashes the bundled files and raises component_hash_mismatch (and refuses to start the managed server) if any digest differs from the pinned value. The manifest is produced by writeRuntimeComponentManifest, which hashes the packaged components and records the digest as the authoritative sha256.
  • No override in packaged builds. The development override (OPEN_COWORK_RUNTIME_COMPONENT_DEV_OVERRIDE_REASON) only relaxes provenance checks for local, unpackaged development. It is ignored entirely once the app is packaged (app.isPackaged), so it can never be set in production to defeat the anchor.
  • Unsigned/dev builds. Local and unsigned CI smoke builds legitimately ship without the pinned manifest; verification degrades to the provenance check and is enforced only for packaged builds. Generating and shipping the pinned manifest is a signed-release build step.