Operate

Security

How Omnesis protects the data on your machines: encryption at rest and its recovery code, the security checks omnesis doctor runs, running the gateway under a dedicated account, and what happens to the gateway's TLS certificate after setup. It is for whoever installs and looks after the gateway. Choosing a certificate in the first place is covered in Setup → Certificates.

Use at your own risk. You are responsible for securing the environment where you run Omnesis, including your devices, operating systems, networks, credentials, and backups. Omnesis cannot guarantee the security of your data on a compromised system. To the extent permitted by applicable law and subject to the LICENSE, the authors and contributors disclaim liability for data loss, disclosure, or compromise caused by malicious actors, malware, viruses, or an insecure environment.

Encryption at rest

With encryption at rest, the databases, stored credentials and backups in the configuration directory are encrypted. Everything hangs off one root key per machine, held by the operating system's keyring (macOS Keychain or Linux Secret Service) or sealed with a passphrase you supply. If the root key cannot be read, the gateway and collector refuse to start rather than open data unencrypted. The installer offers encryption on a fresh install; this section covers turning it on later, headless machines, and recovery.

Turn it on

omnesis secure is the guided path. It inspects the install, takes a backup (through the running gateway, or an offline copy), creates the root key, prints a recovery code, encrypts the secret files that already exist, prepares the keys each store is opened with, and restarts the gateway or tells you to. On a machine that only runs a collector there are no gateway databases, so it prepares the collector's keys and restarts the collector instead.

It works out the machine's role from the configuration directory; --host gateway, --host collector or --host all overrides that, for example when the gateway's database lives elsewhere. --dry-run prints the plan without changing anything. When the gateway was not running, the backup is an offline snapshot of the database files; --rollback --yes, run with the gateway stopped, puts that snapshot back if the database step went wrong. A backup taken through the running gateway is restored with omnesis restore instead (see Restore).

❯ omnesis secure --dry-run

❯ omnesis secure

The steps it runs are also available one by one:

Headless machines: the passphrase backend

A server or container with no desktop keyring uses the passphrase backend: set OMNESIS_SECRET_STORE=passphrase and supply a passphrase at every start. Keyring entries are then sealed on disk under a key derived from it, and the passphrase itself is never stored. There are three ways to supply it:

Source How Use for
systemd credential omnesis service install --secret-store passphrase --keyring-passphrase-credential <abs-path> adds a LoadCredential=omnesis-keyring-passphrase line to the unit Linux services (systemd 247 or newer; older versions ignore the line and the daemon starts without its passphrase)
File OMNESIS_KEYRING_PASSPHRASE_FILE, or --keyring-passphrase-file <abs-path> on service install and the installer macOS services, containers, a fresh headless install
Environment OMNESIS_KEYRING_PASSPHRASE A process you start by hand

Keep the passphrase file owner-only: systemd reads a credential whatever its mode, but any local account can read a world-readable file. For a credential tied to this machine's TPM, encrypt the file with systemd-creds encrypt first. When the configuration directory already uses an OS keyring, service install detects it and needs no flag. omnesis doctor warns about a unit that selects the passphrase backend without naming a passphrase, which would otherwise fail later on the first encrypted store.

Recovery code

Losing the root key means losing every encrypted store and every encrypted backup made with it. omnesis keyring export-recovery writes a recovery envelope into the configuration directory and prints a one-time recovery code. Keep the code somewhere other than this machine. On a new machine, omnesis keyring import-recovery rebuilds the root key from the envelope and the code. omnesis restore --code does the same while restoring a backup, using the envelope the backup carries (see Restore). Backups never contain the root key itself.

❯ omnesis keyring export-recovery

Collectors on other machines

A collector on another machine has its own root key and its own store keys; pairing gives it a gateway credential, never the gateway's keys. The installer's collector role runs omnesis keyring init and omnesis keyring storage-init --host collector, so a fresh collector opens its encrypted stores (such as the WhatsApp archive and the iMessage transcript cache) without a gateway on its machine.

When encryption is on and the root key cannot be read, the collector refuses to start and names the fix. Restore or unlock a missing key rather than deleting files to get past the error: a bank connection's saved session, for example, may hold history the bank will not provide again.

What encryption at rest does not cover

Some imports work on short-lived plaintext copies: browser-history and Screen Time snapshots, and WhatsApp backup imports, use temporary SQLite files in owner-only folders. They are removed when the operation finishes, fails or is cancelled; a killed process can leave them until a later operation cleans up. Deleting a file is not secure erasure.

