CardimSign in

Security

Last updated: 30 August 2026

1. What this page is

This page describes the technical measures Cardim applies today, written from the code as it ships. It is not a contract: the contractual commitments are in the Terms of Service, and what we do with personal data, and on what basis, is in the Privacy Policy.

Cardim is a young product run by a very small team. We would rather say so here, at the top, than leave it to be inferred: section 7 lists what does not exist.

2. Where the data lives

Bookings and customer data live in a Postgres database hosted by Neon in London, United Kingdom, on AWS infrastructure in the eu-west-2 region. The application runs on Vercel, transactional email is delivered by Resend, and error reports go to Sentry. The full list of providers, with what each one is for, is in section 5 of the Privacy Policy.

All traffic is served over HTTPS. Encryption of the storage itself is whatever those providers publish and is not ours to promise; at the application layer, what we encrypt or hash is exactly what the next section lists, and nothing else.

3. Passwords, keys and links

Nothing in this list is stored in a form that a database read makes reusable, with one flagged exception: calendar tokens have to be handed back to the provider, so they are encrypted rather than hashed.

  • Merchant passwords — never stored. We keep the output of scrypt, with a different salt per user, and verification is a constant-time comparison.
  • Password reset links — 32 bytes of cryptographic randomness, and the database keeps only the SHA-256 of the token: reading the database does not let anyone reset anybody's password.
  • Google Calendar and Outlook tokens — encrypted with AES-256-GCM before they are written, under a key ring that allows the key to be replaced without orphaning what is already stored.
  • Sessions and booking links — 128-bit identifiers from the system's cryptographic generator. The session travels in an httpOnly cookie and expires after 30 days.

The link a customer receives by email is itself the authorisation to view, change or cancel that booking — customers have no account and no password. That is why those links, and email addresses, are stripped out of error reports before they leave the application, and why the public forms limit how many attempts one origin may make.

4. What the database will not allow

Two bookings cannot hold the same resource at the same time, and the guarantee does not live in application code: every occupancy row carries its own time range, and a Postgres exclusion constraint refuses any overlap. Two requests arriving in the same instant cannot both win, whatever happens above the database.

A separate trigger stops one customer ending up with two overlapping bookings. For tables and rooms with shared capacity, the head count is checked inside the same transaction, with per-resource locks always taken in the same order so that two simultaneous requests cannot wait on each other.

5. Who can see what

Every dashboard screen queries only the data of the merchant whose session it is, and export and erasure requests require that same scope: one merchant cannot export or erase another's records.

There is an internal console, used to operate the service, whose access is limited to a closed list of email addresses set in the server configuration. When that list is not configured, the console refuses everybody rather than letting anybody in.

6. Retention, erasure and export

A sweep runs periodically and deletes what is of no further use:

  • sessions whose validity has expired — an abandoned session is a live credential for as long as the row exists;
  • temporary seat holds that have already lapsed;
  • rate-limiting records older than 24 hours, which in any case hold a hash rather than the original address;
  • waiting-list entries for dates more than 30 days past, which are a name, a telephone number and an email address belonging to somebody who never became a customer.

Bookings and customers are not deleted on a timer: they are the merchant's business record. Erasure happens on request and is an anonymisation in place — the booking, the time and the amount survive, the person's identity does not, including free-text notes and the mirrored events in a connected calendar. If any of those events cannot be deleted, the merchant is told so rather than reassured.

A merchant may request an export of their data and the complete deletion of the account.

7. What we do not have

This list exists because the alternative is to leave the question unanswered and hope nobody asks it:

  • we hold no SOC 2, ISO 27001 or any other certification;
  • there has been no external security audit and no third-party penetration test;
  • we offer no availability service level agreement, and real availability depends on the providers named in section 2;
  • we run no vulnerability reward programme.

8. Reporting a problem

If you have found a security flaw, write to support@usecardim.com with the steps to reproduce it. We will reply and fix what is within our reach, and we ask that you not disclose it publicly before it is fixed.