Security overview
Version 1.0, effective October 10, 2026.
This page describes how HonestTag protects the data it handles for Shopify stores: what runs where, how it is encrypted, who can reach it, how it is backed up, and what happens when something goes wrong. It also says what we do not have yet. For the legal terms, see our Data Processing Addendum; for who processes data for us, see Sub-processors; for what we collect and keep, see the privacy policy.
What we do not have yet
HonestTag does not hold a SOC 2 report, an ISO 27001 certificate or a certification under the EU-U.S. Data Privacy Framework, and no independent penetration test of HonestTag has been carried out. We do not claim otherwise anywhere. If a security review for your business needs one of these, tell us before you install.
Architecture
The HonestTag app and its tracking endpoint run on Cloudflare's developer platform: Workers for compute, and D1, Workers KV, R2, Durable Objects, Queues and Workers Analytics Engine for storage, all in one Cloudflare account. We do not operate servers of our own for the app or the tracking endpoint.
The app's code has no third-party runtime packages: the Worker is built only from our own source, and its npm dependencies are build and test tools.
Testing happens in a separate staging environment with its own database, storage, queues and analytics dataset. Staging runs no scheduled jobs and serves no store traffic.
Encryption
In transit. Every HonestTag domain requires TLS 1.2 or newer, and a plain HTTP request is redirected to HTTPS. A store's own tracking subdomain, when it uses one, is created with the same TLS 1.2 minimum. Shopify's webhooks are checked against Shopify's signature and refused if it does not match.
At rest. Cloudflare encrypts the databases, key-value data, Durable Objects and object storage we use, with keys Cloudflare manages: in Cloudflare's words, "All objects stored in D1, including metadata, live databases, and inactive databases are encrypted at rest", "All values stored in KV are encrypted at rest", "All Durable Object data, including metadata, is encrypted at rest" and "All objects stored in R2, including their metadata, are encrypted at rest" (D1, KV, Durable Objects, R2).
Your ad-platform and Shopify credentials get a second layer. Each one is encrypted by HonestTag with AES-256-GCM under its own random key, that key is encrypted under a master key held as a Cloudflare secret, and the store's identity is bound into the encryption, so a credential copied under another store cannot be opened. Credentials are decrypted only in memory, for a call to the platform or a check that a connection still works, and are never written to logs. The master key can be rotated without downtime: stored credentials are re-encrypted under the new key.
Keeping each store's data separate
Stores share the same Cloudflare storage, and every store's data is kept apart within it in code, not only by convention. Each storage key carries the store's identity, the store-scoped database layer refuses a query that does not filter on the store first, and the store's identity comes only from a validated lookup of the hostname a request arrived on. A request for a hostname we do not recognize is not tracked at all. The few parts that work across stores by design (installation, privacy deletion, scheduled jobs and our admin console) are listed in the code and reviewed. Automated tests check this separation on every change.
Who can reach the data
Merchants use the app inside Shopify admin, and the app checks Shopify's session token on every request from there; there is no separate HonestTag password to steal. Agencies a store approves sign in separately and see reporting totals only, as section B2 of the privacy policy describes.
Our staff reach the internal admin console only through Cloudflare Access in front of it (single sign-on for people, a service token for our own scripts), which the app verifies again itself and which refuses access if the check fails. Every admin action is checked again on its own.
Manual changes to the production database go through one guarded script. It records a restore point before anything runs, refuses destructive statements unless explicitly allowed, and writes an audit record naming who made each change in the same transaction as the change.
How changes reach production
Code lands on the production branch only after three automated check suites pass on that exact commit: the app's test battery (several thousand checks, including privacy, tenant-separation and deletion tests), the website validator, and the operational gates. Every release of the app goes to staging, and every website release to a preview, before production, through one deploy script, which refuses to ship a commit that is not on the production branch, has local changes, has not passed those checks, or skips staging, and which checks the live service after deploying.
Backups and recovery
- Main database: Cloudflare keeps a point-in-time history that lets us restore to any minute in the last 30 days, and we also take a nightly copy that is test-restored before it is stored. We keep it for 30 days.
- Measurement data: a nightly snapshot, checked against its own manifest before it is stored, kept for 30 days.
- Raw event archive and data-request reports: a second copy in a separate storage bucket, updated nightly.
A restore never brings back a store or a shopper whose data was deleted after the backup was taken. A staging restore drill of the database, key-value and object-storage paths passed on September 28, 2026. All of these copies are kept within our Cloudflare account, so they protect against mistakes and the loss of a single store or bucket, not against the loss of the account itself.
Monitoring and logging
Every scheduled job reports a health signal, and a failed or late job raises an alert to us. Store-level problems (a webhook that stops arriving, deliveries a platform refuses, a credential that stops working) raise alerts too. Merchant, system and staff actions, including every deletion request we process and every manual production change, are recorded in an audit log. We do not retain request-level logs of the traffic to the tracking endpoint.
Incidents and breach notice
We have a written incident response plan, in place since August 2026, covering detection, containment (including a rotation procedure for every secret), assessment, notification and a written post-mortem within 7 days. If a personal data breach affects your store's shopper data, we notify you by email without undue delay and within 48 hours of becoming aware of it, as section 11 of the DPA commits.
Deleting data
When a store uninstalls, HonestTag deletes its Shopify credentials and revokes the access it granted to its connected platforms. Shopify then sends a deletion request about 48 hours later, and we delete the store's data when it arrives, with one exception we have not closed yet: some per-order delivery records (which ad platforms an order, refund or order edit was sent to, with no visitor ID or contact data) have no expiry and are not reached by that deletion. We first take a safety snapshot of the store's database records, so a mistaken deletion of those records can be reversed; if that snapshot fails, the deletion stops and is retried. The snapshot does not cover the store's other stored data, and it is deleted after 30 days. Individual shopper deletion and access requests from Shopify are handled too. What is kept after deletion, and for how long, is listed in the privacy policy and in Annex I of the DPA.
Reporting a security issue
Email support@honesttag.com with "Security" in the subject. We reply within one business day. Please do not test against stores that are not your own.