All resourcesArticle · Technology & security

Why the room QR is the only thing we trust

An unauthenticated in-room surface has exactly one credential, and every safety property follows from how it is treated.

July 24, 20266 min read

The guest app has no login. A guest scans a code on the desk and is in. That is the right experience and it sets a hard constraint: the code is a bearer token anybody in the corridor can photograph.

So the room bound from the URL is the only input trusted. The stay, the folio and the guest name are always derived server-side from that room, never read from the request. A controller that accepted a folio id from the body would let anyone holding any room's code post charges to another guest's bill — there is no authorisation layer behind it to catch that.

Nothing exposes an internal id. Every bound parameter is a uuid, because sequential ids in a guest-facing URL let anyone walk the property by incrementing a number.

Adding a charge is guarded three ways, and the layer that actually prevents a double charge is a database uniqueness constraint scoped to the room — the caches above it only make a replay quiet. Widening any one of those scopes reopens a cross-room leak.

Every write is throttled, and the AI endpoints most of all, because each one costs a paid provider call rather than a database row.

See it on your own property

A 30-minute walkthrough with your rooms, rates and outlets — no slides.