Skip to content

Security

Tax records carry weight. We handle them like they do.

Four lines we won't cross, six controls underneath them, and a published stack so "where does the row actually live?" has a one-line answer.

A close-up of a fingertip on a fingerprint reader, lit by soft daylight.

What we lock in

Four lines, plainly stated.

Read-only bank access

We have read-only access to your bank data. We cannot move your money.

Your SARS password stays yours

Your SARS password is never shared with us.

24-hour deletion

Your statements are deleted within 24 hours of processing.

Data resident in South Africa

All your data stays in South Africa.

Underneath the four

Six guards keeping each line honest.

Column-grade AES-256-GCM at rest

Tax numbers, ID numbers, transaction amounts, descriptions, counterparties, and tax workings are encrypted column-by-column. A leaked database dump on its own is useless. The master key lives in Vercel project secrets, never in the source tree.

Per-user query isolation

Each read against the database is scoped by the authenticated user id from the session. An internal bug can't quietly cross account boundaries; the sealed log catches any read that tried.

Sealed log, joined by hash

Every move on your account is logged with timestamp, actor, target, and a chained hash. Updates and deletes raise an exception at the database, not a silent overwrite. The chain is what makes 'we sealed this' a verifiable claim, not a marketing line.

Passkey-only sign-in

No passwords to lose. WebAuthn passkeys via Better Auth — your device, your biometrics — plus an email OTP fallback. A second factor is forced before a new bank drop, before a return is sent, and before payout details change.

Statement PDFs: 24-hour shelf life

PDFs are read in-request, never persisted to long-term storage — the parser pulls the lines, then the buffer is dropped. Only the derived transaction rows live on. Nothing PDF-shaped sits in our infrastructure waiting to leak.

Logging without your numbers

Sentry and our app logs run a scrubber over every payload before it leaves the process: ID numbers, tax numbers, amounts, descriptions — all wiped at the boundary. Stack traces never carry your data with them.

The stack

The exact rooms your row sits in.

Most local SaaS shops either quietly send tax data offshore or stay deliberately fuzzy about it. We'd rather post the actual stack — including where it is now, and where it's moving to.

Database
Postgres on Neon · eu-central-1 today, moving to the SA region the moment Neon opens it
Statement PDFs
Processed in-request, never persisted — no long-term object store
Application runtime
Next.js 15 on Vercel · default region iad1
Transport
TLS 1.3 only
Sign-in
Better Auth · WebAuthn passkey + email OTP
Bucketing engine
OpenAI gpt-4o (Responses API) · not trained on your data

Spotted a hole?

Send it to security@taxup.app. Forty-eight-hour acknowledgement promise. A formal bug-bounty programme follows public launch; in the meantime we'll thank you by name on this page if you say it's okay.

Check us. Then sign up.

We publish the model on purpose — read it, poke at it, and if you're comfortable, open an account.