The source originals Omnesis reads, logs, filesystem snapshots and swap are outside Omnesis's control. Full-disk encryption (FileVault on macOS, LUKS on Linux) remains what protects a machine that is stolen while powered off. The vector index file is a rebuildable cache; with encryption on, Omnesis keeps an encrypted copy of it so a restart does not rebuild it.

Security checks

omnesis doctor checks this host's security posture by default. The checks are local and read-only, so they run even when the gateway is down; --no-security skips them. On a collector the same checks describe the collector's own stores and service.

Check What it looks at
Permissions The configuration directory and its files are owner-only. Repair drift with omnesis doctor --fix-permissions.
Full-disk encryption Whether FileVault or LUKS is on, or could not be confirmed.
Service hardening Whether the installed service units carry the expected restrictions.
Gateway isolation Whether the gateway runs as your login user or a dedicated account.
Keyring Whether the root key exists and can be read, and whether each service unit is wired to the backend it names.
Recovery code Whether a recovery envelope has been exported, and whether it is intact.
Store encryption Whether each database or provider store is encrypted, still plaintext, or locked.

--fix-permissions keeps directories and managed executables owner-only and restricts other files to owner read and write. The portal's Debug → Doctor page shows the same checks but cannot repair anything.

Hardened gateway

By default both daemons run as your login user. Owner-only file modes keep other OS accounts out, but not other programs running as you: any of them can read the gateway's databases. On Linux with systemd, the gateway can instead run as a dedicated account that systemd allocates each time it starts (DynamicUser=), with all of its state (databases, index, certificate, tokens, models) under /var/lib/omnesis-gateway, unreadable by your account.

That separation holds only if your account also cannot change the code the gateway runs. So root fetches a release, builds it and installs it under /opt/omnesis-gateway, where only root can write. A program running as you can then neither read the corpus nor alter the code that reads it. Root still can, and anyone who compromises the gateway process holds what the gateway holds. On a single-user machine where nothing untrusted runs under your account, the default services are a reasonable choice.

Hardened mode needs Linux with systemd. macOS has no equivalent: run the gateway as your user, or in Docker, which separates it from your other programs in a different way. Collectors never move to the dedicated account and never run as root, because they read your data with your permissions; a Mac collector pairs with a hardened Linux gateway over the network like any other collector.

Installing

On a Linux host run by systemd, an interactive install of a new gateway asks which account should run it; --hardened and --no-hardened answer that for an unattended install. The dedicated account installs the CLI as you and prints one command to run as root; the installer never runs sudo itself. omnesis service install gateway --hardened prints the same command.

❯ omnesis service install gateway --hardened

The dedicated gateway runs from a copy of Omnesis that root fetches and owns, so
installing it takes one command as root:

  curl -fsSL https://omnesis.dev/hardened-gateway.sh | sudo sh -s -- install --version X.Y.Z

Run as root, that command:

  1. fetches the release with git hooks disabled (reading a token from your git credential helper if the repository needs one);
  2. hands over to that release's own copy of the script, so the release decides how it is built;
  3. builds it as a throwaway account that can reach neither home directories nor the rest of the system;
  4. installs the result, root-owned, under /opt/omnesis-gateway/releases;
  5. puts the passphrase that seals the gateway's keys in /etc/omnesis-gateway/keyring.pass, readable only by root, then installs and starts omnesis-gateway.service.

It needs git and a Node 24 that only root can change, such as your distribution's under /usr; a Node installed in a home directory (through nvm, for example) is refused. --no-keyring installs without encryption at rest, and --keyring-passphrase-file uses your own passphrase, which root copies into /etc/omnesis-gateway. --port sets the gateway's port.

It is a new gateway, never your existing one moved: devices pair with it again and sources sync into it again, and nothing in ~/.config/omnesis is copied or removed. So --hardened is refused while a gateway service of yours is registered (remove it first with omnesis service uninstall gateway), and together with --docker, the client and collector roles, an agent-harness install, --no-service and --mkcert, each with its reason. The dedicated gateway serves its own self-signed certificate; for a browser-trusted address put a reverse proxy in front of it (see Setup → Certificates).

Administering

Administer it with omnesis-gateway-admin, linked into /usr/local/sbin. Its cli command runs the installed release's omnesis as root against the gateway's state, address and keyring, so nothing from your account runs as root. After installing, export a recovery code, install a model, and pair this machine's collector, which stays under your account and pairs with a code like a collector on another machine:

# as root, against the dedicated gateway

❯ sudo omnesis-gateway-admin cli keyring export-recovery --backend passphrase

❯ sudo omnesis-gateway-admin cli model install <model-id>

❯ sudo omnesis-gateway-admin cli devices pair --kind collector

❯ sudo omnesis-gateway-admin cli tls status

