TL,DR;
Yes. Capitally is a privacy-first, end-to-end encrypted portfolio tracker. Your financial data is encrypted on your device with keys only you hold — our servers in the EU only ever see encrypted blobs, so we (and anyone who breaches us) literally cannot read your portfolio.
Data lives on your device
The core concept of Capitally is that all of your data is encrypted and kept on your device. Our servers only store a copy of your project for syncing between devices, but as only you have access to the encryption keys, we cannot see the actual data — and it's completely fine if you block those sync requests.
Concretely, that copy sits in your browser's own database for the site (IndexedDB), not as a file you can open in Finder or Explorer, and it is encrypted there too — the plaintext exists only in memory, while you have the app open. Each browser keeps its own store, and the installed app has a store separate from the browser you installed it from (see Desktop & Mobile App), which is why signing in somewhere new starts with a re-sync rather than instant data.
Two consequences worth knowing: if you want a copy you can hold, take a JSON export — see Backing up and restoring your project. And if two devices show different numbers, that is a sync or cached-price problem on one of them rather than a data problem — see Troubleshooting the app.
The only thing we “see” is which market symbols you interacted with — searched for, or fetched prices — but we don't tie that to your account.
Capitally is also a portfolio tracker without Plaid, Yodlee, or any other broker-linking aggregator. We don't ask for your broker username and password, and we don't read your bank account. Imports happen only via direct file upload (CSV/XLS/XML/JSON) or manual input. That's a privacy choice, but it's also a precision one — broker CSV exports go back to the day the account was opened and keep the corporate actions, dividend reinvestments and FX conversions that aggregators typically drop, which is exactly the detail an accurate cost basis (and a tax filing) depends on.
Projects are encrypted by default
Every Capitally project uses client-side AES-256 encryption (AES-GCM) with keys derived from your password via PBKDF2 and protected by RSA-OAEP key wrapping. This is zero-knowledge encryption: the encryption keys never leave your device, and our servers only store ciphertext.
By encrypting your data, we aim to protect it from:
- unauthorized access to data stored in our databases, either by employees, hackers or government agencies
- unauthorized access on your device, but only as long as you protect your browser's profile from direct access, or you don't choose “remember me“ option when logging in
We cannot protect it from:
- supply-chain/man-in-the-middle attacks where attackers replace our source code
- unauthorized writes or deletes made in our databases or on the client device
- detecting project activity — project metadata, like operation type (transaction created, updated, deleted, etc.) and timestamps (when you made the change, not the actual transaction) are not encrypted
How encryption works
When creating a project you have a choice of three encryption modes:
- User Password — when you log in, we use
PBKDF2to derive two passwords from the one you enter, using two separate salts. The first password authenticates you, so our auth servers (Google Identity Platform) never receive your typed password, and the second can't be derived from it. The second password encrypts (withAES-GCM) a set of private keys used for project encryption. You can choose to securely store that key in your browser so you don't have to type it again. - Project Password — the same as above, but you set a separate project password that derives the encryption key, distinct from your login.
- Remote Key — once you log in, the app retrieves an encryption key from the server. The key is not stored in the database; it's derived on the fly from your credentials, a salt, and our own private key. The endpoint that holds that private key is segregated from every other endpoint.
What each mode means at the sign-in screen — which one a Google sign-in account gets by default, and what Logout clears — is in Your account & signing in.
Each project user (the system is ready for project sharing, even though only one user is supported today) has an RSA-OAEP keypair. The private key is encrypted with the main encryption key above and is used to decrypt share keys (another AES-GCM), which in turn encrypt and decrypt project data. There can be multiple share keys per project — e.g. one for each set of data shared between the same users.
The public key is used to encrypt share keys issued to the user, and to sign messages generated by the backend (e.g. new transactions from a broker) so that only the intended user can read them.
Once you enter a password, it's not stored or sent anywhere. The derived encryption keys can be stored in your browser, but they are non-exportable — they can decrypt your data, but the key material itself cannot be read back out, not even by Capitally's own application code.
We use webcrypto for all encryption-related tasks, including generating random numbers
Signing in and account security
Capitally has two independent layers: authentication decides who can sign in to your account, and encryption decides who can read the data. Most of the protection sits in the second layer — someone who got into your account would still be facing ciphertext if the project has its own password.
Two-factor authentication today. Signing in with Google gives you Google's own multi-factor authentication, which is currently the most direct way to put a second factor in front of a Capitally account. Native 2FA — TOTP apps such as Google Authenticator or Authy, plus email and SMS verification — is on the roadmap.
A second secret for the data itself. A Project Password (also called "bring your own key") encrypts the project independently of how you log in, so account access alone is not enough to read anything. It is described as mode 2 in How encryption works above.
Hardware keys. Your encryption key is derived from your password on your device and never reaches our servers, so a hardware key such as a YubiKey would be a convenience for signing in and for handling keys — not the thing standing between an attacker and your data, as it would be at a service that holds your keys server-side. Passkey support, covering both sign-in and project encryption, is also on the roadmap.
If you lose your project password
We cannot reset a project password or recover the data behind it: the key is derived from your password and exists only on your device, and our servers hold ciphertext. Before you conclude the data is gone, check three things — and read the first one before you touch anything.
1. Are you still signed in somewhere else? Encryption keys stay in the browser session until you explicitly click Logout — closing the tab, quitting the browser or restarting the machine does not clear them. So any device or browser where you opened the project and never logged out is a live route back in: open the project there and set a new password under Settings → Encryption. Do not log out of that session to "try again" — it is holding the only copy of the key you have left.
2. Was the password saved? Sign in normally and let your browser or keychain autofill the project password. If it works, set a new project password straight away, or switch the project to User Password encryption so there is only one secret left to keep.
3. Which encryption mode is the project on? With User Password there is no separate project secret — the project unlocks with your login password. With Remote Key, the key is re-derived on the fly from your credentials, so the ordinary account-reset flow gets you back in. Only Project Password puts a second secret in your hands that nothing can reset. If it is the login password itself you have lost, routes 1 and 2 are what you have.
If none of those apply, the data in that project cannot be recovered — not by you, not by us, not by an attacker, and not by a subpoena. That is the same property that makes the encryption worth having.
Sync is not password-loss insurance
The server copy is ciphertext, so it survives a lost device and not a lost password. Prefer User Password encryption unless you have a specific reason not to, keep a project password in a reputable password manager, and take a periodic full JSON export from Settings → Export Data — a complete, re-importable snapshot. See Backing up and restoring your project.
Hosting, GDPR, and EU data residency
Capitally is built in Europe for investors around the world, and operates under EU privacy law.
- Hosted in Europe. All servers and databases live in EU data centres — your encrypted data never leaves European jurisdiction. We use Google Cloud, Railway, Hetzner, MongoDB and Cloudflare.
- GDPR compliant. You have the right to export and to permanently delete your data at any time; both are one-click operations inside the app, with no email required.
- Industry-standard server hygiene on top of end-to-end encryption: HTTPS for all traffic, encryption at rest, need-to-know access for our own team, two factor authentication and access logs.
- No third-party data brokers. We don't share data with advertisers, and no analytics SDK has access to your portfolio — you can also opt out of analytics entirely (see Analytics & error tracking below).
Is the code open-sourced and verified?
Capitally is a closed-source project, but the client app is written in TypeScript and all data handling is done on the client. All network communication is easily verifiable in the browser's dev tools.
Like with every piece of software, it ultimately comes down to trust. You need to trust us that we (or a hacker) won't covertly change that code and steal the encryption keys or passwords.
Most other portfolio trackers describe themselves as "bank-level encrypted", which means the provider holds your keys and can read your data. Capitally is end-to-end encrypted, which means only you can — even our own engineers cannot, by design.
We rely on it ourselves
We chose to implement end-to-end encryption because we want to keep our own financial data private. We're taking the utmost care to keep it that way.
Analytics & error tracking
We don't want to know your financial details, but in order to improve the app and help you in case of issues, we collect some usage data if you allow us to. Specifically we currently gather:
- your user ID
- page URL which may contain the asset ID
- URLs of network requests (which will contain market asset IDs)
- elements you click (their system ID only)
- system log messages (which may contain market asset IDs)
If you don't allow us to identify you, we won't be storing any of the IDs mentioned above. In such case we just log errors and some very minimal feature usage, in a completely anonymous way, without IDs or detailed logs.
This consent is separate from the functionality-cookie consent, which is what remembers your project selection and your table columns between sessions. Declining analytics leaves those alone; declining functionality cookies is what makes the Demo project reopen every time — see Settings and display preferences.
Things we never gather:
- size or value of your investments
- names, notes or any text you create yourself
- custom quote sources