Skip to content

Encryption

When you use Omnodex’s cloud features (Hosted tier and above), your data is protected by end-to-end encryption. This means the Omnodex service never has access to your unencrypted activity. The metadata it can read is listed in What Omnodex Can See.

Each data stream has a stream secret (called the sync passphrase in earlier versions). omnodex connect generates one as six random words, or you supply your own with --secret. It is used to derive an encryption key on your machine using Argon2id (a memory-hard key derivation function). Events are encrypted with AES-256-GCM before leaving your machine, and only ciphertext of your activity is transmitted and stored in the cloud.

When you sign in to the hosted dashboard, your browser retrieves your encrypted key material and decrypts it locally using your account password. The server never sees your stream secret or encryption keys in plaintext.

Omnodex uses a layered key-wrapping architecture inspired by Bitwarden’s:

  1. Stream secret: one per data stream. It is used by the CLI to derive the encryption key for that stream’s events.
  2. Master wrap key: a random 256-bit key generated during account registration. It encrypts your stream secrets so they can be stored server-side (as ciphertext).
  3. Wrap key: derived from your account password + a per-user salt using Argon2id. It encrypts the master wrap key. This is how your password unlocks your stream secrets without the server knowing any of them.
  4. Recovery wrap key: derived from a one-time recovery key shown at registration. It independently encrypts the same master wrap key, providing a backup path if you forget your password.

The server stores only the encrypted forms (ciphertext + IV) of the master wrap key and stream secrets. At no point does it hold plaintext keys or stream secrets.

Each account connected to a stream holds its own wrapped copy of that stream’s secret. Removing a stream from your account deletes your copy; the stream and other accounts’ copies are unaffected.

Omnodex uses Argon2id for all key derivation, the current best-practice algorithm for password-based key derivation. It is memory-hard (resistant to GPU and ASIC attacks) and tuned for security while remaining fast enough for interactive use.

The derived keys are used for AES-256-GCM authenticated encryption.

For live streaming (real-time event relay), a separate streaming key is derived using a two-stage process:

  1. Master key: Argon2id with the same stream secret but a fixed streaming-specific salt (~275ms, computed once per session)
  2. Streaming key: HKDF-SHA256 with the master key and your customer ID as context (sub-millisecond)

This ensures the streaming key and sync blob key are cryptographically independent even though they derive from the same stream secret. Each encrypted event frame includes a key_id (truncated hash of the key) so the browser can verify it’s using the correct key.

A Cowork cloud task runs in a container that never holds your stream secret. Its plugin seals each event with HPKE (RFC 9180: X25519, HKDF-SHA256 and AES-256-GCM) to your stream’s public key, so it can add events to your stream but cannot read any. The server stores the stream’s private key wrapped under another key derived from your stream secret, and your browser unwraps it to read those events.

So that a stream is never switched to a different secret by accident, the server keeps a one-way check value for each stream’s secret. Your machine and your browser both derive it from the secret: the same Argon2id master key as above, then HKDF-SHA256 with its own label (omnodex-stream-verifier-v1). It cannot be turned back into the secret or into any encryption key, and guessing a secret from it costs the same Argon2id work as guessing it from encrypted data. No endpoint returns it.

The server compares the check value when an account connects or reconnects a stream, when a machine is authorized again, and on a machine’s first sync with a given token and secret, and refuses one that does not match. After the stream’s owner rotates the token, a machine proves it holds the secret with the same value to collect the new token. A leaked token alone is not enough.

Every account connected to a stream holds the secret, so it can derive the check value too. The check protects against mistakes and leaked tokens, not against someone the stream’s owner chose to share the stream with.

  • If you lose both your password and recovery key, your cloud data is unrecoverable. We cannot reset it, decrypt it, or help you access it. This is by design.
  • We cannot comply with data requests for your content because we do not have the ability to decrypt it.
  • A breach of our cloud infrastructure would expose only ciphertext: encrypted blobs that are computationally infeasible to decrypt without your credentials.
DataEncrypted?
Event payloads (tool calls, parameters, results)Yes
Session details (start and end, working directory, repository)Yes
Detection findingsYes
Account finding policyYes, one copy per data stream
Stream secrets (stored in account)Yes (wrapped by master key)
Stream secret check valueOne-way derived value, not encrypted; reveals nothing usable
Account email / billing infoNo (needed for service operation)
Machine label, stream names, connection link detailsYes, under the stream secret
Machine ID (random), upload sizes and timesNo, see What Omnodex Can See
Usage metrics (event counts)No (needed for billing)

The hosted dashboard decrypts data in your browser. When you sign in, your browser derives the wrap key from your password, decrypts the master wrap key, then uses that to decrypt your stream secrets. From there, each stream secret is used to derive the decryption key for your event data. The decryption keys are never sent to the server.

When you change your password, the dashboard re-encrypts the master wrap key under a new wrap key derived from your new password. Your stream secrets and event data are unaffected; only the wrapping layer changes.

If you forget your password, enter your recovery key to regain access. The recovery key independently decrypts the master wrap key, allowing the dashboard to re-encrypt it under a new password. If you have lost both your password and recovery key, your encrypted data is permanently inaccessible.