Security and incident response
Last updated: 15 October 2026
This page describes how AppVerix protects the data its Shopify apps handle and what we do if something goes wrong. It is part of our Data Processing Addendum. Questions: support@appverix.com.
1. Incident response plan
A security incident is anything that could expose, change or destroy personal data or let someone who should not have access into our systems.
- Detect. We find incidents through Cloudflare's account audit logs and Worker logs, Shopify notices, and reports from merchants or researchers sent to support@appverix.com.
- Contain. Stop the harm first: revoke or rotate the affected secrets and tokens, disable the affected account or route, or take the affected app offline.
- Assess. Work out what happened, which apps, stores and data were affected, and for how long, using the audit and Worker logs and the database's point-in-time history.
- Notify. If personal data was affected, we tell the affected merchants and Shopify within 72 hours of becoming aware, with what happened, what data, what we have done, and what we recommend. Merchants decide whether to notify their own customers and regulators; we give them what they need.
- Remediate. Fix the cause, restore data if needed (D1 Time Travel can restore to any minute in the last 30 days), and confirm the fix.
- Review. After the incident is closed we write down what happened, the timeline, the cause and what we are changing, and update this plan and our practices.
Report a suspected incident or vulnerability to support@appverix.com.
2. Staff access
- Every person has their own account on each system. Shared logins are not allowed.
- Passwords are kept in a password manager. Each password must be at least 16 characters long or a passphrase, and unique to that service.
- Two-step verification is required on every account that can reach our systems or source code: Shopify Partners, Cloudflare, GitHub and Google.
- Access is limited to what the person's work needs (least privilege). Personal data is opened only to run the service or to answer a support request from the merchant who owns it.
- Access is removed when it is no longer needed.
3. Protecting data
| Area | What we do |
|---|---|
| In transit | All traffic to our apps uses TLS. |
| At rest | Data lives in Cloudflare D1, which encrypts everything it stores (including backup history) with AES-256 at rest. |
| Backups | D1 Time Travel keeps point-in-time history, so a database can be restored to any minute in the last 30 days. |
| Secrets | Shopify API secrets, email-provider keys and similar credentials are stored as Cloudflare Worker secrets, not in source code. |
| Logs | Application logs hold shop domains, order numbers and technical events. They do not hold customer names, email addresses or addresses. We checked the production logs and the code for this and fixed the one place that logged a recipient address. |
| Source control | Real customer data is not kept in our repositories. Tests use made-up data. |
| Outbound data | The apps send data only to Shopify (for the store's own data) and to Resend (to deliver email). This is how the code is written; we do not claim a network firewall. |
| Data loss prevention | Together: data minimisation (apps store only what they need, and AppVerix Invoices does not store order contents), no personal data in logs or source control, secrets kept out of code, encrypted storage, point-in-time restore, automatic deletion of old data (see retention), and per-shop separation in every query. |
4. Test and production data are separate
- Production databases hold real merchants' data. Development and testing use a Shopify development store with made-up customers, and local or staging databases that contain made-up data.
- AppVerix Returns has its own staging Worker and its own staging database (separate from production, filled with made-up data, no Shopify or email credentials, no emails sent). Automated tests run only against in-memory local databases. The Returns end-to-end test script uses the staging database by default and refuses to touch the production database unless it is explicitly forced with a flag.
- The end-to-end scripts of our other apps also refuse to run against production without an explicit flag. A separate staging environment currently exists for Returns only; the other apps are tested locally and on a Shopify development store.
- Real customer data is not copied into test or staging environments.
5. Access logging
- All access to our Cloudflare account (the place the apps and databases are managed) is recorded in Cloudflare's account audit logs.
- AppVerix Returns writes an audit log inside its own database each time an admin screen reads return or customer data. Each entry records the shop, the action and the time, and no personal data values. The table is append-only: the database itself rejects edits and deletes, and entries are removed only after 12 months. The other apps do not have an equivalent in-app audit log yet; they rely on Cloudflare's account audit logs and on Shopify's own logs for admin access.
6. Data retention
| Data | Kept |
|---|---|
| Login session for a store | Deleted immediately when the app is uninstalled |
| A store's app data | While the app is installed; deleted when Shopify sends the shop erasure request (usually within 48 hours after uninstall) |
| A customer's data | Deleted when Shopify sends a customer erasure request |
| Return photos (Returns) | Deleted about 30 days after the return is closed |
| Customer data request exports (Returns) | Cleared from our compliance record after 30 days |
| Access audit log (Returns) | 12 months, then deleted. It holds no personal data (shop domain, action, record ID, time) and is not removed by a store erasure request |
| Backup history | Up to 30 days (D1 Time Travel), then gone |
| Privacy request records | Shop, request type, time and Shopify's customer ID or order numbers only, with no names or email addresses (the Returns export above is the only exception, and it is cleared after 30 days) |