# Minisign Update Verification in OpenLogi: Purpose and Implementation

> OpenLogi employs minisign update verification to ensure downloaded updates are authentic and unaltered. Learn how this ensures your software integrity.

- Repository: [Xuan Zhang/OpenLogi](https://github.com/AprilNEA/OpenLogi)
- Tags: internals
- Published: 2026-08-26

---

**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`](https://github.com/AprilNEA/OpenLogi/blob/main/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:

```rust
// 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)`:

```rust
// 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`](https://github.com/AprilNEA/OpenLogi/blob/main/.github/workflows/release.yml), the release pipeline signs each artifact using the minisign private key stored in repository secrets:

```yaml

# .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`](https://github.com/AprilNEA/OpenLogi/blob/main/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`](https://github.com/AprilNEA/OpenLogi/blob/main/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`](https://github.com/AprilNEA/OpenLogi/blob/main/.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`](https://github.com/AprilNEA/OpenLogi/blob/main/docs/DEVELOPMENT.md) under the "Release updater publishing" section. Additionally, the implementation details are visible in [`crates/openlogi-desktop/src/platform/updater.rs`](https://github.com/AprilNEA/OpenLogi/blob/main/crates/openlogi-desktop/src/platform/updater.rs) for the client-side verification logic and [`.github/workflows/release.yml`](https://github.com/AprilNEA/OpenLogi/blob/main/.github/workflows/release.yml) for the CI signing automation.