Now with native point-of-sale integration: look up, earn, redeem and reverse on the check.See how it works

The most damaging thing a thief could steal from us is a list of phone numbers.

Card data never touches us

Your customer pays on your register, with your payment processor, exactly as they do today. Bribe sits beside the point of sale, not inside the payment: the register tells us a check closed for a known guest and how much it was for. We never receive, store, process, or transmit cardholder data, so there is no card data on our infrastructure to steal, ever.

PCI-DSS out of scope, by design

Because no cardholder data ever reaches us, Bribe is outside the scope of PCI-DSS. Your point of sale and its processor keep the certifications they already hold; adding Bribe changes nothing about your own PCI posture.

The register has to prove it's the register

Every loyalty message from the point of sale arrives with a credential issued by the POS vendor: a shared secret we compare in constant time, or a signed token we verify against the vendor's published public key. Anything that fails the check is rejected before we read the body. Each check is then deduplicated by its unique check id with a constraint at the database level, so a register that retries a message credits the guest exactly once.

We don't have your password

Customer sign-in is delegated to a dedicated identity provider, which handles password hashing, phone verification, Apple and Google sign-in, account recovery, and session management. Our servers receive an opaque account id; a customer password never appears in our logs, our database, or our memory. Venue staff logins to the dashboard are stored only as salted bcrypt hashes.

PII at rest, encrypted

Phone, email, name and date of birth are encrypted with AES-256-GCM. The master key never lives in the database: it is held in a managed secret store and mounted into the application at runtime; each field is sealed under its own wrapped data key. A database dump on its own decrypts nothing.

Multi-tenant isolation in the database, not the application

Every tenant-scoped table is protected by PostgreSQL Row-Level Security policies. The application role used in production is not a superuser. On every request, the application sets app.current_tenant_id for the transaction, and the database refuses to return rows from any other tenant, even if a SQL-injection bug somewhere asked it to. The wall is in Postgres, not in our application logic.

No money moves through Bribe

Points have no cash value and convert to food-and-drink credit only at the venue's register. Where a venue runs a free picks game, the play credits cannot be purchased, sold or transferred; there is no payment endpoint and the database itself rejects any entry that would create one. Nothing here is worth wiring out.

Right to delete

One button in the app. Your encrypted PII columns are nulled, your sign-in is removed from the authentication provider, your rewards and picks are deleted, your visits are anonymized, and the row is marked deleted, all inside the same database transaction. A minimal compliance audit log of the deletion event itself is retained. Details on the account deletion page.

Compliance

  • PCI-DSS. Out of scope; no cardholder data is ever handled.
  • CCPA-ready. Right to know, right to delete, right to opt out of sale (we don't sell).
  • GDPR-ready. Lawful basis tracked at signup, right to access, right to erasure.
  • CAN-SPAM and TCPA. Every marketing email has a one-click unsubscribe; marketing texts are opt-in only and every one carries a stop instruction.
  • Picks games. No purchase necessary, adults only, verified date of birth, offered only where permitted, governed by published Official Rules.