Security and data protection
Appal Post Purchase & Upsell reads order and buyer data from Shopify so it can decide which offer to show after payment and report on what each offer earned. This page describes how that data is protected, how it is backed up, and what happens if something goes wrong.
What we store
Funnel and offer settings, and one event row per offer shown, accepted or declined. Each event carries the order or checkout identifier, the amount, and, for personalisation or targeting, the buyer’s first name, country and Shopify customer ID. We do not store card numbers, full addresses, email addresses or phone numbers.
Encryption
- All traffic runs over TLS 1.2 or higher. There is no plain HTTP endpoint.
- The database is a managed PostgreSQL instance whose volumes are encrypted at rest by the hosting provider, and its automated backups inherit that same encryption.
- Shopify access tokens are stored only in that encrypted database, never in source control.
Access control
- Access to production is limited to the app’s maintainer. There are no shared logins and no third party has a production credential.
- Every account that can reach production requires a unique password of at least 16 characters held in a password manager, plus two-factor authentication.
- Every read of a buyer’s name, email, phone or address is written to an access log recording the shop, the fields read, the reason and the order it was scoped to.
Separating test data from production
Development and testing run against their own database. Merchant data never leaves the production database, and test orders are never written into it. Production data is not copied into development.
Data loss prevention
- The production database is backed up automatically by the hosting provider, daily, encrypted.
- Backups are restorable to a point in time. Restores are exercised when the schema changes in a way that would be hard to reverse.
- Application code and configuration live in a private version-controlled repository, so a lost host can be rebuilt from scratch.
- Deletions are deliberate and scoped to one shop: a shop’s data is deleted when Shopify sends the shop redaction request 48 hours after uninstall, and no code path deletes across shops.
Retention and deletion
Offer events are kept while the app is installed so merchants can report on them. Uninstalling removes the shop’s access tokens at once. Every other row belonging to that shop is deleted when Shopify sends the shop redaction request, 48 hours after the uninstall. A customer redaction request strips that buyer’s name, country and customer ID from the events and deletes their survey answers, leaving only anonymous revenue figures. These run at /webhooks/compliance.
Incident response
If we suspect personal data has been exposed, we follow these steps.
- Detect and triage. Platform logs and error reporting are reviewed on report or alert. An incident is opened the moment exposure is plausible, not once it is proven.
- Contain. Rotate the affected credentials, revoke sessions, and if needed take the endpoint offline. Containment comes before diagnosis.
- Assess. Establish which shops and which fields were affected, and over what window, using the access log described above.
- Notify. Affected merchants and Shopify are notified without undue delay and within 72 hours of becoming aware, with what happened, what data was involved, and what they should do. Notification is not delayed to wait for a complete picture.
- Recover and learn. Restore from backup if data was altered or lost, then write up the cause and the fix, and ship the fix before the incident is closed.
Reporting a vulnerability
Email silas@okayscale.dk with the details and how to reproduce it. We will acknowledge within two business days. Please give us a reasonable chance to fix it before disclosing it publicly.