Security

Last updated 18 September 2026

In short

No badges, no vague reassurance. This is what is there and how it works.

Your password

We do not store your password. What sits in the database is a hash made with argon2id, at the settings OWASP recommends: 19 MiB of memory and two passes. Argon2id is deliberately slow and memory-hungry, so someone who made off with the database could not compute their way through it.

In practice that means we cannot read your password, cannot send it to you and cannot give it to anyone else. Forgotten it? We set a new one; we cannot look up the old one.

The breached-password check

When you choose a password, we check whether it appears in a known breach. That happens without sending your password anywhere.

It works like this: your password is hashed locally and only the first five characters of that hash go to the service that tracks breaches. It sends back every hash starting with those five characters, hundreds of them, and the comparison happens on our server. So the other side never learns which password it was, or even whether there was a match.

If that service is down, your registration goes ahead anyway. Somebody else’s outage must not stop you making an account.

In transit

All traffic between the app and the server goes over TLS. There is no unencrypted variant to fall back to; a request over plain HTTP is redirected to the encrypted one before any content crosses the wire.

Signing in and staying signed in

You stay signed in with two kinds of token: a short-lived one for making requests and a long-lived one for renewing the first. The second is replaced on every use. If a spent token is presented again, which cannot happen by accident, we treat it as theft and end every session on that account at once.

On every request we also look the account up in the database again. That is what makes deleting an account take effect immediately, rather than whenever the last token happens to expire.

Who can reach what

The database separates users. Every beer, batch and group hangs off exactly one account, and the app never asks for anything without that account attached. A shared collection or a trade is an explicit exception you switch on yourself, and it gives access only to what you share.

The catalog is the one thing everybody sees, and that is the point: it holds facts about beers, not about people.

Stopping abuse

Signing in, registering, password resets and sending mail all carry limits per address and per IP. They are there to stop somebody guessing passwords or flooding a mailbox. A refused request does not say which limit was hit, because that would give something away in itself.

Beyond that, no answer from the server reveals whether an email address has an account. Registering with an existing address gives exactly the same answer as registering with a new one. The difference appears only in the mailbox of the person entitled to know.

Backups

Every night the database is dumped and then immediately read back to check that the dump is usable. A backup nobody knows works is not a backup. We keep fourteen daily and twelve monthly copies, and the restore procedure has been carried out for real once, against a separate database.

Where it lives

The server and the mail are within the European Union and fall under the GDPR. No data goes anywhere outside it.

Public lists are public

A list with a public code is meant to be found. It has its own address, it is listed in the directory, and it is indexable by search engines. There is no second switch that makes a public list unlisted: publishing one is the decision, and taking the code away in the app is how it is undone.

That is a change. The share page used to carry noindex and the code used to sit in the part of the URL that never reaches a server. Both were there to make a public page hard to stumble across, and a directory is the opposite of that.

Two things were kept when the code moved into the address, because they protect the link rather than hide the page:

Private sharing is untouched by all of this. An invite code is not a public code: those lists are not in the directory, not indexed, and reachable only by the people you invited.

What a public page shows

Whatever the owner shared: the list’s name, their display name, and the beers in the locations they chose. Not their email address, not their account, and not anything they did not put in that list.

If something on a public page should not be there, there is a report link on the page itself. It needs no account and records nothing about you.

What this does not claim

Fair is fair. These are the things the section above does not assert, so you do not have to assume them:

Found something?

If you spot a hole, write to cheers@back.beer. Tell us before you tell anyone else, give us the chance to fix it, and do not pull other people’s data to make your point. We will answer, we take it seriously, and we will say what we did about it.

This page was written in Dutch. This English version is a translation provided for information. If the two differ, the Dutch text is the binding one.