Security

How Aikebom is secured.

The short version: guests need no account, and a browser session is anonymous unless a link the guest arrives on identifies them; every event and property is its own tenant, scoped in the application (not yet in the database), staff access is role-scoped, integrations fail closed, and deletion is automated. The mechanisms, plainly, below — and what we store and for how long is on the Privacy page.

No guest accounts

Guests never create accounts or passwords. A session is an HMAC-signed, httpOnly cookie, anonymous unless a link the guest arrives on identifies them: a verified guest link, or a link carrying the client’s own reference for them (such as a ticket number) — not verified, since anyone can edit a link — which staff then see on that guest’s requests. There is no guest password to phish, and none stored to breach — but a verified link is itself a bearer credential: whoever holds it can open a session as that guest until it stops opening. Where a property uses verified guest links (a hotel or resort does by default), the claims ride inside a signed token — at most your booking reference, your name, your room or seat, and a guest tier if the property uses one — and stay with the session the link opens. Each link is issued for one booking and stops opening after a set time: for a link staff create by hand, 30 days unless they choose otherwise (from one day to a year); for one made from the property’s booking records, at most 30 days, and a week by default at check-in. Where the booking system reports the checkout, access ends shortly after the stay.

Tenant isolation

Every event and property is its own tenant. The application is built to scope every database query and every admin action to the tenant and role of the request. Today that rests on our code, its review and its tests, not yet on the database.

Row-level security is enabled deny-all on every one of the application’s tables. That closes them to the database’s public data API — a request made with the project’s public key can read or write none of them — but it is not per-tenant separation: the application connects as the owner of those tables, which row-level security does not restrict. Enforcing tenant separation in the database itself is on our roadmap.

No feature pools one client’s guest conversations into another client’s knowledge or reports. Our platform administrators can see, across clients, the topics guests could not get answered and how often each came up, with the properties and events concerned and a download; we use that to decide what public local facts to add to the shared layer that every property and event in a place draws on. They see a client’s example questions and suggested fixes only one client at a time: when supporting that client, on that client’s own dashboard and reports, as its staff see them.

Role-scoped staff access

Four staff roles, each scoped in the application: platform admin, which reaches every tenant; per-tenant organiser (locked to their own tenant); a front-desk reception role that can see the request queue and work it, see the arrivals list, mint guest links and correct a mis-bound WhatsApp number — and nothing else; and a read-only group console for a client running several properties or events. A role is a scope: each client login — organiser, reception and group console — has one shared password, and can also be given to named people, who sign in with their own Google account or Microsoft work account. We invite them, or a property’s organisers invite their own colleagues. Our Microsoft app asks only for basic sign-in (name, email address, and the identifiers of the person’s account and organisation) and is not yet a verified publisher, so Microsoft marks it unverified; where a client’s IT does not let staff approve an app like ours themselves, they approve it once for their organisation, and can withdraw it at any time, which, like disabling someone, stops only new sign-ins. Approving it lets no one in by itself: each person still needs our invitation. Removing someone, or signing them out, ends their session within about 30 seconds, and a named person’s session lasts at most 8 hours (a shared-password session, 12); disabling someone in Google or Microsoft stops only their new sign-ins. We do not enforce multi-factor authentication ourselves: a person signing in with Google or Microsoft is held to what that account requires, and the shared passwords, which stay on beside named sign-in, have none. Client passwords are stored as scrypt hashes — the platform admin’s is an environment variable, compared in constant time. Sign-in, the password gates, the concierge’s conversations (chat, voice and WhatsApp) and the AI-agent endpoints are rate-limited by a separate service; if that service cannot be reached, the limit lets requests through rather than turning people away — it slows abuse, but it is never what keeps anyone out. Platform administration still has a single shared credential; our platform administrators can also sign in by name. Nothing records which administrator viewed what.

Integrations fail closed

The hotel booking-system (PMS) webhook authenticates with a per-tenant secret, checked before the request body is even read, and rotating that secret shuts the old one out at once whenever our database can be read. Server-side fetches of client-supplied URLs are SSRF-guarded (https-only, private networks blocked, size and time capped). The per-tenant MCP endpoint is off unless we switch it on for a client, and requires a key by default. An integration’s key reaches the tenant’s guest-facing information (its facts, programme, announcements, knowledge and exhibitors, and, where switched on, its partners and their offers) and the public lookups the tenant allows — never guest data. Where a property also runs the guest connection, a guest’s own key reaches, of guest data, only that guest’s own stay, plan and requests; where it is switched on for the property, it can add to their own plan and ask for a service that staff then confirm. Revoking every AI-agent key a tenant has issued — integrations’ and guests’ alike — takes effect everywhere within about five minutes (longer while our database cannot be read), not instantly. Voice infrastructure is self-hosted and its webhook refuses unauthenticated calls.

Deletion on a fixed schedule

Retention (the two models on the Privacy page) is enforced by an automated daily job in the engine itself — not a manual routine, and not a client-adjustable setting. When a guest-data deletion run fails, the admin’s Retention page is built to flag it as “The last deletion run did not finish”.

Application & transport

Connections between your browser and us, and our calls to the AI and other service providers, are encrypted (TLS). So is every connection our code makes to our database, and each one also verifies the certificate of our database provider’s connection pooler. The hop from that pooler to the database itself runs inside the provider’s infrastructure. Security headers include a Content-Security-Policy and a rule that stops other sites embedding our pages, and our code gets automated dependency and security alerts. Hosting runs on Vercel with the database on Supabase (managed Postgres); voice runs on our own dedicated server. The providers that see your conversation text to generate a reply — OpenAI and Anthropic, and the Vercel AI Gateway that routes to them — are used under terms that exclude training on the content we send; the other providers listed on the Privacy Policy operate under their own terms.

Certifications, honestly

We’re a young company and don’t yet hold formal certifications such as SOC 2 or ISO 27001. What we can do today: answer your security questionnaire directly, walk your IT team through the architecture on a call, and sign a data-processing agreement. Ask via hello@aikebom.com.

Reporting a vulnerability

Found something? Please email hello@aikebom.com with details and we’ll respond quickly. We ask for reasonable disclosure time and will credit researchers who report in good faith.

Changes

Last updated: 27 September 2026.