Trust Updated 2026-08-01 View as Markdown

Security and privacy

This page describes the security contract: what is protected, how, and what is not. It does not describe internal defensive heuristics, which would be counterproductive to publish.

Accounts

Passwords are hashed with bcrypt at 12 rounds and compared in a timing-safe way. Only the hash is stored; the plaintext is never written anywhere.

Sessions use signed tokens with a bounded lifetime. Because they are stateless, they cannot be revoked before expiry — which is precisely why they are not used as machine credentials. See authentication.

Encryption

Sensitive profile fields are encrypted at rest with AES-256-GCM, using a random initialization vector per value so identical inputs do not produce identical ciphertext. This covers your display name, age, height, goal and target weight, injuries, allergies, and the free-text notes about what has worked and failed for you before.

Ledger data is not field-level encrypted. Push-up counts, meals, weights and habit checkboxes are stored in plain text within the database.

That is a considered line rather than an oversight. Profile fields contain health disclosures and identity; a workout log is personal but not comparably sensitive, and encrypting it would add overhead to every read and write on the hottest path in the application while protecting little. The database itself is encrypted at rest by the provider.

If that trade-off is not right for you, it is worth knowing before you start.

Machine credentials

API tokens for the MCP server are stored only as SHA-256 hashes, carry explicit non-cumulative scopes, and are checked against the database on every call — so revocation takes effect on the very next request. Full detail in authentication.

The MCP endpoint additionally refuses any request carrying a browser Origin header, which closes both the permissive-CORS gap and the DNS-rebinding case the MCP transport specification warns about.

AI safety

Prompt injection defense. Input to the AI endpoints is screened before it reaches a model, and suspicious content is either sanitized or blocked. This matters more here than in a typical chat product because the coach reads text you did not necessarily write — imported CSV content, extracted lab-report text, meal notes.

Length and history bounds. Message length, conversation depth and total conversation size are all capped, so a single request cannot exhaust the context window.

Your data is not training data. Content sent to model providers is processed to answer your request. It is not used to train models, and it is not shared with anyone else.

Third parties

Service Receives Why
MongoDB Atlas Everything, as the system of record Storage
xAI Coaching context for the current request; lab and methylation text during extraction Chat, voice, extraction
VoyageAI Day and summary text Embeddings and reranking
WHOOP Nothing. Data flows inbound only Wearable sync
Vercel Request metadata and logs Hosting

Two things deliberately never leave your device or your account:

  • Lab and methylation PDFs. Text extraction happens in your browser. Only the extracted text is sent for parsing, so the file — with its name, date of birth and provider header — stays local.
  • Progress pictures. Stored against your account and returned only to you. Not sent to any model, not embedded, and not readable by any MCP tool.

Infrastructure

HTTPS everywhere, enforced by the platform. Rate limits per user and per action. Circuit breakers that fail fast when an upstream service degrades rather than hanging your request. Schema validation on every API request, including sanitization that rejects MongoDB operators in field names. Structured logging with semantic event names, which is what makes an anomaly visible.

What is not protected

Being straight about the limits is more useful than a longer list of controls.

Rate limits are per-instance and in-memory. They reset on a cold start, so the effective ceiling across a scaling event is somewhat higher than the stated number. They bound abuse; they are not a hard quota.

API tokens do not expire. That is safe only because revocation is immediate. A token you have forgotten about is a token that still works — list them periodically and revoke what you no longer use.

Ledger data is readable by anyone with database access. See the encryption section above. The set of people with that access is very small, but it is not zero.

Session tokens cannot be revoked before expiry. If you believe a session is compromised, change your password.

This is early-access software. It is built carefully and tested, but it has not been through an external security audit.

Your data

Export. CSV export of your full ledger over any range, at any time, without asking anyone.

Deletion. Request account deletion and the record goes with it.

Ownership. It is your data. It is not sold, not shared with advertisers, and not used to train anything.

Reporting a problem

If you find a security issue, report it privately rather than publicly, and give a reasonable window for a fix before disclosure. Contact details are on the landing page.