Privacy and security
Broker statements and tax returns are some of the most personal data you have. TaxReporter is designed so that this data never leaves your device. TaxReporter has no release yet, so this page describes how it is being built. You can run it from source to try it, as a draft to check.
What your files contain
Section titled “What your files contain”Broker exports can include, depending on the broker:
- your name, address and account number;
- order and transaction IDs;
- every trade, with its date, security, quantity and price;
- dividends and the tax withheld from them;
- deposits, withdrawals and cash balances.
The XML files TaxReporter produces will contain your tax number and name, and the details of every sale and dividend you report.
Together they give a detailed picture of your finances. That is why TaxReporter will never ask you to upload them.
Why everything runs on your device
Section titled “Why everything runs on your device”- No server. TaxReporter has no backend. The browser app will be a set of static files: once loaded, it will read your files inside your browser and build the XML there. The command-line tool will work the same way on your computer.
- No accounts, no analytics, no telemetry. There will be nothing to sign up for, and the app will not report how you use it.
- Almost no network requests. The app will include Banka Slovenije’s exchange rates, which are the same for everyone and contain nothing about you, so loading the app will be the only request it needs. The only other request will be the optional AI check described below, and only if you turn it on. The code that reads your files will never use the network.
- Nothing saved behind your back. What you load will stay in memory while the app is open. Nothing will be stored unless you choose to save or download a file.
- Checked by a test. The plan includes an automated test that fails if the app makes any network request while it imports files.
You do not have to take this on trust. The source code is public, and your browser’s developer tools show every request a page makes.
If you prepare returns for clients, this also means their data is not handed to another company.
When another website frames the app
Section titled “When another website frames the app”A website can show a page from another site inside a frame on its own page. A web server can
forbid that with the frame-ancestors rule of a Content Security Policy, but only in a header it
sends with the page. GitHub Pages, which hosts this site and, when one is published, the preview
of the browser app, sends no custom headers, and a policy written into the page itself cannot
carry that rule. So any website can put the app in a frame.
So the browser app is being built with a frame guard, which a published preview carries too and the finished app will keep: when it finds itself inside a frame, it does not start. The frame shows a short note and a link that opens TaxReporter in its own tab instead.
This is defense in depth, not a guarantee. The guard does not stop another site from framing the page; it only keeps the app from starting there. It is part of the app’s own code, not a rule the browser enforces, so it runs only where the app’s code runs: a frame that turns scripts off stops the guard and the app alike. These documentation pages have no guard and can be framed too.
The exposure is small. The app has no account and no backend, and it sends nothing anywhere, so there is no login for a framing site to misuse and nothing it could make the app send. A site that frames a page from another site cannot read what that page shows or what you type into it.
That last protection does not hold for pages on the same origin (the same scheme, host and
port). GitHub Pages serves this site, the app when it is published, and every other Pages
site of the same GitHub account from one origin, https://<owner>.github.io. A page on that
origin can open the app in a new window and read everything it shows, a tax number and your
broker rows included, while you use it. Neither the frame guard nor the app’s Content Security Policy can stop it:
the guard only keeps the app from starting inside a frame, and the policy trusts its whole
origin. This site loads nothing from other sites, but the account’s other Pages sites are not
part of this project. The way to close this is to serve the app from an origin of its own, a
custom domain or a GitHub account or organization that hosts nothing else
(ADR 0009).
The optional AI check
Section titled “The optional AI check”A later version is planned to offer an optional “second opinion” from a large language model (LLM). It could point out things that look odd, such as a sale with no matching purchase or an unusual withholding rate. It is planned to work like this:
- Off by default. TaxReporter will work fully without it.
- Your own API key. You would use your own account with an AI provider. The project provides no key and runs no service in between. The first planned provider is Anthropic (Claude); others may follow.
- A redacted summary, shown first. Only a summary would be sent: figures per security, holding periods, the exchange rates used, and any problems found. Your tax number, name, address, and account and order numbers would never be included. You will see exactly what would be sent, and nothing goes out until you confirm.
- Sent straight from your device to the provider you chose. The provider’s own terms and privacy policy apply to that request.
- Advisory only. The findings would appear as warnings next to TaxReporter’s own results. They would never change a calculated number or the XML files.
- Your key stays with you. The browser app would keep it in memory, or save it in your browser only if you ask it to. The command-line tool would read it from an environment variable. It would never be logged.
Reporting a security problem
Section titled “Reporting a security problem”If you find a security problem, for example a crafted broker file that makes TaxReporter run code, send data somewhere, or write a wrong value into the XML, please report it privately. Do not open a public issue.
Use GitHub’s private vulnerability reporting: open the repository’s Security tab and choose Report a vulnerability, or go straight to the reporting form. Only you and the maintainers can see the report. Please include the steps to reproduce the problem, and use made-up data instead of your real files.
About this website
Section titled “About this website”These pages are a static site hosted on GitHub Pages. The site itself uses no analytics, no cookies and no third-party scripts. GitHub, as the host, processes visitors’ IP addresses; see the GitHub General Privacy Statement.