PushArmor

Security and threat model

Your devices don't need to trust our relay server. Messages are encrypted on your device, and can only ever be decrypted by your own paired devices. Each app and add-on checks everything the server sends, so the server cannot change a message or pose as one of your devices. Each device makes two key pairs (P-256), one for signing (ECDSA) and one for encryption (HPKE), and the private keys used to decrypt and sign messages never leave it. Where the device supports it, they are kept in its hardware key storage (the Secure Enclave on iPhone, the Android Keystore on Android). (The one exception is a short-lived throwaway key that the web delete-account page holds in your browser tab while you log in with Google or Apple. It is not a device key, and it cannot read messages.)

What each party sees

PartySeesCannot see
Your devices
  • The messages you send them, after decryption and signature checks
  • Any messages for other devices
Our relay server (hosted on Cloudflare)
  • A one-way (keyed) hash of your email address, which is your account ID
  • If you log in by email: your email address, briefly, to send you the login code
  • Your IP address
  • Device public keys
  • The push tokens (FCM, APNs) and web push endpoint URLs the server needs to send you your messages
  • The end-to-end encrypted version of your messages, which it cannot read, and their padded size, so it can relay them to your other devices
  • The random device IDs of the sending and receiving devices for messages you send within your account
  • Any message content
  • Any private keys
  • Any pairing fingerprints
  • Any of the names you give your devices
Cloudflare
  • Everything our relay server sees, since Cloudflare runs it and its database
  • Our delivery logs, kept for up to 7 days: account ID, device IDs, and send results
  • Any message content
  • Any private keys
  • Any pairing fingerprints
Push services (Firebase Cloud Messaging (FCM), Apple Push Notification service (APNs), Google and Mozilla web push, and a UnifiedPush distributor)
  • The push token (FCM, APNs) or web push endpoint URL
  • The encrypted message they cannot read (ciphertext)
  • Undelivered messages, held up to 7 days (pairing requests up to 4 weeks)
  • Any message content
  • Any private or public keys
  • Any pairing fingerprints
This website
  • Nothing about you: static files, no login, no analytics
  • Cloudflare's bot check (Turnstile) runs on the email login page and on the delete-account page only
  • Any message content
  • Any private or public keys
  • Any pairing fingerprints
AWS SES
  • Your email address when it sends a login code
  • Any message content
  • Any private or public keys
  • Any pairing fingerprints
  • We send it nothing else

The push service and our relay server can show a notification with text of their choosing on every platform; verified content appears only after your device decrypts it.

The push service sees the size of a message (padded to a few standard sizes), not its content.

How devices trust each other

Two devices trust each other only after you pair them by verifying that the 4-character pairing fingerprint is identical on both screens.

The pairing fingerprint is not a code sent to your devices, and it is never sent over the network. Pairing has you compare a short code on both screens (short authentication string, SAS). Each device first commits to its values by sending only their SHA-256 hash, and reveals them after it has seen the other device's hash (commit-then-reveal). Each device then computes the 4-character fingerprint on its own, from both devices' public keys and a fresh random value from each device. No one, including our relay server, can steer the result.

Every message is signed by the sending device and checked by the receiving device; repeated or old messages are ignored (replay protection). A message that fails this check is never shown; History lists it as "PushArmor received a message it could not read". Messages you read inside PushArmor passed this check. A notification is only a prompt: if one looks wrong, open PushArmor and read the message there.

Reporting a security problem

Report it in a public GitHub issue or privately with GitHub private vulnerability reporting. The source code is public on GitHub.