To pass Shopify’s app review and protect merchant data, your app needs working OAuth through Shopify’s own libraries, expiring offline tokens, valid TLS everywhere, no open ports facing the internet, high-entropy tokens, HMAC-verified webhooks, minimum necessary scopes, mandatory compliance webhooks,
and a real secrets rotation process. Miss any one of these and Shopify will reject your submission, full stop.
TL;DR:
- Shopify scans submitted apps with Nmap, so close public database, cache, and admin ports, and document any exposure that cannot be removed.
- Use Shopify’s official OAuth library, migrate legacy offline tokens to expiring tokens, and trigger reauthentication when deprecated tokens produce 403 responses.
- Verify webhook HMAC signatures against raw request bodies before parsing, store delivery IDs to skip duplicates, and acknowledge queued work within five seconds.
- Every public app must implement the customers/data_request, customers/redact, and shop/redact topics, meet Shopify’s deadlines, and justify each requested access scope.
- Rotate client secrets on a schedule by accepting old and new credentials during rollout, then revoke the old secret after confirming full propagation.
Table of Contents
- Your practical Shopify app security checklist
- Authentication, authorization, and access tokens
- Webhooks: verification, deduplication and reliability
- Data privacy, compliance webhooks and scope minimization
- Infrastructure, secrets, TLS, and network exposure
- Testing, static analysis, and penetration testing
- Incident response, monitoring, and merchant communication
- Bowtie’s practical path to a secure Shopify app
- Why continuous security matters more than a big fix
- Get a Shopify app security review that actually moves you forward
- FAQ
- Sources
Your practical Shopify app security checklist
Most rejections trace back to a handful of repeat offenders. Before you submit, run through this list and fix what’s broken rather than hoping the reviewer skips it.
- Confirm OAuth runs through an official Shopify template or library, not custom code you wrote from scratch.
- Verify all offline access tokens expire and refresh correctly, with no legacy non-expiring tokens still in rotation.
- Check that every public endpoint serves valid TLS with no certificate chain errors.
- Scan your own infrastructure for open ports before Shopify does, since Shopify runs Nmap scans against submitted apps as part of its review.
- Confirm webhook handlers verify the HMAC signature against the raw body before any JSON parsing happens.
- Audit your requested scopes and remove anything you can’t justify in plain language.
- Test that your three mandatory compliance webhooks respond correctly and within Shopify’s timelines.
- Make sure no client secret, API key, or token lives in your version control history.
Shopify’s security documentation lists five checks reviewers apply directly: protection against the OWASP Top 10, encryption in transit, closed unnecessary ports, token entropy of at least 128 bits (64 in limited cases), and careful handling of shortened URLs. Fail any of these and your app bounces back with a generic rejection notice that gives you little to go on, which is exactly why running your own version of this checklist before submission saves days of back and forth.
Pro Tip: Run your own port scan with Nmap against your staging environment before submission. Finding your own open Redis or Postgres port beats having a Shopify reviewer find it for you.

