Trust & security

What is actually built — and what isn't.

Roots HQ is a small platform. What follows is what is actually built, what is done by hand, and what does not exist — with the code behind each claim named, so you can ask us to show you.

15
controls in place
8
with stated limits
4
we do not offer
6
things we don’t claim

Roots HQ is a small platform run by the people who build it. Everything below describes how the system is built. None of it is a certification, an audit result, or a service-level agreement, and nothing on this page has been through outside counsel.

Tenant isolation

One workspace cannot read another’s data. This is the control everything else rests on.

Every query is scoped to one tenant

In place

Tenant scoping is applied by a database-client extension rather than by each query author. Models holding tenant-owned data are listed in one place, and a read or write against one of them without a tenant in context does not fall back to “all tenants” — it is constrained or rejected.

api/src/config/database.ts · api/src/middleware/tenantContext.ts

An unrecognised domain is refused, not guessed

In place

A request arrives on a hostname, and that hostname is looked up to decide which workspace it belongs to. A hostname that is not registered is rejected. It does not fall through to a default workspace, which is the failure mode that turns one misconfigured DNS record into a data leak.

api/src/middleware/tenantContext.ts · api/src/platform/domainProvision.ts

Platform staff sign in separately from your team

In place

The people who run the platform authenticate through a separate identity system with its own roles. They are not members of your workspace and do not appear in your team list.

api/src/platform/auth.ts · api/src/lib/adminSso.ts

When support can look inside your workspace

With limits

Authorised support staff can open a time-boxed session against one workspace in order to help with it. Entering requires a specific permission, a written reason, and expires after 30 minutes. Read-only is the default; making changes needs a second, separate permission. Every entry is written to the platform audit trail with who, which workspace, which mode and why.

What it does not do

  • Support staff CAN see inside a workspace during such a session — we are not going to claim otherwise. What is controlled is who may do it, that they must say why, that it ends by itself, and that it is on the record
  • The audit trail of these sessions is not currently surfaced to the workspace owner in the admin

api/src/platform/router.ts · api/src/platform/support.ts

Signing in

Who can get an account, and what happens when someone tries repeatedly and fails.

Two-factor authentication (TOTP)

With limits

Any user can turn on TOTP two-factor for their own account. Once on, it is checked at every sign-in for that account. When the workspace security policy requires it, every staff sign-in (web, Roots Manager, Roots POS) needs it, and someone not yet enrolled is taken through setup first.

What it does not do

  • The workspace-wide requirement is set by Roots HQ on the workspace policy — a workspace owner cannot switch it on from inside the app yet
  • TOTP only; hardware security keys are not an option for tenant accounts

api/src/routes/auth.ts · api/src/lib/mfaPolicy.ts

Changing a password signs that account out everywhere

In place

A password reset or change immediately invalidates that account’s existing sessions, so a stolen session does not survive the response to it.

api/src/routes/auth.ts

Repeated failed logins lock the account and then block the address

In place

Failed sign-ins are counted per account and lock it after a threshold — the workspace setting or the workspace security policy, whichever is stricter. The lock lifts on its own after a set time, and a workspace admin can lift it sooner. An address responsible for heavy failed-login volume against a workspace is blocked for that workspace automatically; shared satellite (Starlink) addresses are never auto-blocked, because one block would lock out every customer behind them — the per-account lock still applies there.

What it does not do

  • Wrong two-step codes are refused but are not counted toward the lock

api/src/middleware/rateLimiter.ts · api/src/routes/auth.ts · api/src/lib/workspaceSecurityPolicy.ts · api/src/lib/starlink.ts

Idle staff sessions are signed out by the server

In place

A staff session that nobody has used for the workspace’s inactivity limit (one hour by default, or shorter if the workspace security policy says so) is refused and deleted on its next request, web and apps alike. Only a person resets the clock — a change, or a screen touched since the last request; background refreshes do not. Sales queued offline on the POS are kept and sent after the next sign-in.

api/src/middleware/auth.ts · api/src/lib/sessionActivity.ts · api/src/lib/workspaceSecurityPolicy.ts

Who can reach the admin

Restrictions a workspace owner sets for their own team, independently of every other workspace.

Admin IP allow-list, set per workspace

In place

A workspace can restrict admin access to a list of IP addresses it controls. The list is that workspace’s alone. There is a guard against removing the last address you are currently connecting from, so the feature cannot lock its owner out.

api/src/lib/ipAllowlist.ts · api/src/routes/security.ts

Geographic restrictions, set per workspace

In place

A workspace can restrict admin sign-in by country. One workspace’s rules do not affect another’s.

api/src/routes/security.ts · api/src/routes/auth.ts

