codai docs
Apps

Verify downloads

What is signed and hashed for each platform — minisign signatures on the Windows installer and Linux AppImage, SHA256SUMS on every release — and what is not (Authenticode, notarization, Android).

Every desktop release on github.com/codai-ro/codai-desktop/releases carries two kinds of proof. This page says exactly which files get which, so you know what a green check actually means.

PlatformFileChecksum in SHA256SUMSDetached signatureCode-signing / notarization
Windowscodai_<v>_x64-setup.exeyesyes — codai_<v>_x64-setup.exe.sig (minisign)no Authenticode yet — SmartScreen will warn
Windowscodai_<v>_x64_en-US.msiyesnono
Windowscodai_<v>_x64-portable.zipyesnono
Linuxcodai_<v>_amd64.AppImageyes (when built)yes — .AppImage.sig (minisign, when built)n/a
Linux.deb, .rpmyes (when built)nonot GPG-signed
macOS.dmg——not published; no notarization
Android.apk—signed with the release keystore (APK v2 signature)no separate checksum file yet

latest.json in the same release is what the auto-updater reads; its platforms.windows-x86_64.signature is the content of the .exe.sig file, so the updater and a manual check verify the same thing.

Checksums (every file)

SHA256SUMS lists one lowercase SHA-256 per asset, in the format <hash> <filename>.

# in the folder where you downloaded the assets
$sums = Get-Content .\SHA256SUMS
Get-ChildItem codai_* | ForEach-Object {
  $h = (Get-FileHash $_.FullName -Algorithm SHA256).Hash.ToLower()
  $ok = $sums -match "^$h  $([regex]::Escape($_.Name))$"
  "{0}  {1}" -f ($(if ($ok) { 'OK ' } else { 'BAD' })), $_.Name
}

A checksum proves the file was not corrupted or swapped after it was published. It does not prove who published it — for that you need the signature below.

Signatures (Windows installer, Linux AppImage)

The .sig files are minisign signatures produced by tauri signer. The matching public key is compiled into the app and printed in src-tauri/tauri.conf.json → plugins.updater.pubkey. Only a file signed by the private half of that key will be installed by the updater — and only such a file should be installed by you.

Get the public key

It is base64-encoded in tauri.conf.json. Decode it to a two-line minisign public key:

$pub = 'dW50cnVzdGVkIGNvbW1lbnQ6IG1pbmlzaWduIHB1YmxpYyBrZXk6IDFCRERBM0QxMDY4NzYyNjcKUldSbllvY0cwYVBkRzcrYXdNcmFyMnZmTEhTRGJPOWlmZVkzdGZsVjRJWXN1Q0dHTXp6UWJSaGcK'
[Text.Encoding]::UTF8.GetString([Convert]::FromBase64String($pub)) | Set-Content codai-desktop.pub

The decoded file starts with untrusted comment: minisign public key: 1BDDA3D106876267. Compare that key id with the one in the repository's tauri.conf.json — if they differ, stop.

Decode the signature

The .sig is base64 too:

$v = '0.6.1'
[Text.Encoding]::UTF8.GetString([Convert]::FromBase64String((Get-Content "codai_${v}_x64-setup.exe.sig" -Raw))) | Set-Content "codai_${v}_x64-setup.exe.minisig"

Verify

Install minisign (winget install minisign, brew install minisign, or your distro's package), then:

minisign -Vm "codai_${v}_x64-setup.exe" -p codai-desktop.pub -x "codai_${v}_x64-setup.exe.minisig"

Signature and comment signature verified means the file is the one we signed. Anything else means it is not — do not run it, and tell us at [email protected].

The same three steps apply to codai_<v>_amd64.AppImage / .AppImage.sig on releases that include a Linux build.

What is not signed today

Be precise about what a green result covers.

  • Windows Authenticode — the installer is not signed with a code-signing certificate, so Windows SmartScreen shows "Windows protected your PC" the first time. This is planned (Azure Artifact Signing); until then the minisign check above is the way to know the file is ours.
  • .msi and portable .zip — checksummed, not signed.
  • Linux .deb / .rpm — checksummed, not GPG-signed; no apt/dnf repository exists.
  • macOS — no build is published, hence no notarization.
  • Android APK — signed with the release keystore as every Android app must be (certificate SHA-256 11:F1:6A:8B…; the full fingerprint is in the codai-phone repo). Android verifies it on install and refuses an update signed by a different key. There is no separate SHA256SUMS for the APK yet.

Releases and rollback

  • Releases are tagged desktop-v<version>; the three version files in the source (package.json, tauri.conf.json, Cargo.toml) always agree with the tag.
  • The updater endpoint https://codai.ro/api/desktop/latest.json serves the newest non-pre-release. A bad release is rolled back by marking it pre-release (or deleting it): the previous one becomes "latest" again within five minutes. The updater never downgrades an already-installed newer version.
  • The private signing key never leaves the maintainer's machine and is backed up offline; losing it would orphan every installed client.

On this page