LUCCAS

Fermentation Tracker · security

How we protect your brewery's data

The system holds your batches, stock, customers, invoices, attendance and customer signatures. Here is what protects them from outsiders, from other breweries and from mistakes.

Layers of protection

Each layer works on its own

From what the browser sees down to the database itself. A fault in one layer does not open the data.

  1. Each brewery sees only its own data

    Breweries are kept apart by the database itself, not only by the app. On every request it checks that you are a member of the brewery the data belongs to. Even if the app had a bug, the database would not hand over another brewery's data.

    Row Level Security on every table

  2. An automatic check on every change to the system

    A test signs in as a user of one brewery and, in every table with brewery data, tries to read, change and delete another brewery's records. If even one row could be read, the test fails. The same test makes sure no new table is added without protection.

    80+ tables · read, update, delete

  3. Team roles

    Owner, admin, brewer, sales and reader. Everyone can change only what belongs to their job, and a delivery driver confirms only the stops on their own run. The rules live in the database, not just on the buttons.

    owner · admin · brewer · sales · reader

  4. Signing in

    Passwords are stored only as a hash the password cannot be read back from, so not even we know them. Sign-in attempts are limited, a Cloudflare check that you are not a robot guards signing in and signing up, and every sign-in and failed attempt is logged. The PIN on the attendance terminal locks for 10 minutes after 5 wrong tries.

    bcrypt · Cloudflare Turnstile · sign-in log · PIN lock

  5. Two-factor sign-in

    Besides the password, a code from an app on your phone (Google Authenticator, Microsoft Authenticator, Authy). A stolen password is then not enough: the database releases the brewery's data only after the code. A brewery can require it of all owners and admins.

    TOTP · checked in the database · required for managers

  6. Encrypted connection

    The app runs over HTTPS only and the browser remembers that, so an unencrypted version cannot be slipped in. The database is encrypted on disk too.

    HTTPS + HSTS · AES-256 encryption at rest

  7. Protection in the browser

    The app cannot be embedded in another site, so nobody can trick you into a fake click. The browser does not guess file types and does not pass addresses with secret links, such as a customer's stock offer, on to other sites.

    X-Frame-Options · CSP · nosniff · Referrer-Policy

  8. Files and signatures

    Scanned invoices, customer signatures and incident photos are kept in private storage. They have no public address and only members of your brewery can open them.

    private storage per brewery

  9. Change history

    Changes to important records are logged: who changed what and when. Issued documents can no longer be rewritten; they are corrected with a credit note.

    change history · locked documents

  10. Daily backups outside the database

    Every night the database and all files are backed up to a separate provider in the EU. The backup is encrypted with a key that none of the providers holds. Before it is stored, each backup is automatically restored as a test and checked that every record is there. Daily backups are kept for 30 days, monthly ones for 12 months.

    nightly · encrypted · EU · test restore

  11. Secret keys stay on the server

    Keys to the database, e-mail and AI never leave the server. The browser only gets a public key, which opens nothing without signing in and the database rules.

    keys kept out of the browser

  12. Security updates

    GitHub automatically watches the libraries the system is built on and warns as soon as a vulnerability becomes known. Security fixes go out first, and every change passes the full set of automated tests before it is deployed.

    Dependabot · automated tests before every deploy

Daily limits

A safeguard against misuse

Some features cost money every time they are used. A limit protects against a stolen account and against a bug stuck in a loop. It counts the last 24 hours per brewery.

FeatureLimitOnce reached
Reading a supplier invoice with AI50 / 24 hThe document can be entered by hand
E-mails to customers (documents, reminders)200 / 24 hSending waits until the next day

GDPR

Where your data is

The data is stored in the European Union. Some providers are US companies, so transfers are protected under the GDPR: by the EU – US Data Privacy Framework or by standard contractual clauses.

ProviderWhereWhat for
SupabaseEU – FrankfurtDatabase, sign-in, files
VercelEU – FrankfurtRunning the app
ResendEU – IrelandSending e-mails with documents and notices
CloudflareEU + globalEncrypted backups in the EU (it cannot read them), bot check on Cloudflare's global network
AnthropicUSAReading a supplier invoice with AI, only when you use it
  • DPAA data processing agreement is ready in Slovak, Czech and Romanian. I will send it on request.
  • 48 hIf your data were ever breached, we would tell you within 48 hours of finding out and help you report it to the authority. The procedure is written down in advance.
  • 30 daysWe tell you 30 days in advance before adding or replacing a provider.

A question about security?

If you want to ask how the system handles your data, or you have noticed something suspicious, write to me.