Minisign Update Verification in OpenLogi: Purpose and Implementation

OpenLogi uses minisign update verification to cryptographically guarantee that every downloaded update is both authentic (signed by the maintainers) and unaltered (integrity protected), falling back to strict failure if verification is impossible.

OpenLogi’s automatic update mechanism relies on the gpui_updater crate to distribute release artifacts securely. To protect users from tampered binaries, the updater employs minisign update verification alongside SHA-256 hashing, ensuring only cryptographically signed artifacts from trusted sources are installed. This verification process is enforced through compile-time public key embedding and strict runtime checks that fail closed when security cannot be guaranteed.

How Minisign Update Verification Works

OpenLogi’s security model relies on a two-layer verification stack that runs in strict verification mode for every artifact downloaded during an update check.

Cryptographic Guarantees

The minisign update verification provides two essential security properties:

  1. Authenticity – The *.minisig signature proves the artifact was produced by OpenLogi maintainers holding the private key that corresponds to the embedded public key.
  2. Integrity – The SHA-256 hash ensures the file contents match exactly what was signed, detecting any corruption or man-in-the-middle tampering.

The Verification Stack

When the updater runs in Verification::Strict mode, it validates both the SHA-256 checksum and the minisign signature before accepting any DMG, MSI, or tar.gz artifact. The public key is baked into the binary at build time via the OPENLOGI_UPDATE_MINISIGN_PUBLIC_KEY environment variable and referenced through the MINISIGN_PUBLIC_KEY constant in crates/openlogi-desktop/src/platform/updater.rs.

Implementation in the OpenLogi Codebase

The verification logic is implemented in the platform-specific updater module, where the public key is embedded at compile time and injected into the update engine configuration.

Embedding the Public Key

The public key is optionally embedded using the option_env! macro, allowing the build to succeed without a key in development environments while enforcing verification in release builds:

// crates/openlogi-desktop/src/platform/updater.rs
const MINISIGN_PUBLIC_KEY: Option<&'static str> =
    option_env!("OPENLOGI_UPDATE_MINISIGN_PUBLIC_KEY");

fn minisign_public_key() -> Option<&'static str> {
    MINISIGN_PUBLIC_KEY
        .map(str::trim)
        .filter(|key| !key.is_empty())
}

Configuring the Updater Engine

The EngineConfig is initialized with strict verification and configured with the minisign public key when available. The minisign_public_key() function retrieves the embedded key and passes it to config.minisign_public_key(key):

// crates/openlogi-desktop/src/platform/updater.rs
let mut config = EngineConfig::new(version).verification(Verification::Strict);
if let Some(key) = minisign_public_key() {
    config = config.minisign_public_key(key); // <- adds minisign verification
}
Updater::new(source, config, cx)

This configuration ensures that gpui_updater validates the minisign signature contained in the corresponding *.minisig file before installing any update.

Release Pipeline Integration

The security guarantees of minisign update verification depend on the CI/CD workflow that signs artifacts during the release process.

CI Signing Process

According to the source analysis of .github/workflows/release.yml, the release pipeline signs each artifact using the minisign private key stored in repository secrets:


# .github/workflows/release.yml (excerpt)

- name: Sign release artifacts with minisign
  run: |
    key_file="${RUNNER_TEMP}/openlogi-minisign.key"
    echo "$OPENLOGI_UPDATE_MINISIGN_SECRET_KEY" | base64 -d > "$key_file"
    minisign -S -m "$artifact" -s "$key_file" -x "$artifact.minisig" -W
    # Verify during CI to ensure the signature is correct

    minisign -V -m "$artifact" -P "$OPENLOGI_UPDATE_MINISIGN_PUBLIC_KEY" -x "$artifact.minisig"

The workflow embeds the base64-encoded public key into the binary via the OPENLOGI_UPDATE_MINISIGN_PUBLIC_KEY environment variable, ensuring the distributed application can only verify updates signed by the corresponding private key.

Signature Verification Tests

The project includes automated tests in xtask/src/commands/release/latest_json/tests.rs that verify each DMG artifact carries a valid minisign signature, preventing regression in the update verification pipeline.

Security Design Philosophy

OpenLogi’s updater implements a fail-closed security model that prioritizes safety over convenience.

Fail-Closed Behavior

If the public key is missing—such as in local development builds where OPENLOGI_UPDATE_MINISIGN_PUBLIC_KEY is unset—the updater returns an error from the check call rather than installing an unverified artifact. This design prevents accidental distribution of unsigned builds while allowing developers to run the application without a key. The strict verification mode ensures that any failure in the cryptographic verification chain halts the update process immediately.

Supply Chain Protection

By embedding the public key at compile time rather than fetching it during update checks, OpenLogi eliminates the risk of key substitution attacks. The verification happens entirely within the compiled binary using the gpui_updater crate’s minisign implementation, creating a closed trust loop between the build system and the end-user’s application.

Summary

  • Minisign update verification in OpenLogi combines SHA-256 integrity checks with Ed25519 signature verification to authenticate release artifacts.
  • The public key is embedded at compile time via OPENLOGI_UPDATE_MINISIGN_PUBLIC_KEY and referenced in crates/openlogi-desktop/src/platform/updater.rs through the MINISIGN_PUBLIC_KEY constant.
  • The updater operates in Verification::Strict mode, configuring the EngineConfig with minisign_public_key() to enforce signature validation.
  • Release artifacts are signed in .github/workflows/release.yml using the minisign private key, with signatures stored alongside binaries as *.minisig files.
  • The system fails closed: missing or invalid signatures prevent installation, protecting users from unsigned or tampered updates.

Frequently Asked Questions

What happens if OpenLogi cannot verify the minisign signature during an update?

If signature verification fails, the updater returns an error and refuses to install the artifact. In strict verification mode, which OpenLogi uses by default, any mismatch between the downloaded file and the expected signature—or a missing signature file—causes the update check to fail completely rather than falling back to unverified installation.

How is the minisign public key distributed to OpenLogi users?

The public key is baked into the binary at build time through the OPENLOGI_UPDATE_MINISIGN_PUBLIC_KEY environment variable. This compile-time embedding ensures users receive the key as part of the application itself, eliminating network-based trust assumptions and preventing attackers from substituting verification keys during update checks.

Can developers run OpenLogi without configuring the minisign public key?

Yes, but with limitations. The minisign_public_key() function returns None when the environment variable is unset or empty, which typically occurs in local development builds. However, because the updater runs in strict verification mode, attempting to check for updates without the embedded key will result in an error. Developers can run the application, but the update mechanism will refuse to install unverified artifacts.

Where can I find documentation about the minisign signing process for OpenLogi releases?

The signing workflow and public key management are documented in docs/DEVELOPMENT.md under the "Release updater publishing" section. Additionally, the implementation details are visible in crates/openlogi-desktop/src/platform/updater.rs for the client-side verification logic and .github/workflows/release.yml for the CI signing automation.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →