Security
A loyalty balance is money-adjacent. We treat it that way.
Tenant isolation
Every table that belongs to a café carries its organisation, and access is enforced by row-level security in the database rather than by filtering in the application. A bug in a page cannot expose another café’s customers.
An append-only ledger
Loyalty transactions cannot be updated or deleted. Balances are a cached projection of that ledger and can be reconciled against it at any time, so a balance cannot be quietly rewritten — not by a member of staff, and not by us.
Server-authorised stamping
No balance is ever trusted from a client. Every stamp and redemption re-validates the full chain — staff, organisation, branch, program, membership — takes a row lock, and records who did it, where and when.
Protection against double stamping
Every stamp and redemption carries an idempotency key generated before the request and reused on retry. A double tap or a dropped response replays the original result instead of applying it twice, and a reward cannot be redeemed a second time.
Role-based access
Staff get the scanner only. Managers additionally see customers and programs. Owners control billing, staff and deletion. Staff can be scoped to specific branches, and the server refuses every other branch.
Audit trail
Administrative actions — program changes, staff added or disabled, exports, deletions — are recorded with the actor and the before-and-after state, and the log itself cannot be edited or deleted.
Credentials
Wallet signing material, payment keys and database service credentials are held server-side only and never reach the browser.
Reporting a vulnerability
Email security@cafeity.com. We will acknowledge, investigate, and keep you updated. Please give us reasonable time to fix an issue before disclosing it publicly.