# as you: this machine's collector

❯ curl -fsSL https://omnesis.dev/install.sh | sh -s -- --collector --gateway-url https://localhost:7600 --trust-fingerprint sha256:<fingerprint> --code <code>

tls status shows the fingerprint the collector's command confirms. Inspect the service with sudo systemctl status omnesis-gateway and journalctl -u omnesis-gateway; omnesis service status covers only your user services. The unit is readable only by root, so run sudo omnesis doctor to include it in the checks.

The keys reach the gateway as a systemd credential: the unit names /etc/omnesis-gateway/keyring.pass, which systemd reads as root and hands to this service alone. Before the first start the unit creates the root key, so the stores are encrypted from the beginning; a key the passphrase cannot open stops the start. Keep the passphrase file. Without it, the stores open again only by restoring the key from the recovery code and the recovery envelope in the state directory.

Updating and removing

omnesis update updates your CLI and collector and prints the root command that moves the dedicated gateway to the same release. sudo omnesis-gateway-admin update --version X.Y.Z builds the new release beside the running one, takes a backup through the gateway, switches to the new release, restarts the service and waits for the new version to answer. If it does not, it switches back and prints the commands that list and restore backups, in case the new release already migrated the data. --no-backup switches without a backup. It refuses a release older than the running one unless you pass --force.

sudo omnesis-gateway-admin rollback switches back to the previous release, and sudo omnesis-gateway-admin status shows both. sudo omnesis-gateway-admin uninstall removes the service and the releases but keeps the state directory and the passphrase that opens it. Running the install command on a dedicated gateway whose unit runs code from a login account moves it onto a root-owned release, keeping its port, state and passphrase.

TLS certificate

The gateway always serves HTTPS, with the certificate chosen at setup: a Tailscale certificate, an mkcert one, one you provide, or the self-signed pair the gateway creates on first start. This section covers what happens afterwards: renewal, how a new certificate goes live, and what clients that pinned the old one need.

Renewal and activation

Renewing writes a new certificate to the files the gateway reads; activating starts serving it. The gateway activates on its own: once an hour it re-reads the certificate and key, checks that they parse, match and are within their validity dates, and if they differ from what it serves, switches to them without a restart. omnesis tls reload does this immediately. A replacement that fails the checks is reported and ignored, and the previous certificate stays in use.

The gateway renews the certificates it created: the self-signed pair, the Tailscale certificate and the mkcert certificate. From 30 days before expiry it creates a new one of the same kind (through openssl, tailscale cert or mkcert), checks it and activates it.

Any other certificate you point the gateway at through OMNESIS_TLS_CERT and OMNESIS_TLS_KEY is checked and reported but never renewed or overwritten: renew it with the tool that issued it, into the same files, and the gateway picks it up. A gateway in Docker renews only its self-signed pair; a Tailscale or mkcert certificate is renewed on the host, by re-running its issuer into the same file. gateway.tls.autoRenew: false turns automatic renewal off and gateway.tls.renewBeforeDays moves the threshold; omnesis tls renew renews on request, and --force renews one that is not yet due. omnesis update never renews certificates.

❯ omnesis tls status

Certificate  expiring
  ownership    Tailscale, minted by Omnesis
  certificate  /home/maya/.config/omnesis/tls/tailscale.crt
  fingerprint  sha256:4f1c…9be2
  valid until  2026-10-02T09:14:00.000Z (18 days remaining)
  names        studio.tail-example.ts.net
  renewal      automatic, 30 days before expiry
  last attempt 2026-09-14T03:00:12.000Z failed: `tailscale cert` failed: HTTPS is not enabled for this tailnet

omnesis doctor reports the same facts: a certificate inside its renewal window is a warning, an expired one a failure, and each names the command to fix it. A certificate that does not cover a name the gateway is reached by (the gateway URL, the public address, a pairing address) is also a warning, because clients using that name will refuse it; the fix is a new certificate, not weaker verification.

The self-signed certificate lasts ten years but covers only the network addresses the host had when it was created. After those change, omnesis tls renew --force recreates it with the current ones. A Tailscale or mkcert certificate that no longer covers the address you use is recreated with omnesis tls refresh (add --mkcert for mkcert), which also activates it in the running gateway when it can reach it.

Behind a reverse proxy that terminates TLS, clients see the proxy's certificate, renewed by the proxy's own tooling. omnesis tls status then describes the gateway's own certificate on the hop from the proxy, and lists the public name as served by the proxy.

Clients that pinned the old certificate

A renewed certificate has a new fingerprint, which matters to clients that pinned the old one. The gateway never drops a pin on a client's behalf.