Security Architecture
1. Design goals and threat model
Pocket is built to protect you against the failure modes that actually compromise financial data at scale:
- Server breaches — eliminated structurally. Pocket runs no cloud service and holds no copy of your data, so a "Pocket hack" cannot leak it.
- Data harvesting and resale — eliminated structurally. There is no telemetry, no analytics SDK, no advertising, and no account system.
- Network interception — the app makes no outbound requests carrying personal data (see §8 for the complete list of connections).
- Casual local snooping — an app-lock PIN and OS biometrics gate the interface, and vault/backup contents are encrypted under keys only you can derive.
Explicitly outside the threat model: an attacker who controls your device while you are logged in (malware, keyloggers), or who has physical access to an unencrypted disk. No desktop application can defend against a compromised operating system — see §9 for what we recommend.
2. Where your data lives
Everything you enter is stored in a single SQLite database file (plus a vault folder) inside a data directory on your device. It is created locally, read locally, and never transmitted by Pocket. You can copy it, back it up, or delete it like any file — deleting it removes your data permanently.
Honest detail: the main working database is not encrypted at rest by the app. It is protected by your operating-system account and whatever disk encryption your device uses. This is a deliberate early-access trade-off — the app works with zero setup and no master password to lose — and full at-rest database encryption is scheduled on the roadmap (Q4 2026). Until then we recommend enabling BitLocker / Windows Device Encryption, which encrypts the database (and everything else) whenever the machine is off.
3. Document vault — encrypted, zero-knowledge
Vault files (PAN, insurance, property papers, anything you choose) are individually encrypted on your device:
- Key derivation: your passphrase is run through scrypt (n=214, r=8, p=1) with a fresh random 16-byte salt per file, producing a 32-byte key. scrypt is deliberately memory-hard, which makes brute-forcing passphrases expensive.
- Encryption: the derived key seals the file with AES-256-GCM, using a fresh random 12-byte nonce per file. GCM is authenticated encryption — a tampered or wrongly-keyed file fails authentication instead of decrypting to garbage. Vault files written by earlier early-access builds (Fernet: AES-128-CBC + HMAC-SHA256) remain readable and are transparently re-encrypted to AES-256-GCM the next time they are opened with the right passphrase.
- Zero knowledge: the passphrase and derived key are never stored, anywhere. A wrong passphrase cannot decrypt, and a lost passphrase cannot be recovered — by you, by us, by anyone. That is the point.
- What stays visible: document names, labels, sizes and dates are kept in a plaintext index so the app can list your vault without a passphrase. If a filename is itself sensitive, rename it before adding.
- Different files may use different passphrases; each file carries its own salt. Documents up to 10 MB.
4. Encrypted backup & sync — your key, your storage
- A backup snapshots the database using SQLite's online backup API (safe while the app runs), then encrypts the snapshot with the same scrypt → AES-256-GCM scheme as the vault (envelope v2; v1 envelopes from earlier builds remain restorable), under a passphrase you choose.
- The result is a single opaque encrypted blob written to a folder you pick — including a folder your own Dropbox/OneDrive/Drive client syncs. Your cloud provider stores ciphertext it cannot read; Pocket runs no sync server and holds no key.
- Restores are newest-wins, and a safety copy of the current database is made before any restore overwrites it.
5. App lock and biometrics
- The app-lock PIN is never stored — a scrypt hash (same parameters as above, random salt) lives in the local database, and verification happens server-side in the local app process, never in browser storage.
- Biometric unlock uses the real OS credential system (WebAuthn) — Windows Hello face, fingerprint or device PIN. Pocket never sees or stores biometric data; the operating system performs the check and returns only a signed assertion.
6. The local app server
Pocket's interface is served by a small local web server:
- It binds to 127.0.0.1 (localhost) only by default — unreachable from the network. Serving to your own Wi-Fi (for the phone experience) is a separate, explicit opt-in.
- An optional API token can be required for every request; it is compared in constant time to prevent timing attacks.
- Sensitive actions are recorded to a local, append-only audit log you can inspect.
7. Imported statements are treated as untrusted
A CSV or bank statement is written by someone else, so Pocket treats every field in it — merchant names, descriptions, categories — as untrusted input rather than as its own data. That matters because the interface is a web page: text from a file should never be able to become code running next to your financial database.
- Text shown on screen is HTML-escaped, so markup in a merchant name renders as characters, not as elements.
- Text passed to the page as data is encoded for that context specifically, so it cannot end the surrounding script block.
- Text placed inside a button's action is escaped for JavaScript before it is escaped for HTML, because a browser decodes the second before it reads the first. Names with apostrophes — O'Brien, Trader Joe's — are preserved exactly rather than stripped.
Each of these is covered by an automated test that is verified to fail if the protection is removed, so a future change cannot quietly undo them.
8. Every network connection, listed
| Connection | When | What is sent |
|---|---|---|
| Market price feeds (Yahoo Finance, AMFI, public crypto APIs) over HTTPS | Only when price refresh is enabled/used | Instrument identifiers (e.g. ticker symbols). Never names, quantities, balances or any personal data. |
| Your own cloud folder (if you point backups at one) | Only when you back up / sync | One encrypted blob, sealed under your passphrase before it touches the folder. |
| Hosted AI (optional, off by default) | Only if you explicitly enable it | Described at the point of enabling; the built-in intelligence runs entirely on-device. |
That is the complete list. There is no telemetry, no crash reporting, no update phone-home, and license keys validate offline (§10).
9. What is NOT protected — read this
- The main database is not encrypted at rest by the app (§2). Mitigate with OS disk encryption; the vault exists for your most sensitive documents.
- A compromised device defeats everything. Malware running as you can read what you can read. Keep your OS updated and use an up-to-date antivirus.
- Vault metadata is plaintext (names, labels, sizes) — by design, documented in §3.
- Data in memory while the app runs is not specially hardened beyond OS process isolation.
- The early-access build is not yet code-signed. Only run a build you received directly from us — if in doubt, email us and we will confirm the file's SHA-256 checksum.
- No independent security audit has been performed yet. This page is our own honest account, verified against the source; an external review is planned before wide release. We will publish results here when it happens.
10. License keys
Paid tiers activate with a key that is signed with Ed25519; only the public key ships in the app, so a key that verifies provably came from us. Validation is fully offline — no activation server, no phone-home, and a key past its term simply drops the app to the permanent Free plan.
11. Reporting a vulnerability
If you believe you have found a security issue, email the address on our Contact page with the subject SECURITY. You will get a human response, normally within 48 hours. Please give us a reasonable window to fix the issue before public disclosure; we will credit you (or keep you anonymous, your choice) in the fix notes. There is no bug bounty yet — early access is honest about its budget — but reports are taken seriously and acted on first.