The most damaging thing a thief could steal from us is a list of email addresses.

Card numbers never touch us

When a customer links a card, the actual card number stays inside the card company's vault. We receive a token — a useless string of letters that only works for matching transactions at the specific venues that opted in to our program. The token is meaningless outside that closed loop. There is no card data on our infrastructure to steal, ever.

PCI-DSS out of scope, by design

We never receive, store, process, or transmit cardholder data. The Fidel SDK handles that side of the wall — their PCI-DSS Level 1 environment is certified and audited. Our role is to match the resulting tokens to merchant locations and issue rewards. We maintain a PCI-DSS SAQ A self-assessment to confirm we remain out of scope.

We don't have your password

Sign-in is delegated to Firebase Auth, which handles password hashing, two-factor authentication, account recovery, and session management. Our servers receive a customer UUID; the password never appears in our logs, our database, or our memory.

PII at rest, encrypted

Email and phone are encrypted with AES-256-GCM. Encryption keys are envelope-encrypted under AWS KMS root keys — a fresh Data Encryption Key is generated per tenant, the DEK is encrypted with KMS, and only the encrypted DEK is stored alongside the ciphertext. Decryption goes through KMS with full audit logging. DEKs rotate on a regular cadence.

Multi-tenant isolation in the database, not the application

Every tenant-scoped table is protected by PostgreSQL Row-Level Security policies. The FastAPI 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.

Webhooks: signed, deduplicated, idempotent

Every inbound Fidel webhook is signature-verified using double HMAC-SHA256 before we read the body. Every transaction is deduplicated by its Fidel transaction ID with a unique constraint at the database level — replays are no-ops. The webhook endpoint persists the event before returning 200, so a network blip can never lose a transaction.

Right to delete

One button in the app. Your encrypted PII columns are nulled, your linked cards are detached, your transactions 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.

Compliance

  • PCI-DSS SAQ A. Self-assessed and maintained.
  • 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. Every marketing email has a working one-click unsubscribe.