Security and data handling
What BuyerClear stores, how it is protected, who can reach it, and what leaves your shop.
Updated 7 September 2026. This page describes the latest pilot version. Report a security issue to security@buyerclear.com.
Where everything runs
BuyerClear’s application and separate Registry service run on Cloudflare Workers. D1 holds application records, R2 holds uploaded documents, Workers AI reads documents and Cloudflare Email sends messages. Buyer-facing pages load no analytics or third-party scripts. The Registry Worker alone calls enabled official-source endpoints.
What is stored, and how
Buyer names, contact details, credential numbers, uploaded files and full evidence payloads are encrypted in application storage, with AES-256-GCM under a key held as a Worker secret. Each field is sealed to its own scope, so a ciphertext lifted from one shop’s business name cannot be opened as another shop’s email: the scope is bound into the encryption itself, and a mismatch fails rather than returning something plausible.
| Data | How it is held |
|---|---|
| Business name, contact name, contact email | Encrypted per field and per shop. |
| Credential number, holder name and professional licence details | Encrypted. The number is never stored in the clear. |
| The uploaded document | Encrypted object in R2, deleted on the shop’s retention schedule. |
| Reading and registry results | Full payloads are encrypted. Source identifiers, query times, status and expiry used for scheduling are stored separately without application-level encryption. |
| Shopify access tokens | Encrypted, never logged, never returned by any page. |
| Lookup and operational metadata | Keyed hashes for email and credential lookups; shop and record identifiers, jurisdiction, status, expiry and processing times are not field-encrypted. This metadata may still relate to a person. |
| Decisions and the audit trail | Kept after the document is deleted, because the record of who decided what has to outlive the evidence. |
The audit trail
Audited actions are recorded as events, and each event carries the hash of the one before it. A missing or altered event breaks the chain, and the page that renders the history refuses to show a broken one rather than quietly skipping the gap. The database enforces that an event can have only one successor, so two things happening at once cannot fork the record.
Who can see what
- Merchant staff reach the app through their Shopify session. Staff review routes require a current session and scope application queries to the staff member’s shop. Buyer status pages use a separate private-link flow.
- Notifications direct staff to Shopify Admin. A current Shopify staff session and an explicit protected action are required to decide; legacy bearer review links no longer authorize reviews.
- A buyer reaches only their own application, through a private status reference (100 bits of randomness for newly issued references; older references remain valid). The status page shows the state and a masked address; opening the prefilled update form also asks for the address on the application. Matching an address does not verify ownership of the email account; the link must remain private.
- Nobody at BuyerClear reads a document as part of normal operation. Support work happens against identifiers, never against decrypted content.
What we ask Shopify for
Of Shopify’s protected customer data, BuyerClear requests a single field: the customer email, used to attach an existing store customer to the company it creates. Name, phone and address are not requested. The scopes it holds are listed in the documentation, each with what it is used for.
What we send to registries
The application sends the Registry Worker the credential number, kind and jurisdiction, plus the licence class and issuing authority for scoped professional checks. The Worker receives no name, email, document, shop identity or application identifier. It has no database or object-store binding, does not persist lookup bodies or results, returns Cache-Control: no-store and keeps credential values out of logs. An enabled official endpoint receives only the fields needed for that lookup.
Logs
Nothing that identifies a buyer is logged: not the document, not what was read out of it, not a credential number, not a token. Unexpected server failures log a route with private references removed and bounded error classifications. Raw exception messages and provider response bodies are omitted.
Retention and erasure
- Documents are deleted on the shop’s schedule, counted from submission. The default is 90 days.
- Shopify’s privacy webhooks are executed, not merely acknowledged. A customer redaction erases that buyer’s applications, credentials and documents; a shop redaction erases the shop. Object bytes go first, so nothing survives in storage after the rows are gone.
- An erasure request that matches nothing is recorded as matching nothing, rather than as a completed erasure.
Abuse and availability
The pages a buyer reaches without signing in are rate limited by address: five submissions and thirty status views a minute. Uploads are capped at 10 MB and the file type is decided by the file’s own signature, not by what the browser claims. A registry that is slow or unreachable never blocks a decision; it becomes a flag for a person.
What we do not do
- No automatic approval.
- No sale of buyer data or sharing for advertising. Data is processed by the services described above and shared with the merchant’s Shopify store to provide the application.
- No tracking scripts, no advertising pixels, no session recording.
- No credential data used by BuyerClear to train a model. Document reading uses Workers AI; see Cloudflare’s data-usage policy.
Reporting a problem
Write to security@buyerclear.com. Describe what you found and how to reproduce it. We answer, and we say what we changed.