# How OpenLogi Ensures DMG Integrity Using Minisign Signatures in the Release Updater

> Learn how OpenLogi uses minisign signatures in its release updater to guarantee DMG integrity. Discover the build-time key embedding and runtime verification process for secure artifact validation.

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

---

**OpenLogi's release updater verifies DMG integrity by embedding a base64-encoded minisign public key at build time and enforcing strict signature verification at runtime using the `minisign-verify` crate, rejecting any artifacts that fail cryptographic validation.**

The AprilNEA/OpenLogi repository implements a secure macOS update mechanism through the **gpui-updater** crate, ensuring that every DMG artifact distributed to users is cryptographically signed and verified before installation. This design leverages the **minisign** signature scheme to protect against tampered binaries, with the public key injected during the CI build process and enforced through strict verification policies at runtime.

## Build-Time Public Key Embedding

The foundation of OpenLogi's security model relies on compile-time embedding of the minisign public key, ensuring the key is immutable once the binary is distributed.

### 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) (lines 28-31), the public key is captured from the build environment using Rust's `option_env!` macro:

```rust
/// Base64 minisign public key, embedded at build time by the release workflow.
const MINISIGN_PUBLIC_KEY: Option<&'static str> =
    option_env!("OPENLOGI_UPDATE_MINISIGN_PUBLIC_KEY");

```

This constant reads the `OPENLOGI_UPDATE_MINISIGN_PUBLIC_KEY` environment variable provided by the CI pipeline. For local development builds where this variable is absent, the constant resolves to `None`, triggering a fail-closed behavior that prevents unverified updates.

### Runtime Key Retrieval

The `minisign_public_key()` function (lines 72-78 in the same file) handles the extraction of the embedded key:

```rust
fn minisign_public_key() -> Option<String> {
    MINISIGN_PUBLIC_KEY.map(|s| {
        s.trim().to_string()
    })
}

```

This function returns `None` for development builds or the trimmed, base64-decoded public key string for release binaries built in CI.

## Runtime Verification Architecture

The updater configures strict verification policies that mandate both SHA-256 manifest checksums and minisign signature validation before any DMG can be installed.

### Engine Configuration with Strict Verification

