Skip to content

Zero-Knowledge Fitness Tracking: How VitaLog Actually Protects Your Data

Most fitness apps say "your data is encrypted." Few can say "even we can't read it." VitaLog is in the second category, here's exactly how, and what it means for you.

TL;DR. Progress photos are encrypted on your device with AES-256-GCM before they leave. The key is generated on your device and wrapped with a password-derived secret we never see. Our servers hold ciphertext that looks like random bytes. We cannot decrypt your photos, not for an ad partner, not for an engineer, not for a subpoena. We can decrypt nothing on our side because we fundamentally do not have the keys.

The problem

Fitness and health data is uniquely sensitive. Progress photos, weight, body composition, bloodwork, mood, sleep, nutrition, and supplement use: together they paint a picture of your private life most advertising platforms would pay a great deal to access. The dominant apps in the category have turned that access into their business model:

The failure mode isn't always malicious. It's that plaintext-on-server gives every party downstream (advertising integrations, law enforcement, insurance companies, future acquirers) the technical capability to read your data. Architecture is policy. An app that can read your data eventually will, either by compromise or by choice.

What zero-knowledge actually means

Zero-knowledge is a specific, testable property: the service provider holds no information capable of decrypting user data. Keys live only on client devices, encryption happens client-side before upload, and the server holds only ciphertext.

The test: if an attacker fully compromised our servers, could they read your photos? For a zero-knowledge system, the answer is no, they would have ciphertext and opaque metadata, but no key. The same test applies to a government subpoena, an acquisition by a less scrupulous company, or a rogue engineer. In all cases, the answer must be no.

"Encrypted at rest" is NOT zero-knowledge. Neon Postgres encrypts our database at rest, but Neon holds the decryption keys, so Neon can decrypt, we can request decrypted queries, and anyone who compromises Neon can decrypt. "Encrypted in transit" is NOT zero-knowledge either, TLS protects data as it travels but unencrypted data lives on the server once it arrives. Both are necessary but neither is sufficient.

Zero-knowledge adds a client-side encryption step before upload, where the key is a secret only your device holds.

How VitaLog implements it (photos)

When you enable photo cloud sync and upload a photo, the following happens entirely on your device:

  1. Compress. Your photo is resized to 800 px longest edge, re-encoded as JPEG at quality 0.7. No EXIF is persisted.
  2. Chunk. The compressed JPEG is sliced into 1 MB chunks. Each chunk is independent.
  3. Encrypt. Each chunk is encrypted with AES-256-GCM. A 12-byte IV is generated for each chunk (cryptographically random, never reused). The IV is prepended to the ciphertext. Authentication tag length is 128 bits.
  4. Upload. Each ciphertext chunk is PUT to a dedicated R2 URL like photos/{userId}/{photoId}/chunk-{i}. The server never sees the plaintext, the IV separately, or the encryption key.
  5. Commit. After all chunks are present, a final commit marks the photo as complete. The server verifies chunk presence and total byte count, both of which are visible metadata, but cannot verify anything about the content.

The encryption key itself is:

For OAuth accounts (Google, Apple sign-in) where we never have a password to derive from, you set a separate photo passphrase in Settings that plays the same role. The passphrase wraps the photo key; we hold only the wrapped form. Losing the passphrase loses cross-device photo access but not the account itself.

What is NOT zero-knowledge (and why)

For transparency: not every data path in VitaLog is end-to-end encrypted. Here's the honest breakdown:

DataEncryption modelWhy
Progress photosZero-knowledge (client-side AES-256-GCM, per-user key, server never holds key)Highest sensitivity; embarrassment + identification risk
Structured state (protocols, journal, bloodwork, workouts, nutrition, settings)Local-first by default. Cloud sync is TLS in transit + Neon Postgres encryption at restCloud sync is opt-in; the vault option wraps it client-side if you want full E2E
Account data (email, display name, password hash)TLS in transit; PBKDF2-hashed password; Neon at-rest encryptionRequired for authentication; zero-knowledge password auth (SRP, OPAQUE) is a possible future upgrade
Wrapped encryption keysStored on server but wrapped with PBKDF2(password), server has ciphertext onlyEnables roaming between devices after the user authenticates
Optional vault backupFull state AES-256-GCM wrapped under PBKDF2(password)Opt-in for users who want full state E2E-encrypted
Real-time sync notificationsOnly metadata, HLC timestamps, device labels, never state contentThe Durable Object fanout carries pointers, not payloads

Why not make every path zero-knowledge? Engineering tradeoff. Fully client-side search, trend detection, and compound-interaction analysis would slow the experience significantly for the average user. The photo path is where the worst-case exposure is most severe, so that's where we invested in the strictest guarantee. The structured-data path has less sensitive worst-case exposure and the opt-in vault feature serves users who want the full E2E model.

What "encrypted" usually means in fitness apps

Most fitness, nutrition, and workout apps describe themselves as "encrypted." In practice that usually means one of two postures, neither of which is zero-knowledge:

