Security & trust
What we hold, and what we do not
Most of XR never touches a server we operate. It runs on your machine, talks to the model provider you configured with the key you supplied, and writes to a local database. This page is about the smaller part that is ours: the account, team and billing service behind the Business tier.
Never collected, in any tier
Not stored, not logged, not used for training. The audit entry records the model and the token count.
Local-only. A managed model sees the text you send it and nothing else on your disk.
No usage analytics, no crash pings, no session replay — from the app or from this website.
Nothing on your machine stops working when you sign out, cancel, or never sign in at all.
Controls
12 implemented · 4 not yetThe row that matters most is the one that is not green. Team memory is encrypted at rest and in transit with keys we hold, which means we are technically able to decrypt it. That is what “server-side encryption” means everywhere, and language like “end-to-end” is how vendors avoid saying it.
| Area | Control | How you can check |
|---|---|---|
| Transport | TLS 1.2+ everywhere, HSTS with a one-year max-age, no plaintext fallback Certificate issuance is automated; HSTS is set at the edge, not per-route. | Certificate issuance is automated; HSTS is set at the edge, not per-route. |
| Authentication | 15-minute access tokens, rotating refresh tokens with reuse detection Re-presenting a consumed refresh token revokes the entire token family, not just that token — the standard stolen-cookie signal. | Re-presenting a consumed refresh token revokes the entire token family, not just that token — the standard stolen-cookie signal. |
| Authentication | Rate limiting on all authentication endpoints Sign-in emails are limited per address and per source independently; a limit on either alone is trivially sidestepped. | Sign-in emails are limited per address and per source independently; a limit on either alone is trivially sidestepped. |
| Authorization | Role checks re-read from the database on every request A cached role is a stale role. Deleting a member takes effect immediately. | A cached role is a stale role. Deleting a member takes effect immediately. |
| Request integrity | CSRF double-submit tokens on every cookie-authenticated mutation Bearer-authenticated calls are exempt — there is no ambient authority to abuse. | Bearer-authenticated calls are exempt — there is no ambient authority to abuse. |
| Input handling | Schema validation at every route boundary, parameterised queries throughout No string-concatenated SQL, generated by Drizzle ORM; no ORM escape hatches in the codebase. | No string-concatenated SQL, generated by Drizzle ORM; no ORM escape hatches in the codebase. |
| Team memory | AES-256-GCM per fact, key derived per workspace via HKDF-SHA256 The master key is generated per organization and stored only wrapped by a deployment key; the database holds ciphertext and a digest, never plaintext. | The master key is generated per organization and stored only wrapped by a deployment key; the database holds ciphertext and a digest, never plaintext. |
| Relay | The relay cannot read frames — opaque `{iv, ct}` buffers only Keys are exchanged at device pairing and never reach the relay. There is nothing legible to log, which is why nothing is logged. | Keys are exchanged at device pairing and never reach the relay. There is nothing legible to log, which is why nothing is logged. |
| Audit | Hash-chained audit log of administrative actions and data access Each entry commits to its predecessor. A deletion or edit breaks the chain and the verify endpoint reports where. | Each entry commits to its predecessor. A deletion or edit breaks the chain and the verify endpoint reports where. |
| Payments | No card data ever reaches our servers Checkout and the customer portal are Stripe-hosted; we store identifiers, never instruments. | Checkout and the customer portal are Stripe-hosted; we store identifiers, never instruments. |
| Audit | Audit entries are read-access only where it matters Model prompts are never written to the log. The detail field records the model identifier and the prompt length, and the test suite asserts the prompt is absent. | Model prompts are never written to the log. The detail field records the model identifier and the prompt length, and the test suite asserts the prompt is absent. |
| Data lifecycle | Erasure by verified request — the email path is documented; no self-serve delete is shipped Deletion runs through the Data Rights Request path (privacy@xr.rrrtx.ai); the privacy policy describes the same path the product implements. | Deletion runs through the Data Rights Request path (privacy@xr.rrrtx.ai); the privacy policy describes the same path the product implements. |
| Governance | SOC 2 Type I In progress. Controls are implemented and evidenced above; the remaining work is an independent auditor's opinion on their design. | In progress. Controls are implemented and evidenced above; the remaining work is an independent auditor's opinion on their design. |
| Governance | Penetration test by an external firm Scheduled. Until it is done, we describe the security posture as reviewed, not tested. | Scheduled. Until it is done, we describe the security posture as reviewed, not tested. |
| Team memory | Per-message end-to-end encryption Not in v1.0.0. Team memory is encrypted at rest and in transit with keys we hold — which means we can decrypt it if compelled to. Claiming otherwise would be false, so it is stated plainly here and in the docs. | Not in v1.0.0. Team memory is encrypted at rest and in transit with keys we hold — which means we can decrypt it if compelled to. Claiming otherwise would be false, so it is stated plainly here and in the docs. |
| Governance | SOC 2 Type II Not attempted for v1.0.0. Type II observes controls over a period of months, which cannot be done retroactively for a release that is days old. | Not attempted for v1.0.0. Type II observes controls over a period of months, which cannot be done retroactively for a release that is days old. |
Sub-processors
Four, and each one is only reachable because a customer action calls it. If you never invite anyone, enable SSO, use managed models or export an audit log, three of these never see a byte of yours.
| Provider | Purpose | What it sees |
|---|---|---|
Stripe United States / Ireland | Payment processing, invoicing, customer portal | Organization name, billing email, seat count, payment instrument (held by Stripe, not us) |
Cloudflare (R2) Global edge, with a selectable jurisdiction | Storage for audit-log exports you request | The export file itself, encrypted at rest, served over a short-lived signed URL |
Postmark United States | Transactional email — sign-in links and invitations | Recipient address, the message body. No marketing mail is ever sent. |
Your model provider Per that provider's terms | Only if you use managed models and only for the requests you send | The prompt you submitted, to whichever provider you selected — OpenAI, Anthropic or Google |
When you cancel
- day 0 — team services stop. Every member’s local XR behaves exactly as it did before the trial, because none of it depended on us.
- day 0–30 — data is retained and fully exportable. Team memory in plaintext JSON, audit log as CSV.
- when you ask — erasure by verified request (privacy@xr.rrrtx.ai, subject “Data Rights Request”), confirmed by email. Not archived, not “retained for legal reasons” once erased.
Reporting a vulnerability
Mail security@xr.rrrtx.ai, or read /.well-known/security.txt. We acknowledge within two business days and we will tell you what we concluded, including when the conclusion is that we disagree.
There is no bug bounty in v1.0.0. We will credit you in the release notes if you want the credit, and we will not pretend a credit is a payment.
One more thing about trust
The most common way a security page becomes a lie is a company shipping a local-first product and then quietly making the local part worse. So it is worth noting where the incentive points: the Business tier is $15 per user per month for services that run on our infrastructure. There is no revenue in degrading the free build, and the licence check is a signed token verified offline against a key compiled into the app — no phone-home, no grace-period shenanigans, and no remote switch that could turn anything off.