BorderFolio/Security & data handling
Security and what happens to your statement
Last reviewed 31 August 2026
A broker statement is one of the more revealing documents a person owns, and uploading one to a small product is a reasonable thing to hesitate over. This page answers the hesitation concretely: what is asked for, what is read from the file, what is kept and for how long, what leaves the server and to whom, who can look at it, and how to remove all of it. Where the honest answer is a limitation rather than a reassurance, it is written as a limitation.
1. Broker credentials are never requested
There is no field for a broker login anywhere in BorderFolio, and no hidden one either: no brokerage integration exists in the codebase at all — no API keys, no read-only tokens, no OAuth connection, no aggregation service such as Plaid or SnapTrade. A portfolio is built in exactly two ways: you upload a document, or you type holdings in by hand.
The consequence worth stating plainly is what BorderFolio therefore cannot do. It cannot place a trade, move money, change a beneficiary or read your account balance. Even a total compromise of this service would not give an attacker a route into your brokerage, because no route exists to steal.
The only optional third-party sign-in is Sign in with Google, which requests the openid email profile scopes — your email address and display name. It grants no access to Gmail, Drive or anything else, and you can use an email and password instead.
A direct Interactive Brokers connection appears on the roadmap. If it ships, it will be an opt-in addition to statement import, never a requirement.
2. What is actually stored from the document
The extractor is looking for a small number of financial facts. Everything else on the page — your name, your address, cash balances, account totals, transfer instructions, bank details — is not a field it writes anywhere.
| From the statement | Kept? | Where it ends up |
|---|---|---|
| Ticker, ISIN, market (MIC), country | Yes | Identifies the instrument you hold |
| Quantity and average purchase price | Yes | Your position |
| Each purchase: quantity, price, date, stated commission | Yes | Contribution history — the record that separates deposited capital from market growth |
| Dividends received in the period, per instrument | Yes | Dividend history and withholding estimates |
| Original file name, upload time, rows extracted, duplicates skipped | Yes | The import journal, so you can see what a past upload did |
| Broker account number printed on the page | No | Read during the import only, to keep two accounts in one document apart. There is no account-number column in the database |
| Your name, address, cash balances, account totals, anything else on the page | No | Not extracted into any field |
Nothing enters your portfolio automatically. Every import stops at a review screen showing what was read, what was skipped as a duplicate and what could not be imported; the data is written only when you confirm it. See how statement import works.
Separately from the statement, an account holds what you gave it: name, email, a bcrypt hash of your password (never the password), optional date of birth, the tax residence and rates you configure, and your plan and usage counters.
3. Is the original file kept?
Yes, briefly, and then it is deleted whether you ask or not.
- The upload is stored in a private Amazon S3 bucket — not public, not listable, not linkable. Nothing in the product serves the raw file back over the web.
- It is kept so that a failed or partial import can be re-run without asking you to find the document again. After parsing, the file itself is no longer needed for anything.
- A scheduled job runs daily at 03:30 UTC and deletes every stored file older than 7 days, regardless of account, plan or activity. Retention is a property of the bucket, not a promise someone has to remember to keep.
- Deleting your account deletes the files immediately, rather than leaving them to that sweep.
What survives the file is the extracted data and the journal entry — the file name, when it was uploaded and how many rows it produced.
4. What leaves the server: AI extraction
Reading an arbitrary broker's layout is done by a language model rather than a per-broker parser, which is why any statement works without a supported-broker list. That has a privacy cost, and it should be stated rather than buried: the contents of the document you upload are sent to OpenAI's API over TLS, so the model can extract the holdings and transactions from it. A PDF is sent as a file, a screenshot as an image, a CSV or text export as text.
Two things bound that transfer:
- OpenAI's API terms state that data submitted through the API is not used to train their models. They act as a processor for this service, not as a recipient of a dataset.
- The request carries the document and the portfolio figures — not your identity. Your name and email address are not part of any prompt. Later analysis of your portfolio (insights, withholding commentary) sends holdings and the tax residence you configured, again without identifying you.
No other third party receives the document or its contents. If sending a statement to an AI provider is not acceptable to you, entering holdings manually avoids it entirely and produces the same portfolio.
5. Encryption, in transit and at rest
- In transit. Every connection to the site, the app and the API is HTTPS over TLS 1.2 or 1.3; older protocol versions are refused, plain HTTP is redirected, and HSTS is set so a browser will not try HTTP again. Traffic to OpenAI, to S3 and to the payment provider is TLS as well.
- At rest — uploaded files. Objects in S3 are encrypted at rest with AES-256 by the storage service.
- At rest — the database. Postgres and the analytics store run on a single private host and are not exposed to the internet: only the web server listens publicly, and the database ports are bound to the loopback interface behind it.
- Passwords. Stored as bcrypt hashes. They cannot be read back, by anyone, including us — a forgotten password is reset, never recovered.
- Backups. The database is dumped nightly to a separate private S3 bucket, encrypted at rest, used only to restore the service after a failure.
On the account side: sign-in and password-reset endpoints are rate-limited per IP address and per email address, sign-up and password reset are additionally protected by a Cloudflare Turnstile challenge, repeated failed logins trigger a captcha, and every upload endpoint sits behind an authenticated, email-confirmed session.
6. Who has access
BorderFolio is built and run by one person — Steffan Kharmaaiarvi, the founder (about). There are no employees, no contractors and no outsourced support desk, so the honest answer to "who could look at my portfolio" is: one named individual with production access, and nobody else.
- The internal admin dashboard shows aggregates and account rows — signups, revenue, subscription state, quota usage, AI cost. It has no screen that opens a user's holdings, contributions or statements.
- Support does not read your portfolio to answer a question. If diagnosing a specific import ever requires looking at your data, you will be asked first.
- Your data is never sold, rented or shared with advertisers or data brokers, and there are no advertising networks or ad pixels anywhere on the site or in the app. Product analytics is opt-in and deliberately blind to portfolio content — see the processor table below.
- Error monitoring records identifiers and stack traces, not request bodies — a crash report does not carry your statement.
7. Deleting a portfolio
In the app, open Manage portfolios and choose Delete portfolio. It takes effect immediately and removes, in one cascade: the positions, the contribution history, the monthly snapshots, the dividend records and the statement journal entries belonging to that portfolio.
The uploaded files behind those imports are already gone, or go with the next daily sweep at the latest. Deleting your only portfolio is allowed on any plan — you land back on the upload screen and can start over. Your monthly import allowance is deliberately not refunded by the delete, so a delete-and-recreate cycle is not a way to reset the counter.
8. Deleting your account
Self-service, in the app: Profile & Settings → Security → Danger zone → Delete account, confirmed by typing DELETE. No email to support, no waiting period, no retention offer. It is irreversible.
What the deletion does:
- Erases the profile — name, email, date of birth, tax residence and rates, settings and plan counters.
- Erases every portfolio and everything under it: positions, cost basis, contribution history, snapshots, dividend records.
- Erases the statement journal and the uploaded files in storage.
- Invalidates all sessions and refresh tokens, so other devices stop working immediately.
- Removes your rows from the analytics store.
- Cancels an active subscription with the payment provider so it stops renewing. It does not itself issue a refund — see the billing & refund policy.
The deletion is built to succeed even when its dependencies do not: if the billing provider or the storage service is unreachable at that moment, your account is still erased and the remaining cleanup is retried hourly until it completes. An outage somewhere else must never leave you with an account you cannot delete.
Two things survive, and both should be said out loud:
- A tombstone row — your user id, a SHA-256 hash of your email address, the deletion timestamp and the reason. No name, no other personal data. It exists so support can confirm an account was deleted and when, and so repeated create-and-delete cycles are detectable. The address itself cannot be recovered from the hash, and it is released for signing up again.
- Database backups. Nightly backups are retained for disaster recovery, so a copy of your rows can persist in an archive after deletion until that archive is superseded. Backups are used only to restore the service after a failure — never to bring a deleted account back.
Access, correction and portability requests under GDPR and comparable laws go to admin@borderfolio.app, as described in the Privacy Policy.
9. External processors
Everything outside this service that touches your data, and what each one gets. Production runs on Amazon Web Services in the United States, so this is where your data is processed regardless of where you live; for EEA, UK and Swiss users that transfer relies on the European Commission's Standard Contractual Clauses.
| Processor | What it receives | Why |
|---|---|---|
| Amazon Web Services (US) | Everything: the application host, the database, uploaded statement files, backups | Hosting and storage |
| OpenAI | The contents of the documents you upload; portfolio figures and your configured tax residence for analysis | Extracting holdings and transactions from an arbitrary statement layout; portfolio insights |
| Freemius | Name, email and billing details you enter at checkout | Payments, subscriptions and licensing. Card details go to the payment provider and are never seen or stored by BorderFolio |
| Cloudflare | Connection metadata: IP address and browser signals, at DNS level and for the Turnstile challenge | DNS, proxying and bot protection on sign-up and password reset |
| Mailgun | Your email address and the contents of transactional messages | Confirmation emails, password resets, monthly reports |
| Sentry | Error reports and application logs: identifiers, stack traces, technical context — not request bodies, not statements | Knowing that something broke before you have to report it |
| Only if you choose Sign in with Google: your email address and display name | Optional authentication | |
| Market data providers | Ticker symbols and exchange codes only | Prices, dividend data, instrument reference and FX rates. A quote request says which symbol, never who is asking |
| PostHog (EU region) | Only if you accept cookies: page views, the channel you arrived from, and named product events. Autocapture and session recording are switched off and event text is masked — no ticker, holding or amount is ever sent | Knowing which pages produce signups. See the Cookie Notice |
The list is exhaustive as of the review date at the top of this page. A new processor with access to portfolio data would be added here, and the page's review date updated, before it goes live.
10. What this page does not claim
Security pages tend to imply more than the product has. These are the gaps, stated plainly, so you can judge the risk yourself rather than discovering the limits later.
- No certifications. BorderFolio has not been through SOC 2, ISO 27001 or an equivalent audit, and has not commissioned a third-party penetration test. A solo product claiming otherwise would be lying.
- Two-factor authentication is not available yet. Until it is, use a unique password — the account is protected by bcrypt hashing, rate limiting and captchas, not by a second factor.
- One operator is a single point of failure as well as a small attack surface. Nightly backups with a documented restore procedure exist for exactly that reason.
- An AI provider sees your statement. That is inherent to reading any broker's format without a per-broker parser. Manual entry is the alternative that avoids it.
- Deleted data can linger in backups until those archives are superseded, as described above.
Found a vulnerability? Email admin@borderfolio.app with enough detail to reproduce it, and expect a reply. There is no paid bounty programme; there is a fast fix and public credit if you want it. Please test only against your own account.