Security
Controls that exist in code, described by what they do rather than by what they are called — and a section naming the ones that are not built, because a security page listing only strengths tells you nothing except that it left things out.
Passwords are Argon2id hashes
Hashed, not encrypted — there is no key that turns one back into a password, so a forgotten one is replaced rather than retrieved. Nobody here can read yours.
Two-factor is compulsory for owners and managers
Not offered — required. Somebody in one of those roles who has not enrolled is held on the account screen and cannot reach the console. These are the roles that can void a bill and release a table with money owed.
A terminal PIN is a different secret
Separately hashed, never the password. A password is typed once per shift in a back office; a PIN is typed on a tablet in front of guests, where it will be watched. Shoulder-surfing one does not yield the other, and three wrong PINs lock the terminal and say for how long instead of pretending the PIN was merely wrong.
A guest holds no credential at all
Scanning a table card opens a session on the server naming that table. The browser holds a session cookie and nothing else. A token the guest carried would be a token the guest could edit.
Every sign-in is written down, so you can see where your account is signed in and end any of those sessions — and so can we, during an incident, without changing your password out from under you. An integration token is stored as a hash; the token itself is shown once, at the moment it is created, and never again.
Rate limits
Held in the database rather than in memory, so they survive a restart and every process sees the same counter. A real person mistypes a password three times; a script tries three thousand.
Per account.
Per account.
Per address.
Per table.
Per table.
Per table. The tightest of the three, because it is the only one that raises a manager's notification directly.
Per device.
A limit is not a substitute for a write that behaves. The same change that tightened the rating bucket also deduplicated the write — one rating per sitting — and moved the manager's notification so that it fires on a changed rating rather than on every press. A bucket that permits four presses should still not produce four rows and four warnings.
Two gates, and they answer different questions. One asks whether this person's role may press this thing. The other asks whether this row belongs to this venue at all. A system with only the first is a system where a correctly-signed-in manager can read another restaurant's takings.
The venue gate is enforced at the query layer rather than in each screen, so it applies to a path nobody remembered to think about. A build-time rule flags a read on a venue-facing screen that reaches past its own venue, which is how the class of mistake gets caught rather than the individual mistake.
A control that is drawn but refuses when pressed is a bad control. A button a role may not press is not rendered for that role in the first place, and the refusal behind it exists anyway — because a screen is a convenience and the server is the rule.
Every privileged or financial action writes a row, and each row's hash is computed over the row before it. Signing in and failing to, a PIN failure, a role or permission change, a price change, a void, a refund, a discount above the ceiling, releasing a table unpaid, a drawer adjustment, a shift closed with a variance, a bill reprint, a data export, a support session starting and ending — all of it, with who, what, how much, before and after, the reason, the approver, the terminal and the time to the millisecond.
Verification does not merely walk the chain. It recomputes each row's hash from that row's own contents and compares, so an edited row is reported as tampered rather than slipping through because its link still matches. Deleting a row or reordering two of them breaks the chain and is reported separately, naming the row it broke at.
The boundary, stated so you know which side you are on
Recomputing needs the exact bytes that were hashed, and one field was not stored before the migration that added it. Rows older than that keep link-only cover: deletion and reordering are detected, an edit is not. They are deliberately not rewritten — re-hashing history to make a report look clean is the one operation an append-only ledger must never perform.
The most dangerous capability any platform has, so it is constrained hard — and every constraint below is enforced in code, not promised in a document.
An operator asks. Only an owner of your venue can say yes, and the request lapses if nobody answers within fifteen minutes. A refusal is recorded too — a request that was refused should still be something you can point at.
The grant carries its own expiry and it is enforced when it is read, not when a sweep happens to run. A session cannot outlive its approval by waiting.
The controls that deny or revoke a session keep working while the session is live. A control the subject cannot operate is not consent.
Recording a payment, voiding, refunding, cancelling a settled bill, releasing a table unpaid and adjusting a drawer are all refused for the duration. Ask the venue to do it, or leave first.
Where no owner is reachable, a second operator co-signs, the session may look and never touch, and it runs fifteen minutes instead of thirty. The requester cannot be their own second pair of eyes.
The request, the answer, the entry and the exit are written into your venue's own audit trail, where you see them.
There is no key-management service and no external secret store. The application key is a file on the host, denied over HTTP, and what depends on it is written down. That is a smaller claim than most security pages make, and it is the true one.
This is the section most security pages do not have. It is here because the rest of the page is only worth reading if this one exists — and because a buyer weighing us against something larger deserves the real comparison rather than a flattering one.
There is no alerting system yet. An incident is found by a person looking, which means the time between something happening and somebody noticing is not bounded by anything. This is the largest open item on the page.
Incidents are recorded internally and there is a screen for them, but nothing public reads it. So today you would hear from us directly rather than see it on a page.
Which is why the terms carry no availability commitment. A percentage would be invention dressed as telemetry.
There is no re-encryption path. Rotating would mean every enrolled authenticator re-enrolling, so it is a planned operation rather than a routine one.
One database, no cold storage. The retention sweep is written so that the missing tier costs data nobody agreed to lose rather than quietly losing it — the privacy policy explains the arithmetic.
The drivers are written and tested against published documentation. None has been exercised against a live merchant account, and going live is refused until credentials have been verified with a real read against the acquirer.
Two things this page does not claim, which similar pages usually do: an independent penetration test, and a tested disaster-recovery target. Neither has happened. When one does, it will appear here with a date on it.
If you have found a vulnerability, tell us before you tell anybody else and we will not come after you for it. That safe harbour has two conditions and they are the only two: do not access another venue's data, and do not degrade the service for the rooms running on it.
Acknowledgement within 24 hours, triage within 72, and a fix timeline that follows the severity rather than the calendar.
Everything else about reaching us, including which channels genuinely exist, is on Contact.