Security
Last updated:
How My GLP Shot protects your data
The default mode is local-only. Your shots, doses, weights, mood, body measurements, lab values, photos, and notes never leave your device unless you explicitly opt into cloud sync.
If you turn on cloud sync, the encryption happens in your browser before any byte hits our server:
- Your password is never sent to our server. It is run through
PBKDF2-SHA-256with 600,000 iterations in the browser to derive both an authentication token (sent to the server) and an AES-256-GCM key (kept on your device). - All synced data is encrypted with that AES-256-GCM key using a fresh random 12-byte IV before upload.
- The server stores opaque ciphertext only. We have no key material. We literally cannot read your data.
- Doctor-share links generate a fresh per-share AES key and place it in the URL fragment after the
#— fragments are not sent to servers, so the share link's key never reaches us either.
The full encryption code is short, idiomatic, and uses only the platform's built-in SubtleCrypto Web API. You can read every line on GitHub.
Independent audits
As of , My GLP Shot has not undergone a formal third-party penetration test or cryptographic audit. The code is public; community audit is welcome and encouraged.
If a formal audit is conducted, results will be published here.
What we promise on disclosure
- Acknowledge within 48 hours. A real human will reply, not an autoresponder.
- Patch critical issues fast. Privacy and crypto issues take priority over feature work.
- Public credit. If you'd like to be credited (with a name, handle, or anonymously), we'll add you to a public security acknowledgements list. Credits live in SECURITY.md.
- No legal threats for good-faith research. If you're acting in good faith — testing only your own data, not exfiltrating other users' data, not running denial-of-service against production — we are not going to come after you.
How to report
Email [email protected] with:
- A clear description of the issue and the impact.
- Steps to reproduce (test account, sample input, etc.).
- Optionally, a suggested fix or mitigation.
For high-severity issues, please do not open a public GitHub issue first — give us a chance to fix it before broad disclosure.
Encrypted channel
If your report contains anything you'd like to encrypt in transit, encrypt to the email address above's public key. PGP key fingerprint will be added here once published; until then, plain TLS email to [email protected] is the supported channel.
Out of scope
- Theoretical attacks against the underlying primitives we depend on (browser
SubtleCrypto, TLS, the Stripe billing flow). - Vulnerabilities that require a compromised user device or a fully compromised browser — at that point, all bets are off, regardless of our app's design.
- Self-XSS or social-engineering of the user's own browser console.
- Issues only reachable from a custom-built or modified version of the code.
Infrastructure
- Servers: independent VPS infrastructure (not AWS or Google Cloud).
- Backups: daily encrypted (AES-256-CBC + PBKDF2) backups to a second VPS.
- TLS: Let's Encrypt certificates, auto-rotated, OCSP stapling enabled.
- Email: Resend for transactional mail; no marketing automation, no third-party tracking pixels.
- Analytics on the marketing site: self-hosted privacy-friendly Umami (no IPs, no cookies, no cross-site tracking). The app itself loads zero third-party scripts.
Account deletion
To delete your account and the encrypted cloud blob, open the app → Settings → "Delete account and all cloud data." The deletion is immediate and irreversible; we do not retain backups of deleted account data beyond the rolling encrypted snapshot, which is itself unreadable to us and rolls over.
Questions? [email protected]