Role-based permissions

In place

Actions are gated by role, so a staff account does not automatically get owner-level abilities.

api/src/middleware/auth.ts

What gets recorded

What the system writes down when something security-relevant happens.

Audit trail for security-relevant actions

With limits

Sign-in failures, staff changes, password resets, two-factor changes, IP blocks and unlocks, security-setting changes and discount changes are written to an audit trail. A settings entry records WHICH setting changed and never its value, so the log itself cannot become the leak.

What it does not do

  • Covers security and money-affecting actions, not every read of every record
  • Retained in the primary database — there is no separate append-only or off-box audit store

api/src/middleware/audit.ts · api/src/routes/settings.ts

Every AI action is recorded before it is applied

In place

Calyx writes what it was asked and what it proposed to an audit table. Its suggestions are recorded as proposals; applying one is a separate, human action.

api/src/routes/sage/index.ts

Your data

What is stored, what is encrypted, what leaves the server, and how long things are kept.

Stored credentials are encrypted with AES-256-GCM

In place

API keys, OAuth tokens and provider secrets are encrypted before they are written, using AES-256-GCM with a per-value initialisation vector. They are decrypted only in memory at the point of use, and secrets are never written to logs.

api/src/utils/crypto.ts · api/src/platform/secrets.ts · api/src/lib/masterCredentials.ts

Payment records, without card details

In place

Roots HQ provisions and operates your storefront, tracks orders and keeps your business records synchronised. Customer payments are processed through your own connected payment account, and you remain the merchant of record. Roots HQ stores order totals, the processor’s transaction reference, and payment and refund status — the operational record you need to run the business. It does not store raw card numbers, CVV, or equivalent cardholder data: those go from the buyer to your provider, and there is no column anywhere in the schema that could hold them.

api/src/routes/webhooks.ts · api/src/lib/invoicePayments.ts · api/prisma/schema.prisma

Payment webhooks are signature-verified

In place

Incoming payment webhooks are verified against the provider’s signature before anything is acted on.

api/src/routes/webhooks.ts

AI conversation history is deleted after 30 days

In place

Calyx conversation history and its usage log are pruned to a 30-day window automatically, so the assistant’s record of your business does not accumulate indefinitely.

api/src/routes/sage/index.ts

Exporting your data

With limits

An owner can export the contact list and consolidated multi-channel sales as CSV. The export is admin-only and is itself written to the audit trail.

What it does not do

  • This is not a full account export — it covers contacts and sales, not every record in the workspace
  • There is no self-service “download everything and close my account” flow; ask and a human does it

api/src/routes/export.ts

Deleting a workspace

With limits

A workspace can be deleted. Deletion is performed by the platform owner rather than self-service, and it is recorded in the platform audit trail.

What it does not do

  • There is no self-service delete button, and no automatic export of your data before deletion — export first (contacts and sales CSV) or ask us to
  • No published timeline for removal of data from the most recent backups, which age out on the ordinary retention schedule rather than being purged on request

api/src/platform/router.ts

What platform staff can see across workspaces

With limits

Running the platform requires knowing whether commerce is working at all, so a platform-wide total — an order count and a summed seller GMV — is shown on the platform dashboard. It is genuinely aggregate: no individual order, customer or line item, and no per-workspace breakdown. It is restricted to roles holding billing-read permission, which support roles deliberately do not have, and viewing it writes an entry to the audit trail. That figure is sellers’ money taken through sellers’ own payment accounts — it is not Roots HQ revenue and is never presented as such.

What it does not do

  • Platform owners and billing roles can see an aggregate revenue total spanning all workspaces. If that is not acceptable for your business, raise it before you sign up rather than after
  • Support roles get workspace health and counts, but no seller financial figures

api/src/platform/router.ts · api/src/platform/audit.ts · api/src/auth/permissions.ts

Backups and availability

The least flattering section on this page, and the most useful one.

Backups are taken at the machine level

With limits

The server is backed up by whole-machine (VM image) backups at the infrastructure level. Roots HQ no longer runs its own nightly database dumps; they were retired on 28 September 2026.

What it does not do

  • How often machine backups run, how long they are kept, where they are stored and how they are encrypted are managed at the infrastructure level and are not published here

docs/security/2026-09-28-backups-vm-level.md

Routine restore testing

Not offered

The weekly automated restore test ran against the application-level dumps, which were retired on 28 September 2026. There is no routine restore test of the machine-level backups that we can point to, so none is claimed.

What it does not do

  • Whether a machine-level backup restores cleanly has not been demonstrated from this repository

docs/security/2026-09-28-backups-vm-level.md

Disaster recovery

With limits