Both are necessary baseline hygiene. Neither answers the question "if an attacker fully compromised the servers, could they read user photos?" The answer for almost every plaintext-on-server app is yes.

Two encryption postures are worth specifically highlighting because they DO clear the bar:

VitaLog's positioning is not "we encrypt and they don't." It is: cross-platform (iOS, Android, Windows, macOS, Linux), pharmacology / peptide / bloodwork / interaction analysis that Apple Health doesn't provide, AND zero-knowledge encryption for the most-sensitive surface (progress photos) regardless of which platform the user is on.

What law-enforcement requests look like

If VitaLog receives a valid subpoena or warrant for a user's account, we can produce:

We cannot produce:

This is not a legal loophole or clever phrasing. It is architectural. The data is mathematically unavailable to us without the user's password or passphrase.

Why you can trust this claim

Architectural security claims are only believable if verifiable. VitaLog's are verifiable via:

If we ever weaken this model, for example by capturing decryption keys on the server, a visible code diff would show it. The architecture is the commitment.

Try VitaLog

Free. No ads. Zero-knowledge photos. Real-time multi-device sync. Everything client-side unless you explicitly opt into cloud sync.

Open VitaLog Live demo

Frequently asked questions

What does "zero-knowledge" actually mean?
Zero-knowledge means the service provider (in this case VitaLog) holds no information capable of decrypting your data. Keys live only on your device, the encryption happens before anything leaves your device, and the server stores only ciphertext. A server compromise, insider threat, or legal subpoena cannot produce plaintext because we fundamentally do not have it.
Is the entire app zero-knowledge?
Progress photos are zero-knowledge end-to-end. The rest of your state (protocols, journal, bloodwork, workouts, nutrition) is local-first by default, if you never enable cloud sync, nothing leaves your device. Optional cloud sync for that state uses TLS in transit and encryption at rest on our database (Neon Postgres). The separate opt-in vault feature encrypts that state with a PBKDF2-derived key from your password for full end-to-end protection. Photos are the strictest tier because they are the most sensitive.
How does VitaLog encrypt photos?
When you upload a photo: (1) client compresses to 800 px max, (2) slices into 1 MB chunks, (3) encrypts each chunk with AES-256-GCM using a unique 12-byte IV per chunk, (4) uploads ciphertext to Cloudflare R2 storage. The encryption key is 256-bit AES-GCM, generated on your device and stored in IndexedDB with "non-extractable" flag set. For password accounts the key is wrapped under PBKDF2(password, salt, 600,000 iterations) and the wrapped version is stored in our database, we store the wrapped key but cannot unwrap it without your password. For OAuth accounts, you set a separate photo passphrase that plays the same role.
Can VitaLog comply with a subpoena for photo content?
No, we are architecturally incapable of producing plaintext. We can produce only (a) the ciphertext chunks and (b) opaque metadata (photo ID, user ID, chunk count, upload date, user-chosen category label). The ciphertext is indistinguishable from random bytes without the decryption key. We can fulfill preservation orders and metadata requests but cannot decrypt the content.
What happens if I lose my password?
If your account is password-based and you have no other device with the cached key, you lose access to existing cloud-stored photos. The ciphertext remains in R2 storage, but there is no recovery path on our side because we never held the key. Account data not in photos (protocol, journal, bloodwork) is recoverable via password reset. If you are on an OAuth account and forget your photo passphrase, the same applies, only photo access is lost, not your account.
Does Apple Health protect my data?
Apple Health data on-device is protected by iOS data-protection APIs (encrypted with the device passcode). iCloud sync of Health data is end-to-end encrypted with your iCloud keychain. This is a strong privacy model for Apple-ecosystem users. VitaLog complements Apple Health with pharmacology, bloodwork, peptide tracking, and cross-device sync for Android + web that Apple Health doesn't cover. If you're iOS-only and want only Apple's standard features, Apple Health plus a simple tracker may be all you need; VitaLog serves the broader set of clinical-grade tracking use cases across platforms.
Why not make everything zero-knowledge?
Engineering tradeoff. Zero-knowledge requires client-side search, client-side trend detection, client-side all-the-things, which is feasible but slow for very large data sets. The progress-photo path is where plaintext-server-access has the worst consequences (identification, embarrassment, advertising exploitation), so that's where we invest in full zero-knowledge. The structured-data path (numbers, dates, labels) has less sensitive worst-case exposure. For users who want everything encrypted, the opt-in vault feature wraps the full state in client-side AES-256-GCM with a password-derived key.
What about sub-processors like Cloudflare and Neon?
Cloudflare R2 holds encrypted photo ciphertext, the encryption happens before upload, so Cloudflare sees random bytes. Neon Postgres holds account data, wrapped encryption keys, and structured state; data is encrypted at rest by Neon, in transit by TLS, and the vault-encryption option wraps it client-side before upload for strict zero-knowledge on the structured path too. Resend sends transactional email (verification, password reset). All sub-processors are listed in our sub-processors document and sign EU 2021 Standard Contractual Clauses.