Authentication, authorization, and access tokens
Authentication is where most Shopify app incidents start. Shopify’s own guidance is blunt about it: hand-rolled auth is the most common source of security failures, and developers should lean on official templates and libraries instead of writing OAuth from scratch.
Here’s the sequence that keeps you compliant and keeps merchants connected:
- Build OAuth using Shopify’s official app template or an officially supported library for your stack, rather than reimplementing the token exchange yourself.
- Store offline access tokens as expiring tokens from day one, since non-expiring offline tokens are being phased out and Shopify will reject GraphQL Admin API requests that still rely on them after the enforcement date.
- Watch for 403 responses tied to deprecated non-expiring tokens and treat them as a trigger to kick off your re-authentication flow automatically.
- Rotate client secrets on a schedule, not just after an incident, by deploying support for the new secret first.
- Accept both the old and new secret during the rollover window so in-flight requests don’t break merchant sessions.
- Revoke the old secret only once you’ve confirmed the new one is fully propagated across your infrastructure.
Shopify’s credential management guidance treats client secrets exactly like passwords: never hardcode them, never commit them, and rotate immediately the moment you suspect compromise.
Pro Tip: Build your secret rotation script now, before you need it under pressure. Testing a calm rotation beats improvising one during an active breach.
Webhooks: verification, deduplication and reliability
A webhook endpoint that trusts its payload without verification is an open door. Shopify’s webhook documentation requires verifying the HMAC-SHA256 signature against the raw request body before you touch the payload with any parser.
- Place your HMAC verification middleware ahead of any body-parsing middleware so you’re checking the signature against the untouched raw bytes, not a reserialized version.
- Reject any request that fails HMAC verification immediately, with no partial processing.
- Capture and persist the
X-Shopify-Webhook-Idheader so you can detect and skip duplicate deliveries. - Design every webhook handler to be idempotent: processing the same event twice should produce the same result as processing it once.
- Route high-volume or slow-processing webhooks through an event bus or queue (Pub/Sub, EventBridge, or similar) so your endpoint can acknowledge receipt within Shopify’s five-second processing window while the real work happens asynchronously.
Shopify’s guidance ties verification, raw-body handling, and deduplication together for a reason: skip one and the others stop protecting you. A handler that verifies HMAC but isn’t idempotent will double-process a retried delivery; one that’s idempotent but doesn’t verify HMAC will happily process a forged request.
Data privacy, compliance webhooks and scope minimization
Every public Shopify app must implement three mandatory compliance webhook topics before it clears review. Shopify’s privacy law compliance documentation spells out exactly which ones and how they need to behave.
- Subscribe to
customers/data_request,customers/redact, andshop/redact, the three topics Shopify requires for every public app regardless of what data you actually collect. - Register HTTPS endpoints with valid, non-expired certificates, and make sure each one returns a 200-series status code on successful receipt, with HMAC verification applied the same way as any other webhook.
- Complete the actual redaction or data export within the timelines Shopify specifies, and test the flow using Shopify CLI webhook triggers rather than waiting for a live merchant request to surface a bug.
- Audit every scope your app requests and strip out anything you can’t explain in one sentence to a reviewer, since optional scopes without clear justification are a common point of friction during review.
Scope minimization pays off twice: it narrows your attack surface if a token ever leaks, and it speeds up app review because reviewers spend less time questioning why a simple inventory app wants access to customer payment data.
Infrastructure, secrets, TLS, and network exposure
Shopify’s review process includes an actual network scan, not just a documentation checklist. Treat your infrastructure hardening the same way you’d treat code review.
- Serve every public endpoint over valid TLS, and test the certificate chain yourself rather than assuming your load balancer configuration is correct.
- Never expose database, cache, or admin ports to the public internet. Shopify scans submitted apps with Nmap and will flag open ports it finds; if a port genuinely needs to stay open, document the mitigation and be ready to explain it.
- Store secrets in a dedicated secret manager such as Vault, AWS KMS, or a cloud provider’s parameter store, never in environment files that end up in version control.
- Encrypt data at rest, not just in transit, and keep staging environments fully separated from production so a compromised test environment can’t leak real merchant data.
Pro Tip: Run a free TLS checker like SSL Labs against every public subdomain your app touches, including internal tools you forgot were reachable from the outside.
Testing, static analysis, and penetration testing
Security bugs caught in code review cost a pull request. The same bugs caught after launch cost merchant trust.
- Run software composition analysis in CI with tools like npm audit or Snyk to catch vulnerable dependencies before they ship, since supply-chain compromises are a real and growing risk for Shopify apps that pull in third-party packages.
- Add static analysis (SAST) to your pipeline and gate merges on it passing, the same way you’d gate on unit tests.
- Write automated tests specifically for permission checks and tenant isolation, since a multi-tenant app that leaks one merchant’s data into another’s session is a severe and avoidable failure.
- Engage an external penetration test before a major launch, before a significant feature release, or immediately after any suspected security incident, and expect a remediation report with ranked findings rather than a pass or fail grade.
- Keep production data out of staging entirely; use sanitized fixtures so a staging breach can’t expose real merchant information.
Incident response, monitoring, and merchant communication
When something goes wrong, speed and clarity matter more than perfection.
- Detect the issue through monitoring, then contain it immediately by cutting off the affected access path.
- Assess the scope: which merchants, which data, which window of time.
- Notify affected merchants and Shopify with a clear account of what happened and what you’re doing about it.
- Remediate the root cause and rotate every credential that could plausibly have been exposed.
Wire your monitoring to catch authentication anomalies, sudden spikes in webhook failures, and API request rates that don’t match a merchant’s normal usage pattern. Shopify expects concrete remediation proof, not just a promise that it won’t happen again.
Bowtie’s practical path to a secure Shopify app
We built our Shopify security work around exactly the checklist above, because that’s the sequence that actually gets apps through review and keeps them clean afterward.
- Our Senior Developer Review walks through authentication, scope usage, and secrets handling line by line against Shopify’s own requirements.
- Our ShipDoctor scan gives you a fast, affordable read on where your app stands before you spend a review cycle finding out the hard way.
- Our AI Code Reviews & Optimization service covers dependency audits, webhook handler logic, and idempotency gaps that manual review tends to miss.
- Engagements end with a prioritized remediation list, rotation scripts where needed, and a post-fix validation pass, so you’re not guessing whether the fix actually held.
If you’re carrying an older app built before expiring tokens and mandatory compliance webhooks were standard, that migration work is exactly the kind of application security assessment we handle regularly.
Why continuous security matters more than a big fix
The apps that stay clean aren’t the ones that did one giant security push before launch. They’re the ones where someone rotates keys on a schedule, runs the test suite on every pull request, and checks the monitoring dashboard before coffee. A quarterly scramble to patch everything at once always misses something that daily discipline would have caught in minutes.
— Chad
Get a Shopify app security review that actually moves you forward
Running through a checklist tells you what’s wrong. Fixing it under a review deadline is a different problem, and it’s the one we spend most of our time solving for Shopify app teams.