Recovery means restoring the server from a machine-level backup. That restores the database, uploaded media and server configuration together.

What it does not do

  • No recovery-time or recovery-point objective is published, because none has been measured
  • No standby host; recovery depends on restoring the machine backup

docs/security/2026-09-28-backups-vm-level.md

Public status page

Not offered

There is no public status page. If something is wrong, the honest way to find out today is to ask us, and we will tell you what we know.

What it does not do

  • No uptime history is published, and no historical uptime figure is claimed anywhere on this site

Incident response

Not offered

There is no published incident-response policy, and no contractual notification window. What happens in practice is that the people who build Roots HQ are the people who would contact you.

What it does not do

  • No documented severity levels, response times, or post-incident report commitment
  • Do not treat anything on this page as a service-level agreement — there is none

Breach notification

Not offered

There is no contractual breach-notification window. What we will actually do is tell affected workspaces what happened, what we know, and what we do not yet know, as soon as we understand it well enough to be accurate.

What it does not do

  • No committed notification timeframe. Do not treat this as a contractual undertaking

Reporting a problem

How to reach a human about a vulnerability, and what happens next.

Reporting a vulnerability

In place

Security reports go to the same address as everything else, marked “Security”. A machine-readable security.txt points at it. We will confirm receipt, and we will not threaten anyone who reports something in good faith.

marketing/public/.well-known/security.txt

Stated plainly, because silence reads as yes

Certifications Roots HQ does not have.

Plenty of vendors imply these by never mentioning them. If any of the following is a requirement for your business, Roots HQ does not meet it today, and you should know that before you sign up rather than during procurement.

SOC 2

No SOC 2 report exists. No audit has been performed and none is in progress.

ISO 27001

Not certified, and not pursuing certification today.

PCI DSS

Roots HQ is not PCI-assessed and does not need to be for the way it works: card details go directly to your payment provider, who is. Handing card numbers to Roots HQ is not possible — there is nowhere to put them.

Penetration test

No third-party penetration test or security audit has been commissioned.

A Data Processing Agreement

There is no standard DPA on the shelf. If your business needs one, ask — that is a conversation, not a download, and we will not pretend a signed document exists when it does not.

Legal review of these pages

The terms, privacy and acceptable-use pages were written by the people who built the product. They have not been through outside counsel.

Who else can see data

Subprocessors.

The distinction most vendor pages blur: nearly every integration here runs on credentials you supply. Connecting Square means your Square account, billed to you, under your agreement with them — not ours. Only the rows marked “Roots HQ” are on our account.

ProviderAccountWhat reaches them
Hosting provider
Runs the server the application and its database sit on.
Roots HQEverything, at rest. The database and uploaded files are on this host — not in a third-party object store.
Matomo (self-hosted)
Visitor analytics for the public roots-hq.com website only — not the Roots HQ app, storefronts or the mobile apps. Runs on our own analytics server, not a third-party analytics company.
Roots HQPages visited, the referring site, browser and device details, IP address, and first-party analytics cookies. Not sold, not shared with advertisers, and never used for advertising.
Anthropic
Powers Calyx, the assistant.
Roots HQ
Optional
The text of the question and the business context needed to answer it. Sent only when someone uses Calyx.
OpenAI
Alternative model provider for Calyx and receipt reading.
Roots HQ
Optional
As above — the content of the request being processed.
PayPal, Square
Take card payments from your buyers.
Yours
Optional
Order and payment details. Card details go to them directly and never through Roots HQ.
Stripe
Bills your Roots HQ subscription, once subscription billing is switched on. Not used for your buyers’ payments.
Roots HQYour workspace’s billing contact and subscription details. Card details go to Stripe directly and never through Roots HQ.
EasyPost
Carrier rates, labels and tracking.
Yours
Optional
Delivery addresses and parcel details for shipments you create.
Twilio
Text-message provider, used only if a workspace connects its own Twilio account. SMS is not currently offered.
Yours
Optional
Phone numbers and message content for messages you send.
Your email provider
Delivers the email your storefront sends.
Yours
Optional
Recipient addresses and message content. Roots HQ does not resell email sending.
eBay, Etsy, Meta
Marketplace order sync and social publishing.
Yours
Optional
Order and listing data for the channels you choose to connect.

Found something?

Reporting a vulnerability.

Report anything you find to hello@roots-hq.com with “Security” in the subject. Tell us what you did and what you saw; a proof of concept helps. We will confirm we received it. Please do not run automated scans against the live service, access an account that is not yours, or move data out of one — report it instead and we will take it from there. We do not run a paid bug-bounty program.

hello@roots-hq.com · security.txt

Related: how the security model works · tenant isolation architecture · privacy · terms