Shopify App Access Scopes: Write to Read Done Right
A practical guide to downgrading Shopify app access scopes from write to read: audit, rewrite mutations, handle re-authorization, and pass app review.

Reducing Shopify app access scopes from write to read is one of the fastest ways to improve install approval rates and pass app review. Merchants and reviewers both scan the permission screen before anything else, and an app that asks for write access it never uses looks risky. This guide walks through the full downgrade: auditing which write scopes you actually need, rewriting mutations and webhooks so read-only scopes still work, handling merchant re-authorization, and measuring the impact on installs and review outcomes.
The core idea is least privilege. Shopify's review team expects you to request the minimum scopes required for your app's declared features, and merchants increasingly reject apps that ask for broad write permissions up front. If your app only reads products, orders, or customers to display data, you should be requesting read scopes, not write scopes.
Why Shopify pushes least-privilege scopes
Shopify's app review guidelines and the merchant-facing permission screen both reward narrow scope requests. When a merchant installs your app, they see a list of permissions in plain language. Write scopes are flagged as higher risk because they allow your app to change store data. A read-only scope list is easier to approve, easier to justify, and easier to defend in a support conversation.
Reviewers look for three things:
- Scope-to-feature match. Every requested scope should map to a feature described in your app listing.
- No unused write scopes. If you request
write_productsbut only display product data, that is a red flag. - Clear upgrade path. If a feature genuinely needs write access, the app should request it only when the merchant enables that feature, not at install time.
This is also a trust signal. Merchants compare apps side by side, and the one asking for fewer permissions usually wins the install.
Auditing which write scopes your app actually uses
Start with a full inventory. List every scope in your app configuration and every API call in your codebase.
Step 1: Export your current scopes
Pull the scope list from your app's configuration (in the Partner Dashboard or your app's environment variables). Group them by read and write.
Step 2: Map scopes to code paths
Search your codebase for GraphQL mutations and REST write endpoints. For each one, note which scope it requires. A simple table helps:
| Scope | Used by | Can it be read-only? |
|---|---|---|
write_products |
Bulk product update job | No, if you edit products |
read_products |
Product listing, bundle builder | Yes |
write_orders |
Fulfillment sync | Only if you push fulfillment |
read_orders |
Order dashboard | Yes |
write_customers |
Tagging customers | Only if you write tags |
read_customers |
Segmentation view | Yes |
Step 3: Flag dead scopes
Any scope with no matching mutation or write endpoint is a candidate for removal or downgrade. This is where most apps find easy wins.
Rewriting mutations and webhooks so read-only scopes still work
The hard part is not removing scopes, it is keeping features working. Two patterns cover most cases.
Pattern 1: Replace mutations with read queries
If a feature only displays data, replace the mutation with a query. For example, a dashboard that previously wrote a cached copy of product data can instead read products on demand. This removes the write scope entirely.
Pattern 2: Defer write scopes to opt-in features
If a feature genuinely writes data, request the write scope only when the merchant enables that feature. Shopify supports incremental authorization, so you can request additional scopes at runtime and prompt the merchant to approve them. The install screen stays read-only; the write scope appears only when needed.
Webhooks
Webhooks do not require write scopes. They require the matching read scope for the topic you subscribe to. If you are subscribing to products/update but only request read_products, that is fine. Review your webhook subscriptions and confirm each one is covered by a read scope.

Handling merchant re-authorization and scope-change prompts
Changing scopes means existing installs need to re-authorize. Shopify handles this through the OAuth flow: when your app requests a different scope set, the merchant is prompted to approve the new permissions.
Practical steps:
- Version your scope set. Keep the old and new scope lists in configuration so you can roll out gradually.
- Detect scope mismatch. On each request, compare the granted scopes in the session token with the scopes you need. If they differ, redirect to OAuth.
- Explain the change. In your app's UI, tell the merchant why the permission screen is appearing again. A short banner is enough.
- Handle downgrades gracefully. If a merchant previously granted write access and you no longer need it, do not force a re-auth just to remove it. Let the scope expire naturally or prompt only when a feature requires it.
If you are building this kind of scope migration, our Shopify app development service covers audits, rewrites, and review preparation.
Measuring the impact: install approval rates and review outcomes
Scope changes are measurable. Track these before and after:
- Install completion rate. The percentage of merchants who finish the OAuth flow after starting it.
- Review feedback. Note any comments about permissions in your app review results.
- Support tickets. Fewer permission questions usually means fewer pre-install support requests.
- Uninstall reasons. If merchants cite permissions, a read-only scope set should reduce that.
A read-only scope set does not guarantee approval, but it removes one of the most common rejection reasons. Combined with a clear listing and a working demo, it moves the review in your favor.
Getting help: when to bring in a Shopify app development partner
Some downgrades are straightforward: remove a dead scope, replace a mutation with a query, ship. Others are not. If your app writes data across multiple resources, uses legacy REST endpoints, or has webhook logic tied to write scopes, the rewrite can touch core architecture.
Signs you should bring in help:
- Your scope list has more than a handful of write scopes and no clear owner.
- You are preparing for app review and need a second opinion on scope justification.
- You want to move to incremental authorization but are unsure how to structure the OAuth flow.
- You need to keep existing installs working while changing permissions.
A partner can audit the codebase, propose a target scope set, rewrite the affected mutations and webhooks, and handle the re-authorization flow. The goal is the same as yours: the smallest scope set that still delivers the app's features.
If you want a starting point, review our products page to see how we structure Shopify apps and integrations, or send us a message with your current scope list and we will tell you what can be downgraded.
Related reading
Frequently asked questions
Can I change my Shopify app's access scopes after it is published?
Yes. You update the scope list in your app configuration and ship the change. Existing merchants will be prompted to re-authorize when your app requests the new scope set. Plan the rollout so you do not break features that still rely on the old scopes.
Do webhooks require write scopes?
No. Webhook subscriptions require the matching read scope for the topic. For example, subscribing to products/update needs read_products, not write_products. Review each subscription and confirm it is covered by a read scope.
What is incremental authorization in Shopify?
Incremental authorization lets your app request additional scopes at runtime instead of at install. The merchant sees a read-only install screen first, and write scopes appear only when a feature that needs them is enabled. This keeps the initial permission request narrow.
Will reducing scopes break my existing installs?
It can if your code still calls mutations that need the removed scopes. Audit every write endpoint before removing a scope, and test the full flow in a development store. Downgrades that remove unused scopes are safe; downgrades that remove used scopes require code changes first.
How do I know which scopes my app actually uses?
Search your codebase for GraphQL mutations and REST write endpoints, then map each one to the scope it requires. Any scope with no matching call is a candidate for removal or downgrade.
Does a smaller scope list improve app review outcomes?
It removes one of the most common rejection reasons. Reviewers expect every requested scope to map to a listed feature, and unused write scopes are a red flag. A read-only scope set that matches your features is easier to approve.
Ready to downgrade your Shopify app scopes?
Send us your current scope list and we will tell you what can be reduced, what needs a code change, and how to handle re-authorization without breaking existing installs.