Security and update integrity
Updated · 6 min read · For IT and security, developers
This page is for IT, security reviewers and developers. It explains how an update is protected from upload to install: each app signs its file list with its own Ed25519 key, the installer checks that signature and every file’s SHA-256 before it changes anything, and channel access, API keys and workspace isolation limit who can publish or download.
How an update is protected end to end
An installed copy of your app installs only files that your app’s key signed. Here is the chain, from upload to the user’s disk:
The server builds a signed file list
When a build finishes processing, the server writes a manifest: every file’s path, size and SHA-256 hash. It signs the manifest with the app’s private Ed25519 key.
The installer knows the public key
The app’s public key is built into its installer when the installer is compiled. The installer does not download the key, so a compromised download path cannot swap it.
The installer verifies the signature first
On every update check the installer verifies the manifest’s signature against that built-in key before it reads the file list. A bad signature stops the update.
Each file is checked by hash
Files download to a temporary folder. Each one must match the SHA-256 in the signed manifest. One mismatch stops the update and the temporary files are deleted.
The apply is all or nothing
The installer renames the current files to backups, moves the new files in, and removes the backups only when every file is in place. If anything fails, it restores the backups. A user never ends up with half an update.
Download links are short-lived, signed URLs. They are requested only when a download starts, and only for files that the channel’s current build lists. The links themselves are not trusted: the hash check above decides whether a file is used.
Signing keys
- Each app has its own Ed25519 key pair, created with the app. A key never signs another app’s updates.
- The private key stays on the server and is stored encrypted. The platform can keep it under AWS KMS encryption or under its own master key.
- You can copy the app’s public key from the app’s Settings tab, for example to verify a manifest yourself.
For background on why update signing matters, read How to sign desktop app updates.
Path safety on the user’s machine
A signed manifest still cannot write outside the install folder. The server refuses unsafe file names at upload, and the installer checks every path again before downloading anything. It refuses absolute paths, drive letters, network and device paths, .. segments, backslashes, colons, control characters, Windows reserved names such as CON or NUL, duplicates, and the installer’s own .omni-installer folder. One unsafe path refuses the whole update.
Uninstall is limited the same way. By default it removes only the files the installer wrote, which it records in a list after each update. It never deletes system folders or the user profile folders themselves, such as Windows, Program Files, AppData, Desktop or Documents.
Who can download updates
| Channel access | How it is checked | How it is stored |
|---|---|---|
| Public | Anyone with the app id and channel name | Nothing secret |
| Private with tokens | The request carries a channel token | Only a SHA-256 hash of the token; the token is shown once |
| Private with a password | The request carries the channel password | Only an argon2id hash of the password |
Revoking a token takes effect on the next request. The channel page keeps an access log of successful update checks on private channels. An installer built for a private channel carries that channel’s token, so anyone who has that installer can use the channel. Share it like a credential.
Who can publish builds
- Dashboard sign-in uses a one-time email link that expires after 15 minutes. There are no passwords to leak.
- CI API keys belong to one app and can only publish builds to it. The server stores a SHA-256 hash of each key and shows its first characters so you can tell keys apart. Each key is rate-limited, and revoking it takes effect on the next request. Only a workspace owner or admin can create or revoke keys.
- Workspace roles limit app deletion, billing, API keys and member management to owners and admins. Team invites are not available yet, so today a workspace has one member.
Isolation between workspaces
Identical files are stored once, but access is per workspace. When you upload, the server says a file already exists only if your own workspace uploaded it before. Knowing another customer’s file hash does not let you put their file in your build or get a download link for it. The server also decides every storage location itself and never trusts a path sent by the browser or CI.
The public update service that installers talk to reads only app, channel and build data. It has no access to the database that holds user accounts and billing.
Malware scanning of uploads
The build pipeline has a malware scan step that checks each uploaded file with ClamAV and fails the build on a hit. It is a platform setting and is not switched on in every environment yet. Do not rely on it in place of scanning your own builds before you upload them.
What data Omnihorn stores
| Data | What it contains |
|---|---|
| Your account | Email, name, workspace name, plan, and the legal versions you accepted |
| Your builds | The files you upload, their hashes, versions, release notes and CI source details such as branch and commit |
| Install events | Install, update, uninstall and failure events with a random per-installation id, app build, platform, OS version and, where known, country. No user names or emails |
| Channel access log | For each successful check on a private channel: time, channel, token used, installation id, platform and whether an update was offered |
| Uninstall feedback | An optional reason and short note, sent without a name or email |
Omnihorn staff use an internal admin site to support customers. It is reachable only from a private network, and staff actions on workspaces are recorded in an internal audit log. For the legal terms, read the Privacy Policy, the Data Processing Addendum and the Acceptable Use Policy.
What is not covered yet
- Installers are not code-signed yet. Until a code-signing certificate is configured, Windows SmartScreen shows an unknown-publisher warning for
setup.exe. Update files are still verified by the app’s own signature. See the SmartScreen post. - No independent audit. The update chain has not been reviewed by an outside security firm, and Omnihorn holds no security certifications.
- Channel credentials on the PC. A token or password typed into the installer’s channel dialog is saved in the installer’s per-user settings, not in Windows Credential Manager.
- No single sign-on. Dashboard sign-in is by email link only.
›What happens if someone tampers with an update file in storage?
The installer refuses it. Every file must match the SHA-256 in the manifest, and the manifest must carry a valid signature from the app’s key. The update stops and the installed files stay as they were.
›Can Omnihorn staff publish a build to my app?
The signing key is held on the platform, so the platform can sign. The staff admin site offers no action to publish builds; it can suspend an app or revoke a build.
›Is the installer signed?
Not yet. Code signing of setup.exe is built but no certificate is configured, so SmartScreen warns. Updates are protected by the per-app Ed25519 signature regardless.
›Do you have SOC 2 or ISO 27001?
No. Omnihorn holds no security certifications and has not had an independent audit. This page describes the controls that exist in the product.
Keep reading
Something wrong or missing? Tell us.