Tested: app proxy works with `[app_proxy]` config alone, without `write_app_proxy`. Is the scope enforced anywhere?

The app proxies docs say “Configuring an app proxy requires the write_app_proxy access scope.” We have apps in production with working proxies that never requested this scope, so we ran a controlled test to see what the scope actually changes. Sharing the results and hoping someone from Shopify can clarify the intended behavior.

Setup

  • React Router app template, @shopify/shopify-app-react-router 1.2.x (@shopify/shopify-api 13.1.0), Shopify CLI 4.7.1, managed installation, deployed with shopify app deploy.
  • App already installed on a dev store with write_products,write_metaobjects,write_metaobject_definitions. No proxy configured before the test.
  • Probe route behind authenticate.public.appProxy that reports whether the signature validated, whether an offline session and Admin client were returned, runs currentAppInstallation { accessScopes { handle } }, and has a sub-path that returns Content-Type: application/liquid with {{ shop.name }}.
  • TOML addition:
[app_proxy]
url = "/expiring-proxy"
subpath = "expiring"
prefix = "apps"

Phase A: [app_proxy] added, scope NOT declared

shopify app deploy validated and released the version with no warning about the missing scope. About 15 seconds after release, https://{shop}/apps/expiring/... went live on the already-installed store, no reinstall needed.

Check Result
Signature verified by authenticate.public.appProxy yes
Offline session + Admin client returned yes
Admin GraphQL query through that session works
Liquid response rendered by Shopify ({{ shop.name }} resolved) yes
POST with JSON body forwarded yes
write_app_proxy in currentAppInstallation.accessScopes no

Phase B: write_app_proxy added to scopes, redeployed

Before the merchant accepted the new permission: every check identical to Phase A. After accepting in the admin: write_app_proxy and the implied read_app_proxy appeared in accessScopes, the app/scopes_update webhook fired, and every proxy check was still identical. The only observable difference between the two phases is the scope list itself.

Other things we looked at

  • The access scopes reference lists it only as “Allows your app to use app proxies.”
  • The Admin GraphQL schema (2026-07) has no proxy-related types or fields, so the scope doesn’t gate any API operation we can find.
  • The requirement never appeared in the developer changelog. It was communicated through the docs, a Partner Dashboard banner, and emails, with a November 14, 2025 deadline (thread). Backfills were handled by email rather than a form (thread).
  • The [app_proxy] section of the app configuration reference and the authenticate app proxies guide don’t mention the scope at all.
  • Shopify staff said in this thread that stores which don’t accept the scope get it backfilled server-side. In this later thread the guess was that without the scope “the proxy route almost certainly won’t be active.” Our test shows the opposite for a store where the scope was never declared, let alone granted.

Questions

  1. Is write_app_proxy technically enforced anywhere today, or is it purely a consent/disclosure requirement that Shopify backfills?
  2. Is there a planned date after which proxy requests will fail for installs that lack the scope? If so, where will that be announced?
  3. Adding a required scope re-prompts every existing merchant with “edit page content” wording (discussed here). For apps whose proxies only read data, is there a recommended path that avoids that prompt?
  4. Could the docs state explicitly whether the scope is a hard requirement or a disclosure requirement?

Happy to share the probe route and exact request logs if useful.

References

1 Like