SupportSecurity

Security

Copy page

What Workflow Transactional Email is built on, where it runs, how your mail credentials and store data are encrypted and isolated, and how we keep the app up to date. No PHP anywhere.

Workflow Transactional Email is built and operated by Code Creation Labs. This page explains what the app is made of, where it runs, how your store's data is protected and how we keep everything up to date. It is written for store owners and for anyone filling in a security questionnaire. What the app stores and for how long is on Data, privacy and security; the legal side (privacy policy, data processing agreement, sub-processors) is on Legal & data protection.

What the app is built on

Layer What we use
Application code TypeScript on Node.js, a current long-term-support release. The admin pages, the layout editor and the services that run your Flow steps are one code base.
Database and cache PostgreSQL (Google Cloud SQL) and Redis (Google Cloud Memorystore)
Hosting Containers on Google Kubernetes Engine in Google Cloud region europe-west1 (Belgium, European Union). Databases, caches, file storage and application logs are region-local.
Shopify integration Shopify's official app libraries, Shopify Flow actions, the Admin GraphQL API for the optional permissions, and Shopify's webhooks
Email delivery The mailbox you connect: your own SMTP server, Microsoft 365 or Google Workspace. The app's own alert emails to you go through Amazon SES in Frankfurt.
Your storefront Nothing runs in your theme or your checkout.

There is no PHP, WordPress, Java or other runtime anywhere in the service. The app is listed on the Shopify App Store and passed Shopify's app review, which covers Shopify's security and protected customer data requirements.

How your data is protected

In transit. Every connection between your browser, Shopify, your mail provider and the app uses TLS. The database and the cache have no public address: they are reachable only from inside our private network.

At rest. All databases and file storage are encrypted at rest with keys we manage in Google Cloud KMS.

Field-level encryption on top. Anything that could be used to send as you gets a second layer: SMTP usernames and passwords, Microsoft 365 and Google OAuth tokens, the secrets you store, your store's Shopify access token, and the addresses on your unsubscribe list. Each value is encrypted individually with AES-256-GCM under a separate key in Cloud KMS, with automatic key rotation, and decrypted in memory only for the moment an action runs. Every decryption of a protected value is recorded in an internal access trail. Secret values are redacted from the action history before it is written and are never returned by the Developer API or to Sidekick.

Secrets. API credentials and keys of the service itself live in Google Secret Manager and are loaded when a service starts. They are not in the code, not in the container images and not in the build pipeline.

Data minimisation. The app is installed with no access to your store's data. Customer data reaches an email only because you pass it in from Shopify Flow. The four optional permissions (reading a metafield's file on one order or customer, creating a unique discount code) are asked for in place, granted through Shopify's own dialog and revocable at any time. See Permissions: what the app can read from your store.

Who can access what

  • Your store only. Every record carries the store it belongs to, and every query is scoped to the store that was authenticated. One store can never read or change another store's layouts, senders, secrets or history.
  • Verified requests only. Pages inside the Shopify admin are authenticated with Shopify session tokens. Flow steps and Shopify's own webhooks are verified by Shopify's HMAC signature before any data is touched, and a Flow step that is delivered twice is executed once.
  • Rendered content. Layouts are rendered on our servers and the result is sanitised before sending: scripts, event handlers, javascript: URLs, iframes and form elements are stripped, so a value passed in from Flow cannot turn into active content in someone's inbox.
  • Outbound requests. URLs the app connects to on your behalf, for the HTTP Request action, for attachments fetched from a URL and for files referenced by a metafield, are checked before connecting: loopback, link-local, cloud metadata and private network addresses are refused, including through a redirect. Redirects are capped and responses size-limited.
  • Our team. Production systems are reached only through Google Cloud IAM with individual accounts. Internal maintenance tools are not exposed to the internet.

How we keep the app up to date

  • Every change is scanned before it can ship. The pipeline runs type checks and linting, static application security testing (SAST), secret detection, dependency vulnerability scanning and container image scanning. Our release bar is zero known vulnerabilities in dependencies and in the image.
  • Runtime and operating system. The container image, Node.js on its Alpine Linux base, is rebuilt with every release, so runtime and operating system patches ship continuously. The managed Kubernetes platform keeps the underlying nodes patched.
  • Shopify platform. We track Shopify's API versions and the security advisories for Shopify's app libraries, and apply updates promptly. The app runs on a current Admin API version.
  • Security reviews. We conduct a full internal review of every route, data path and database query at regular intervals, most recently in October 2026.
  • Monitoring. Availability is monitored around the clock and published on our status page, and errors alert us. Operational logs are stored in the same EU region, kept for at most 30 days and never contain credentials or secrets.

Retention and deletion

  • Action history, which records what was sent and is therefore customer data, is deleted automatically after 30 days.
  • Uninstalling deletes everything: layouts, senders, secrets, history, the unsubscribe list and uploaded files, immediately and irrecoverably.
  • Shopify's mandatory privacy requests (customers/data_request, customers/redact and shop/redact) are handled automatically within the timelines Shopify sets, including a customer's entry on the unsubscribe list.
  • The full table of what is stored is on Data, privacy and security. Sub-processors and the retention schedule are in the privacy policy. A signed data processing agreement can be requested at workflow-transactional-email.app/dpa.

Reporting a security issue

If you believe you have found a vulnerability, or you need a security questionnaire completed, email support@codecreationlabs.com. Security reports are read and answered with priority.