Security
How GrandStay protects hotel and guest data — the controls we actually run, and the ones we do not yet have.
Last updated
Tenant isolation is enforced in the database
A hotel must never see another hotel's data, and hiding it in the interface is not sufficient — anything the browser can request, a determined user can request directly. Every tenant-scoped table in GrandStay carries a property identifier and a row-level security policy that filters on it. The database refuses cross-tenant reads and writes regardless of what the client asks for.
The policies are covered by an automated test suite that runs as real users against a real Postgres instance and asserts that one tenant cannot reach another's rows. A change that would weaken isolation fails the build.
Privileged operations are gated on the server
Operations like check-in, check-out, posting a folio charge, taking a payment and editing a reservation run as database functions with elevated rights, which means row-level security does not protect them from the inside. Each therefore carries its own checks in the function body: that the caller belongs to the property, that their role grants the specific permission, and that the record is in a state where the operation is legal.
These guards are tested against a full replay of the migration chain, including the cases that matter operationally — a stale check-out must not release a room a new guest has since occupied, and a clerk without the check-in permission must be refused by the database even if the button is somehow reachable.
Payment credentials are encrypted at rest
When a property or partner connects its own payment gateway, the secret is encrypted before storage using a key held outside the database, and is never returned to the browser in full — the interface shows only enough to identify which key is configured. Card numbers themselves never reach our servers: card entry happens directly with the payment provider.
The audit log is tamper-evident
Operational actions are written to an append-only audit log in which each entry incorporates a hash of the one before it. Altering or removing a historical entry breaks the chain and is detectable on verification. The log cannot be edited through the product by anyone, including us.
Financial periods can be locked once closed, in the property's own timezone, so a night audit cannot be rewritten after the fact.
Access control
Staff access is governed by role templates that grant named permissions rather than broad tiers, and the gate is applied on the server as well as in navigation — reaching a page by typing its URL does not bypass it. Sessions expire after inactivity, with a warning before they do. A property suspended for non-payment loses back-office access immediately rather than at the next login.
Application hardening
- State-changing requests carry a CSRF token.
- Sensitive endpoints are rate limited server-side, including one-time-password flows.
- Payment operations are idempotent: a retried or double-submitted request replays the original result rather than charging twice.
- Booking creation takes a row lock and re-checks availability inside the transaction, so two simultaneous bookings cannot oversell the same room.
- Errors are reported to our monitoring with record contents scrubbed.
Data protection and backups
Data is encrypted in transit with TLS and at rest by our infrastructure provider. Backups are taken on a schedule and stored separately from the live database. The desktop application keeps a local encrypted store so a property can keep operating through a network outage, and reconciles when connectivity returns.
Guest identity documents are the most sensitive data the system holds. They are stored in access-controlled buckets, scoped to the property that collected them, and should be deleted by the property once its local retention period expires.
What we do not have yet
We would rather tell you this than have you discover it during procurement:
- No SOC 2 or ISO 27001 report. We have not completed a third-party audit. The controls above are real and testable, but they are not independently certified, and we will not claim otherwise.
- No public bug bounty. We accept and act on reports, but we do not currently pay for them.
- No published penetration test. If your procurement process requires one, contact us and we will discuss scope and timing rather than send you someone else's report.
If a control you need is missing, say so before you sign. It is far easier for us to plan for it than to retrofit it after a deployment.
Reporting a vulnerability
Email security@grandhms.com with enough detail to reproduce the issue. We will acknowledge within three business days and keep you updated until it is resolved.
Please test only against your own account or a demo tenant, do not access or modify data belonging to another property, and give us a reasonable window to fix an issue before disclosing it. We will not pursue legal action against researchers who follow that.
If something goes wrong
If a breach affects your data we will notify you without undue delay, with what we know, what we are doing and what you should do. Where we act as your processor we will support you in meeting your own notification duties to regulators and to your guests.