Our Senior Developer Review starts at a few hundred dollars and covers the authentication, scopes, and secrets issues that cause most review rejections. Teams that want ongoing coverage use our Ship Shape Service for continuous monitoring and code review between releases.
- Start with a ShipDoctor scan for a fast read on where your app stands today.
- Move to a full Senior Developer Review when you’re closer to submission and need line-by-line findings.
- Use our AI Code Reviews & Optimization service for ongoing dependency and webhook handler audits.
Visit our pricing page to pick the option that matches where your app is right now.
FAQ
What does Shopify check during app review?
Shopify checks for OWASP Top 10 protections, valid TLS encryption in transit, closed unnecessary network ports, secure token generation with sufficient entropy, and careful handling of shortened URLs, according to Shopify’s security documentation. Apps that fail any of these checks get rejected during review rather than receiving a conditional pass.
How do I verify a Shopify webhook is legitimate?
Verify the HMAC-SHA256 signature against the raw, unparsed request body before any JSON parsing occurs, as described in Shopify’s webhook verification guide. Place this verification in middleware ahead of your body parser, and use the delivery ID header to catch duplicate deliveries.
What are the mandatory compliance webhooks for Shopify apps?
Every public Shopify app must implement customers/data_request, customers/redact, and shop/redact, per Shopify’s privacy law compliance requirements. These need HTTPS endpoints with valid certificates that return successful status codes and complete the requested action within Shopify’s specified timelines.
Why does my Shopify store have a password?
A password on a storefront typically means it’s a development store, which Shopify keeps password protected by default since it isn’t meant for live transactions or real payment processing. If a live store shows a password screen, that’s usually an intentional “coming soon” state rather than a security issue.
What happens if I keep using non-expiring Shopify access tokens?
Shopify is phasing out non-expiring offline access tokens, and GraphQL Admin API requests using them will eventually get rejected, according to Shopify’s token migration guidance. Apps still relying on legacy tokens should implement the migration path now rather than waiting for enforcement to break production traffic.