Security
Last updated · 3 July 2026
Backstop’s differentiator is not “we promise not to look.” It’s that our infrastructure cannot look at the parts that matter. This page describes how.
The trust model
Backstop has three physical places where code runs: your child’s laptop (the endpoint), your browser (the parent PWA), and our servers (the control plane). Content flows between the endpoint and your PWA. The control plane in the middle is a ciphertext relay — it stores and forwards opaque bytes.
What the control plane can see:
- Your account email and Argon2id password hash.
- Which endpoints belong to your family and when they were last online.
- The size and timing of each alert.
- The delivery channel and destination you asked us to route to (e.g. a phone number or a browser push subscription).
- A coarse two-bit severity bucket (0 = “notify eventually,” 1 = “notify now”) so routing rules can pick the right channel.
What the control plane cannot see:
- Screenshots. They never leave your child’s laptop.
- Your BYOK LLM provider API key. It lives in your endpoint’s OS keychain.
- Full LLM responses. Only the fields needed for an alert get packaged, and even those are encrypted before we see them.
- Alert content. The one-sentence summary and triggered categories are encrypted before they reach us.
- Your harms taxonomy and blocklists. Encrypted before we see them.
End-to-end encryption using age
We use the age protocol on both sides:
- On the endpoint, we use the audited Rust
agecrate. - In the browser, we use age-compatible primitives built on the
@noblelibraries.
Both sides speak the same wire format, which sidesteps a large class of interop and key-scheduling bugs.
Cryptographic primitives
- X25519 for elliptic-curve key agreement.
- ChaCha20-Poly1305 for authenticated symmetric encryption.
- BLAKE3 and HKDF for key derivation.
- Argon2id for password-derived key wrapping.
Additional authenticated data (AAD) on every encrypted record includes the record’s
primary identifier (alert_id, config_version, etc.) to prevent
ciphertext-substitution attacks.
The family key
Every family has one long-lived symmetric family key.
- Generated in your browser at signup, using the platform’s cryptographically secure random source. It is never sent to us in plaintext.
- Stored at rest in your browser’s IndexedDB, wrapped under a key derived from your login credentials via Argon2id and HKDF. Held in memory only while the PWA is open.
- Backed up via a 12-word BIP-39 mnemonic phrase shown once at signup, and optionally by an encrypted backup file you can save to iCloud, Google Drive, or a USB stick.
- Delivered to enrolled endpoints via a short-lived pairing code shown in the parent app during install, so that endpoints can decrypt configuration and encrypt outgoing alerts to you.
If you lose all of your devices, your 12 words, and your backup file, we cannot recover your data. That is by design. It’s the same trade-off Signal and iMessage make.
Where our own secrets live
Even though we cannot decrypt your content, we still hold service secrets. Those are protected accordingly.
- Private CA key (the root of endpoint identity) and update signing key (the ability to push code to enrolled endpoints) both live in Google Cloud KMS with non-exportable keys. Nobody — including us — can extract the raw key material. Access is via signing-only APIs.
- JWT signing keys live in Google Cloud Secret Manager, encrypted with GCP CMEK, and are rotated annually or on emergency.
- Endpoint client certificate private keys live in the OS keychain on your child’s device (Windows DPAPI or macOS Keychain), not on our servers.
Alert delivery under E2EE
When an endpoint fires an alert, it encrypts the content under your family key, packages delivery hints (channel + destination) alongside the ciphertext, and hands the bundle to the control plane.
- Web push is delivered as a payload your service worker decrypts locally with the family key you already hold.
- SMS, email, and WhatsApp are content-free pings by default: “You have a new Backstop alert. Open the app to see.” Full content is only visible after you open the PWA and it decrypts locally.
Kids on the endpoint
The endpoint does exactly what it needs to and nothing more. It runs in the user’s session for screen capture, uses a signed helper for privileged operations, and its update client verifies signatures against a manifest anchored to our KMS-held signing key. Tampering detection reports back to you.
Vulnerability disclosure
Please report anything you find to security@backstop.family. Our disclosure policy is also published at /.well-known/security.txt per RFC 9116.
Response commitments:
- Acknowledge within 24 hours.
- Triage within 5 business days.
- High-severity fixes within 30 days.
- Critical fixes (remote code execution, key exposure) within 7 days with an emergency hotfix channel push.
- CVE assignment for issues at medium severity or higher.
Bug bounty
We plan to open a public bug bounty in v1.5. Meanwhile, we thank named reporters on this page (with permission) and offer swag.
What we still see (being honest)
We do see metadata: your email, when your endpoints are online, how often they send alerts, the size of each alert, and the delivery routes you chose. That metadata is enough for someone with legal process to learn things about your family’s use of Backstop, even though they cannot learn the content of any alert or rule. We think that’s the right trade-off for a product that has to reliably deliver notifications.