Security
Last updated: 29 August 2026, 7:30pm AEST (Melbourne)
How FlowPrint protects your store’s data and your customers’ privacy, in plain terms. This page covers the security architecture; for the full legal detail on what data is processed and why, see the Privacy Policy.
How to read this page
This page describes the security architecture FlowPrint actually runs, in enough detail that a security-minded reader can evaluate the design rather than take our word for it. Every claim describes something built and deployed, not a roadmap. Where a limitation exists, it is stated in the section it belongs to rather than hidden.
Per-shop cryptographic isolation
Every store that installs FlowPrint gets its own signing keypair (ECDSA P-256), generated at install time and never shared across merchants. Every worker (the small program on the PC connected to your printers) generates its own RSA-2048 keypair locally on first run; the private half never leaves that device, and the cloud only ever holds the public half.
The design rule, enforced in review before any key-handling code ships: a single leaked secret, whether a worker private key, a shop signing key, or a database row, must have a blast radius of exactly one store. There is no global signing key, no shared encryption key, and no table that requires a cross-store query to serve one store’s request. Sending domains are additionally unique at the database level, so no two stores can ever claim the same domain.
Document encryption, end to end
Every document delivered to a worker is envelope-encrypted before leaving the cloud: a random per-job key encrypts the PDF with AES-256-GCM, that key is encrypted to the target worker’s RSA-2048/OAEP public key, and the whole encrypted payload is signed with the shop’s own ECDSA P-256 key over SHA-256. The worker verifies the signature before decrypting, decrypts in memory, prints, and discards.
Two consequences worth stating precisely. First, once a job is encrypted for delivery, FlowPrint’s own backend cannot read it; only the one worker it was encrypted for can. Second, the public halves (worker public keys, shop signing public keys) are not secrets, and leaking them gets an attacker nothing: neither can decrypt or forge anything alone. If a print step fails over to a backup worker, the envelope is rebuilt for that worker’s own key at delivery time; keys are never shared between workers to make failover convenient.
All transport is HTTPS or WSS. Shopify access tokens and shop signing keys are encrypted at rest with AES-256-GCM.
The worker has zero inbound attack surface
The worker never opens a port, never runs a listening service, and never accepts an inbound connection. It makes outbound connections only, to FlowPrint’s own hostname, the way a desktop app checks for updates. Port-scan the machine it runs on and FlowPrint contributes nothing to the results. Any design that would require the worker to listen is rejected as a matter of policy, not preference.
It is also deliberately kept ignorant: no order data, no customer details, no business logic, no Shopify credentials. It receives an encrypted print-ready document and a printer name. The pairing handshake uses a single-use, high-entropy pairing key shown once in the admin and spent immediately on use; rolling it invalidates the old one.
Removing a worker (Logout and scrub, or uninstall) overwrites its private key on disk before deleting it, purges all local state, and revokes its cloud registration in the same action, on both Windows and Linux builds.
Zero-retention documents
A rendered PDF exists in storage only for the window between rendering and its single delivery attempt, and is deleted the moment that attempt finishes, success or failure, typically seconds. A scheduled sweep additionally removes any orphan that could survive an edge case, so the normal path and the failure path both end in deletion.
Reprint and preview never read a stored copy, because there is none: they re-fetch the order live from Shopify’s Admin API and render again. Customer downloads (thank-you page, order status, customer account, email links) are rendered live on each click and stream straight through; nothing is cached server-side. The credential for those links is Shopify’s own per-order token, re-derived server-side on every request, so FlowPrint issues and stores no download credentials of its own.
Quote requests follow the same principle at the feature level: a submission becomes a draft order inside the merchant’s own Shopify store, and FlowPrint keeps nothing. Back-in-stock registrations live as records inside the merchant’s own store and are deleted the moment the one notification sends.
Email: authentication, suppression, and what your DNS is asked for
Merchants on paid plans can send from their own domain. Setup asks for exactly one DNS record: a DKIM TXT record at a FlowPrint-named selector, containing a public key generated fresh for that domain. It is additive, touches nothing else in the zone, and cannot interfere with existing email (Microsoft 365, Google Workspace, or anything else). FlowPrint never asks a merchant to modify their SPF record, because for mail sent through our pipeline the merchant’s SPF is never consulted; DMARC passes on DKIM alignment, with the signature naming the merchant’s own domain. Sending from a domain is impossible until DNS proves control of it. The DKIM private key is handed to the sending provider and immediately discarded; FlowPrint stores only the public half.
Bounces and complaints are captured on every send through an authenticated event pipeline, and an address that hard-bounces or complains is suppressed permanently across every sending channel before any further send is attempted. Suppressed addresses are stored as SHA-256 hashes only, so the suppression list cannot function as a mailing list, and a GDPR erasure request erases the hash. Every send is internally attributable to the store that caused it, so one store’s list quality can never silently degrade delivery for the rest.
Addresses collected by storefront forms are vetted before they can ever become a bounce: the domain is checked for the ability to receive mail, and mail-system watchdog aliases (postmaster@, abuse@ and similar) are refused. Replies always go to the merchant, never to FlowPrint: mail sent from a merchant’s own domain is answered directly to their own mailboxes through their own mail system, and mail sent from the shared FlowPrint address carries the merchant’s contact address as its reply-to.
Application security
There is no FlowPrint password, login page, or session of its own anywhere: authentication inside the Shopify admin is Shopify’s own cryptographically signed session token, verified on every API request. The one public storefront entry point (quote and back-in-stock submissions) is authenticated by Shopify’s signed App Proxy mechanism, rate-limited per IP and per store, and every webhook from Shopify is HMAC-verified before its body is parsed at all.
Merchant-authored template content renders with output escaping on, and the browser context used for PDF rendering is isolated per render so no state can leak between stores. Rendered document pages state a strict Content-Security-Policy under which our own scripts run nonce-based and injected scripts do not run at all. Display names and email fields are sanitised against header injection; error messages shown to merchants never include upstream provider internals.
Access to the smallest practical scope is the default everywhere: the app requests only the Shopify permissions its features use, deliberately excludes customer-data scopes it can work without, and operational credentials are stored as platform secrets, never in code, never logged, and never echoed back in any interface.
Compliance
FlowPrint implements all three of Shopify’s mandatory GDPR webhooks: customers/data_request, customers/redact, and shop/redact. Uninstalling revokes the access token immediately; shop redaction deletes every record tied to the store, including uploaded template images, any email configuration, and the sending-domain identity registered with our email provider, so nothing capable of sending as that merchant survives their departure. Customer redaction also erases the hashed suppression entry derived from that customer’s address.
Full detail on what is processed, why, for how long, and your rights, lives in the Privacy Policy linked at the top of this page.
Infrastructure
FlowPrint runs entirely on Cloudflare’s network (Workers, D1, R2, Queues, Browser Rendering), with no self-hosted servers. Email is delivered through Cloudflare’s Email Service for the shared sender and through a major cloud email provider for merchant-owned domains; both are processors that deliver the one message and retain no authority over the content beyond that. Cryptography uses the platform’s native Web Crypto implementation rather than bundled libraries.
What we don’t claim
FlowPrint holds no formal certification (SOC 2, ISO 27001 or similar) at this stage, and we would rather say so than imply otherwise. What we offer instead is a small, inspectable attack surface: an outbound-only worker, per-store key isolation, immediate deletion as the default data posture, one public endpoint, and a hosting platform whose own hardening is done by people with far more resources than any small vendor. If certification becomes material to your business, ask, and you will get a straight answer about where things stand.
Report a security concern
Email development@flowprint.app with as much detail as you can share. Reports go to the people who wrote the code, and a genuine report gets a genuine, direct reply. There is no formal bug-bounty program yet; that is a statement about our size, not our attitude.