Privacy & Sync Security
A plain, honest account — written to be clear, not to impress.
Again is local-first: the app works fully offline, with no account, no email, and no password. Sync between your own devices is optional and opt-in — nothing leaves your device unless you turn it on.
In short
- No account, no email, no password. Your sync identity is just two random 256-bit secrets generated on your device.
- End-to-end encrypted sync. Your content is encrypted with AES-GCM-256 using a key derived (via HKDF-SHA256) from one of those secrets. That key never leaves your device.
- The server never receives your encryption key — or the secret it comes from. When linking or restoring, your device sends only a one-way SHA-256 fingerprint of the secret (which is all the server stores to recognise you). The raw secret, and the key derived from it, never travel over the network.
- Metadata is not encrypted. The server can see that you synced something and when (event timestamps, device id, a version number), but not what — titles, notes, schedules, and completion dates are all inside the encrypted payload.
Identity model
When you enable sync for the first time, your device generates locally:
- User ID — a random identifier (UUID) for your data, not tied to your name, email, or phone. Sent in the clear.
- Sync secret — 256-bit random root of both authentication and the encryption key. Never sent raw — only its SHA-256 fingerprint is transmitted.
- Device ID — identifies this specific device (UUID). Sent in the clear.
- Device token — a 256-bit per-device key that authenticates this device to the API. It is auth-only and cannot decrypt anything. Sent once when registering/linking a device, then only its hash is stored.
Both secrets are kept in your device's secure storage — the iOS Keychain directly, and on Android an encrypted store sealed with a key held in the hardware-backed Android Keystore. Server-side, only SHA-256 hashes of each secret are ever persisted — never the secrets themselves.
"Pseudo-anonymous", not "anonymous": Cloudflare logs the client IP per request (their default, retained briefly). A determined adversary who could subpoena Cloudflare could in principle correlate a User ID with an IP. We don't claim more than that.
What's encrypted, what isn't
Each sync event has metadata that stays in the clear — id, user id, device id, event type, a version number, and timestamps — plus a payload field carrying the content (the loop's title, notes, emoji, colour, schedule, completion dates…). That payload is wrapped in an AES-GCM-256 envelope; the 32-byte key is derived on each device from the sync secret via HKDF-SHA256.
HKDF is one-way: even someone who recovered the key could not work back to the sync secret. The key is never stored or transmitted — every device re-derives it on demand, which is how two devices holding the same secret read each other's events.
What the server (or anyone with read access) can see: how many events of each type exist, their timestamps, which device created each, and your overall activity cadence. What it cannot see: your titles, notes, emoji, colours, schedules, or completion dates — and we never collect your email, name, phone, contacts, location, or photos at all.
Linking a second device
QR scan. The new device generates an ephemeral key pair and shows a QR carrying a random pairing id plus its public key — no secret. The existing (already-enrolled) device scans it, performs ECDH against that public key, and AES-GCM-seals your sync secret + user id under the derived key. It posts that sealed blob to a single-use, 60-second relay; the new device claims and opens it with its private key, then enrols. The server only ever holds two public keys and ciphertext — it can't derive the shared key, and the QR carries nothing a photo could exploit. (Same handshake the web companion uses.)
No other device to hand? Settings → Sync → Restore from sync key rejoins from your saved key directly — no second device, no code.
Screen-leak defence
The screens that show the QR or the raw sync key set the platform's
secure-window protection — FLAG_SECURE on Android and a
secure-layer overlay on iOS — so while they're open, the system
blocks screenshots, recents thumbnails, screen recordings, and most
screen-mirroring. A separate biometric prompt gates those screens, so
even on an unlocked phone you must re-authenticate before anything is
revealed.
This closes the easy, accidental exfiltration paths. It is not a defence against an attacker holding your unlocked device — see below.
Data retention & deletion
- Settings → Sync → Delete cloud data — hard-deletes all of your sync data on the server (events, device records, link tokens, sync state, and your encrypted snapshot blob) along with your user record.
- No device authenticates for 6 months — the same deletion runs automatically via a periodic inactivity cull.
- You disable sync on a device — that device's local credentials are wiped and its server record revoked. Your other devices and data stay intact.
- Expired, single-use link codes are purged regularly.
Cloudflare retains request metadata (including IP) briefly per their own defaults; we have no admin control over that.
Threat model — what we defend, what we don't
Defended:
- Network eavesdroppers — TLS protects every request, and the raw sync secret + encryption key never traverse the network at all (only the SHA-256 fingerprint does).
- A malicious or compromised server reading your content — because the client only ever sends the fingerprint, even a server that logged every request could not derive your encryption key. (It could capture a device token to act as one of your devices, but a device token can't decrypt anything, and a malicious server already controls its own data store.)
- A read-only breach of the database or snapshot storage — both hold only ciphertext + nonce + auth tag plus routing metadata. No content is readable without the sync secret, which is never stored.
- Accidental screen leaks — secure-window protection on the QR / sync-key screens.
- An unlocked device in someone else's hands, briefly — the biometric gate on cross-device-security actions.
Not defended (and we won't pretend otherwise):
- An attacker with your unlocked device and your biometric (coercion): no software-only product can defend against this.
- Traffic-pattern analysis — a passive network observer can see request timing, IP, and rough payload size.
- State-level adversaries / forensic device extraction — out of scope for a personal tracker.
- Forward secrecy — one key decrypts all of your events; if the sync secret leaks, past events under it are exposed. Rotating the sync key (in Settings) re-keys going forward and removes the old ciphertext from the server.
This is not a marketing document — it's a plain description of how sync actually works, caveats included. If something here doesn't match what you see, the contact address is on the privacy page.