When initializing the updater, the code constructs an `EngineConfig` with `Verification::Strict` enforced. As implemented in [`crates/openlogi-desktop/src/platform/updater.rs`](https://github.com/AprilNEA/OpenLogi/blob/main/crates/openlogi-desktop/src/platform/updater.rs) (lines 64-70):

```rust
let mut config = EngineConfig::new(version).verification(Verification::Strict);
if let Some(key) = minisign_public_key() {
    config = config.minisign_public_key(key);
}
let updater = Updater::new(source, config, cx);

```

The `Verification::Strict` setting requires both manifest integrity checks and cryptographic signature verification. The configuration is enriched with `minisign_public_key(key)` only when a valid key is present, ensuring production builds enforce signature validation while development builds fail safely.

### Signature Verification Flow

At runtime, the updater executes a four-step verification sequence:

1. **Manifest Retrieval**: Downloads the static [`latest.json`](https://github.com/AprilNEA/OpenLogi/blob/main/latest.json) manifest that lists the appropriate artifact for the current OS/architecture combination.
2. **Artifact Download**: Retrieves both the DMG file and its companion `.minisig` signature file.
3. **Cryptographic Verification**: Calls the **minisign-verify** library to validate that the DMG's signature matches the embedded public key.
4. **Conditional Exposure**: Only exposes the update to the user or proceeds with auto-installation after successful verification.

If the public key is missing—which occurs in local development builds—the updater returns an error immediately, preventing any unverified artifact from reaching the user.

## CI/CD Signing Process

The integrity guarantee depends on the signing process executed during the release workflow, defined in [`.github/workflows/release.yml`](https://github.com/AprilNEA/OpenLogi/blob/main/.github/workflows/release.yml) (lines 274-275).

### Minisign Signing Commands

The CI pipeline signs each artifact using the minisign private key stored as a secret, then immediately verifies the signature using the public key:

```bash

# Sign the artifact (e.g., the .dmg file)

minisign -S -m "$artifact" -s "$key_file" -x "$artifact.minisig" -W

# Verify immediately to fail the job if signing is invalid

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

```

The `-S` flag initiates signing, `-m` specifies the message (artifact) file, `-s` provides the private key path, and `-x` outputs the signature file. The subsequent verification step ensures that any corruption or signing errors are caught before the release is published.

### Public Key Injection

The `OPENLOGI_UPDATE_MINISIGN_PUBLIC_KEY` environment variable is injected into the build environment during the CI workflow, ensuring that release binaries contain the correct public key for future verification of updates.

## Security Guarantees and Fail-Closed Design

OpenLogi's updater implements a **fail-closed** security posture. When the `minisign_public_key()` function returns `None`—as it does in builds where the environment variable is not set—the updater cannot construct a valid verification configuration. This prevents the installation of any artifact that lacks a valid minisign signature, protecting users from:

- Man-in-the-middle attacks during download
- Compromised release artifacts
- Accidental installation of development or test builds in production

According to the source code in [`crates/openlogi-desktop/src/platform/updater.rs`](https://github.com/AprilNEA/OpenLogi/blob/main/crates/openlogi-desktop/src/platform/updater.rs), this design ensures that only releases signed with the trusted minisign key distributed through the official CI pipeline can be applied to user systems.

## Summary

- OpenLogi embeds a base64-encoded minisign public key at compile time via the `OPENLOGI_UPDATE_MINISIGN_PUBLIC_KEY` environment variable, stored in 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).
- The `minisign_public_key()` function extracts this key for production builds while returning `None` for local development builds.
- The updater configures `EngineConfig` with `Verification::Strict` and registers the public key via `config.minisign_public_key(key)` to enforce cryptographic verification.
- The **minisign-verify** crate validates DMG artifacts against their `.minisig` companions before exposing updates to users.
- The CI workflow in [`.github/workflows/release.yml`](https://github.com/AprilNEA/OpenLogi/blob/main/.github/workflows/release.yml) signs artifacts using `minisign -S` and verifies them immediately with `minisign -V` before distribution.
- The system fails closed when verification is impossible, ensuring unverified artifacts cannot be installed.

## Frequently Asked Questions

### What happens if the minisign public key is not embedded in the binary?

If the `OPENLOGI_UPDATE_MINISIGN_PUBLIC_KEY` environment variable is absent during the build process, the `MINISIGN_PUBLIC_KEY` constant resolves to `None` and the `minisign_public_key()` function returns `None`. In this scenario, the updater cannot complete strict verification and returns an error, preventing the installation of any unverified DMG artifacts. This fail-closed behavior protects users from installing potentially compromised updates in development environments.

### Which files are involved in the signature verification process?

The verification process involves three components: the DMG artifact itself (e.g., `OpenLogi-1.0.0.dmg`), the detached signature file with the `.minisig` extension (e.g., `OpenLogi-1.0.0.dmg.minisig`), and the embedded public key constant in the binary. The updater retrieves both the DMG and its `.minisig` companion from the release source, then uses the **minisign-verify** library to validate that the signature was created with the private key corresponding to the embedded public key.

### Where is the minisign signing implemented in the CI pipeline?

The signing logic resides in [`.github/workflows/release.yml`](https://github.com/AprilNEA/OpenLogi/blob/main/.github/workflows/release.yml) at lines 274-275. The workflow executes `minisign -S` to sign each artifact with the private key stored in repository secrets, followed immediately by `minisign -V` to verify the signature against the `OPENLOGI_UPDATE_MINISIGN_PUBLIC_KEY` variable. This ensures that only properly signed artifacts are attached to GitHub releases and distributed to users.

### How does the updater handle signature verification failures?

When the **minisign-verify** library detects a signature mismatch, invalid signature format, or missing signature file, the verification returns an error before the DMG is exposed to the user or installed automatically. Because the `EngineConfig` uses `Verification::Strict` mode, any cryptographic validation failure halts the update process entirely, ensuring that only artifacts passing both SHA-256 checksum validation and minisign signature verification can be installed on macOS systems.