Security

The least worth stealing

Taper holds your sources, your filters and what you saved. Not what you read. Here is how the rest of it is kept, and what we do not claim.

The short version

The strongest thing about Taper's security is how little there is to steal. A reader's account holds their sources, their filters and what they saved, and nothing else — no article history, no read state, no card.

  • Accounts are kept apart by the database itself, not by the application remembering to filter a query.
  • Your password never reaches our servers. It goes from your browser to our authentication provider, which keeps a hash.
  • Every page and every route is checked for a session before it runs, and the session cookie is verified rather than trusted.
  • Everything is encrypted in transit. Our providers encrypt it at rest.
  • No screen inside the app loads a script from somebody else's server. No tag manager, no chat widget, no advertising pixel, and no payment script — checkout is a redirect to pages Stripe hosts rather than an iframe on ours.
  • The public pages carry Google Analytics, and only for a visitor who accepts it. Decline and nothing of Google's loads.
  • Cloudflare Turnstile loads on the sign-in and sign-up forms when they look automated. It is the only other third-party script on the public site, and it does not run inside the app.
  • Nothing is counted inside the app, at all: the reader's own screens report nothing, and the counter refuses any address under them even if it is asked to. Measurement is a public-site question and stays one — an edition's address is built from a name the reader typed, so a page view from in there would be a record of what somebody reads.

How accounts are kept apart

Every table that holds a reader's rows carries a Row Level Security policy tying each row to the account that owns it, and the database refuses anything else. This matters more than it sounds: isolation does not depend on every query being written correctly, so a mistake in application code cannot hand one reader another reader's rows.

Sources are held per account rather than shared. Two people subscribed to the same address keep a row each, so no account can read another's source list and nobody can rename a publisher for everybody else. That duplication is the point of the design.

The one part of the system that reads across accounts is the background job that keeps the feed cache warm, and it is granted exactly one function, with no ability to act for a reader. Nothing that serves a request runs with elevated privileges.

Closing an account is a single database function that deletes the caller and nothing else — it takes no arguments, so there is no account id for a bug to get wrong.

Signing in

Authentication is handled by Supabase Auth. Your password travels from your browser to them directly and is stored as a hash; it does not pass through Taper's own servers, so there is nowhere in this codebase a password could be logged.

The session cookie is checked by verifying its signature on every request, not by reading what it claims. A cookie is something the person holding it can edit, so it is only worth anything after the signature has been checked — and that check happens before any page or route decides who you are.

The gate is by URL prefix, applied before a request reaches the code that would answer it. An unauthenticated call to the API gets a 401 rather than a redirect, so nothing about the app leaks to a caller without a session.

What a breach would expose

Worth saying plainly, because a page that avoids the question is avoiding it for a reason.

Somebody who got into the database would learn your email address, the list of publications you follow, the words you filter, the names you gave your editions, and the items you saved. That is a picture of your reading interests and we do not pretend otherwise.

What they would not find, because none of it exists: what you read, when you read it, how long you spent, any article Taper fetched but you did not save, your password, or a card number.

The design decision behind that list came first and the security benefit followed. Editions are blended live and discarded because a bounded feed does not need a warehouse — but the smallest system worth attacking is the one that holds the least, and that is the version we ended up with.

Fetching feeds safely

A feed address is something a reader types, which makes it untrusted input pointed at our own network. Every address goes through one guard on its way in, and the same guard is applied to addresses discovered inside a web page and to every hop of a redirect — not once at the top of the flow.

The guard refuses anything that is not ordinary HTTP or HTTPS and anything resolving to a loopback or private network address, so a feed cannot be used to make our servers fetch something inside our own infrastructure.

Pictures are a separate decision. Article and publisher images load in your browser straight from the publisher's own servers rather than being proxied by us, which keeps this service from becoming an open image proxy for arbitrary addresses out of a feed.

What we do not claim

No SOC 2 report, no ISO 27001 certificate, no third-party penetration test to show you, and no bug bounty programme. None of those exist, and a page that carefully avoided mentioning them would be doing so on purpose.

We also do not offer single sign-on, an audit log, or a security questionnaire response. Taper is a reader for individuals, priced accordingly. If you need those things for a company deployment, we are not the right product yet and would rather say so than sell you a plan.

Getting your data out, and closing the account

Export
Your sources come out as an OPML file, from the sources screen, any time and without asking anyone. It is the format every other reader imports.
Deletion
Account settings, at the bottom. It runs immediately, deletes everything hanging off the account in one operation, and cannot be undone. There is no grace period, because a grace period means the data is still there.

Reporting something

Write to hello@taper.news with "security" in the subject. Tell us what you found, how to reproduce it, and what you think it lets somebody do. A rough report that arrives is worth more than a polished one that does not.

We will acknowledge it within three working days and tell you what we are doing about it. There is no bounty — see above — and we will credit you by name if you want it.

If you are testing in good faith, stay inside your own account, do not run anything that degrades the service for other readers, and do not read or keep anybody else's data. Do that and we will not take or support legal action against you for the research.

Where it runs

The database is Supabase Postgres, and the application runs alongside it. Both providers encrypt data at rest and hold their own certifications; ours are the parts described on this page.

Traffic is HTTPS end to end. The app and everything auth-related is served with headers keeping it out of search results, because a reader's editions are not a public document.