Security

Your privacy is absolute.

PulseApp uses zero-knowledge encryption — the same architecture as Signal, Bitwarden, and ProtonMail. Your contacts' names, numbers, emails, and notes are encrypted on your device with a key only you hold. Even our own engineers can't read them.

The promise

We never see plaintext

Every contact name, phone, email, and note is encrypted on your device BEFORE it touches our servers. We store ciphertext only.

AES-256-CBC encryption

Each contact field is encrypted with AES-256-CBC and a unique random IV before it leaves your device. (HMAC-SHA256 is used separately to fingerprint phone numbers for duplicate detection — not to authenticate the ciphertext.)

Dual-lock recovery

Your encryption key is sealed twice — once with your password, once with a 16-character recovery key. Lose one, use the other.

How the encryption actually works

Plain English version. Skip ahead if you don't care.

1

Account creation

When you sign up, your device generates a random Master Encryption Key (MEK) — 256 bits of entropy. This key is the only thing that can decrypt your data. We never see it. It exists only on devices you own.

2

The MEK gets sealed twice

Your MEK is locked into two encrypted “lock boxes”: one sealed with your password (lock_box_1), one sealed with a 16-character recovery key shown to you once at signup (lock_box_2). Both lock boxes are stored on our servers. Both are useless without the correct password or recovery key.

3

Every contact is encrypted before upload

When you add or edit a contact, your device encrypts every PII field (name, phone, email, broker name, notes) using AES-256-CBC with the MEK and a unique random IV per field. The encrypted output looks like “Np4wK7mL:U2FsdGVkX1+randomciphertext...” — useless to anyone without your key.

4

The server stores ciphertext

Our Supabase database receives the encrypted strings. It does not — and cannot — see the underlying names, phones, or notes. Row-level security policies ensure only you can read or write rows tagged with your user ID.

5

Decryption happens on YOUR device, with YOUR key

When you open the app, your device unlocks lock_box_1 with your password to recover the MEK. The MEK then decrypts every contact field as it's rendered. The MEK is cached in iOS Keychain so you don't re-enter your password every launch.

What this means in practice

  • • If our database gets breached, attackers get encrypted blobs. Useless.
  • • If we get a subpoena, your contacts' names, numbers, emails, and notes are ciphertext we can't decrypt — though we'd have to produce the data we do store in plaintext (call outcomes and dates, production estimates, list tags, and your account profile).
  • • If a rogue employee accesses the database, they see ciphertext. They cannot read your contacts.
  • • If you forget your password, your recovery key is the only way back. We literally cannot reset your data for you.

Threat model

How we defend against the realistic threats — and where we cannot defend.

Database breach

Attacker gets full DB dump.

Mitigation: They get ciphertext blobs. No keys are stored alongside the data. Useless.

Rogue employee

Internal attacker queries the database.

Mitigation: Same as above. We literally cannot read contact data even with full DB access. Audit logs record any admin RPC calls.

Compromised device

Attacker has physical access to your unlocked phone.

Mitigation: Face ID / passcode lock optional but recommended. App auto-locks after inactivity. Keychain encryption protects cached MEK.

Lost password + lost recovery key

You forget your password AND lose your 16-character recovery key.

Mitigation: Your data is unrecoverable. This is by design — zero-knowledge means we cannot bypass your own keys. Save your recovery key.

Security questions

How is this different from other "secure" CRMs?

Most "secure" CRMs just use TLS + encryption-at-rest, which means the SERVER can still read your data. That's called "server-trust" encryption — useful, but doesn't protect against breaches, subpoenas, or rogue insiders. Zero-knowledge means YOUR DEVICE encrypts before sending. We literally never have the keys.

Is the code open source?

Not yet, but the cryptographic libraries we use are well-known, audited open-source implementations: CryptoJS for AES-256-CBC and HMAC-SHA256, and @noble/hashes (audited by Cure53) for PBKDF2-SHA256 key derivation. We use no homegrown crypto.

Have you been audited?

Not yet — we're a new product. As we scale, we'll commission an independent security audit and publish the results. Until then, the architecture is public (this page) and the techniques are standard.

What about my user account itself (email, name)?

Your account profile (email, your own name, NMLS number) is stored in plaintext — we need it for transactional emails and Supabase Auth requires a plaintext email. For your contacts, the identifying fields (names, numbers, emails, notes) are zero-knowledge encrypted; non-identifying fields that power features — call outcomes, dates, production estimates, and list tags — are stored in plaintext.

Can you support law enforcement requests?

We comply with valid subpoenas and warrants. We can only hand over what we actually have: the encrypted (undecryptable) contact identity fields, plus the data we store in plaintext — your account profile, call outcomes and timestamps, production estimates, and list tags. We cannot decrypt your contacts' names, numbers, emails, or notes under any circumstances.

Found a vulnerability?

Email info@mobile-crm-app.com. We respond within 48 hours. Responsible disclosure encouraged.

Try the only zero-knowledge mortgage CRM.

60 days free. Every feature unlocked. Your contacts stay yours.

Get started