UK product engineering & compliance

Give an AI agent safe write access to Shopify

An agent gets a credential, never a login: scoped to one job, expiring on its own, revocable without touching a person. Here is which credential, for which job, and how we rotate it.

Ritesh AgarwalSep 15, 20269 min read
Never hand the agent your master key: blast radius by credential, from a staff login down to a read-only token

Direct answer

Never give an AI agent a Shopify staff login, a collaborator account or the store owner’s credentials. Give it a credential that is scoped to the job, expires on its own and can be revoked without touching anything else. For theme work that is a Theme Access password, used through the Shopify CLI against an unpublished theme. For data work it is a custom app created in the Dev Dashboard with the narrowest scopes that fit, read scopes first, authenticated with the client credentials grant so the token expires every 24 hours. Legacy custom apps created in the admin still work, but none can be created since 1 January 2026 and they only rotate by uninstall and reinstall. Keep the Dev MCP for documentation; it holds no store access at all.

ScopeOne job, one credentialTheme Access for themes. Read scopes before write. One write scope per job.
LifetimeTokens that expireClient credentials tokens last 24 hours. Theme Access passwords die when deleted.
NeverNo logins, everStaff, collaborator and owner accounts carry every permission and cannot be scoped.

Key takeaways

  1. An agent holds a credential, never a login. Staff and collaborator accounts cannot be scoped to a job.
  2. Theme work needs write_themes only. A Theme Access password gives exactly that and is revoked by deleting it.
  3. New custom apps live in the Dev Dashboard since 1 January 2026; their client-credentials tokens expire after 24 hours.
  4. Legacy admin-created apps rotate only by uninstall and reinstall, and can never be recreated. Migrate them.
  5. The Dev MCP gives an agent docs and schema, not store access. Confuse the two and you over-provision.

What an agent can actually hold

Our previous guide put the theme in Git and let the agent work a branch. This one answers the question that arrives the moment that works: what credential is in the agent’s environment when it runs shopify theme push or updates a price through the Admin API? Most stores answer it badly. The founder’s login gets pasted into a config file because it was quicker, and the agent now holds payouts, staff, domains and customer exports in order to change a Liquid file. This guide sits in our UK engineering and compliance work and extends the Git and preview-theme workflow rather than repeating it.

Shopify gives you three credentials that can be scoped, and one that cannot.

01 · ThemesTheme Access password

Created by store staff in the Theme Access app, viewed once, with a link that expires after seven days. It grants write_themes and nothing else, is passed to the CLI as --password or the SHOPIFY_CLI_THEME_TOKEN variable, and is revoked by deleting it.

Shopify: manage theme access

02 · DataDev Dashboard custom app

Since 1 January 2026 every new custom app is created in the Dev Dashboard and installed on stores in the same organisation. Scopes are declared per app version, and the client credentials grant issues a token that expires after 24 hours.

Shopify: get API access tokens for Dev Dashboard apps

03 · DocsDev MCP

npx @shopify/dev-mcp gives Claude Code or Cursor Shopify’s documentation, GraphQL schema and validation. It runs locally, needs no authentication and holds no store access. The right first rung, and the wrong reason to hand over a token.

Shopify: Dev MCP server

The one that cannot be scoped is a login. A staff account, a collaborator account or the owner’s own credentials carry whatever the role allows, in the admin and through the CLI, and these are the things a theme edit never needs:

Billing and payoutsStaff accounts and rolesCustomer exportsInstalling and removing appsDomains and settingsThe published theme
Legacy apps still work, but the clock is running. Custom apps created in the admin under Develop apps are now legacy. Existing ones keep working, but no new ones can be created since 1 January 2026, their token is shown once and never expires, and the only rotation is uninstall and reinstall. Delete one and you cannot replace it like for like. Shopify changelog: legacy custom apps · Shopify: admin-created custom apps

The access ladder

AN AGENT MAY HOLD THESE · SCOPED, SHORT-LIVED, REVOCABLENEVERDev MCP · docs onlyschema, docs, validationno store, no credentialRead-only custom appread_products, read_orders24 h token · same orgTheme Access passwordwrite_themes, nothing elseunpublished theme + PRScoped write appone write scope per jobdry run · log · roll backStaff or owner loginevery permission, no scopenever for an agenteach rung adds blast radius · scope, lifetime and revocation are what keep the left side safeFIG. 01THE ACCESS LADDER
Fig. 01 Climb only as far as the job needs. Every rung on the left can be scoped, expired and revoked. The top rung cannot, which is why an agent never gets a login.scroll →

Think of access as a ladder and climb only as far as the job needs. The bottom rung is the Dev MCP: the agent can read every doc and validate every query with no credential at all, which is enough for a surprising amount of planning. The next rung is a read-only custom app, read_products and read_orders, so the agent can inspect the catalogue and reason about it without being able to change a thing. Theme work climbs one more rung, to a Theme Access password on an unpublished theme, where a mistake is a preview nobody sees. Only a job that genuinely writes data, a price sync or a metafield backfill, earns a write scope, and it earns exactly one. The top rung is a login, and no job earns that.

If the store already carries a pile of apps and tokens nobody remembers issuing, that inventory is the first job, before any agent is connected: a hardening pass over the store’s apps, tokens and staff permissions takes a day and removes the credentials that would otherwise become the agent’s by accident.

A collaborator or staff login for the agent
  • Carries every permission the role has, in the admin and the CLI
  • Two-factor prompts built for a person block an unattended job
  • The store activity log shows a person, not the job
  • Cannot expire on its own; revoking it removes a human too
vs
A scoped credential for the agent
  • Scopes declared per app version, read first, one write per job
  • Client credentials tokens expire after 24 hours
  • The activity log shows the app by name
  • Revoke by deleting a password or rotating a secret, nobody else affected

The activity log matters more than it looks. From Settings, General, the Store activity log lists recent actions with the name of the person or app that performed each one. It holds the 250 most recent actions and cannot be filtered or exported, so it is a review tool, not an audit trail; still, an agent that acts as a named app is visible there, and one acting as the founder is invisible. Shopify: activity logs in the admin

Tokens, scopes and rotation

BUILD ON THE MIDDLE LANE · SHORT-LIVED, SCOPED, ROTATED WITHOUT A HUMANTHEME ACCESSPASSWORDStaff creates itin the Theme Access appViewed oncelink dies after 7 daysCI secretSHOPIFY_CLI_THEME_TOKENDelete = revoketheme access endsDEV DASHBOARDCUSTOM APPClient ID + secretscopes set per versionToken requestclient credentials grantExpires in 24 hre-request, no humanRotate the secretin the Dev DashboardLEGACY ADMINCUSTOM APPToken shown oncethen never againNever expireslives until revokedUninstall + reinstallthe only rotationNever delete the appnone made after 1 Jan 2026FIG. 02THREE TOKEN LIFECYCLES
Fig. 02 Three ways an agent can hold Shopify access, and what rotation means for each. The middle lane expires on its own, which is why it is the one to build on.scroll →
CredentialReachesLifetimeRotate or revokeGive it to an agent?
Theme Access passwordThemes only (write_themes)Until deletedDelete it in the Theme Access appYes, for theme work on an unpublished theme
Dev Dashboard custom app tokenThe scopes on the app version24 hoursRe-request; rotate the client secret in the Dev DashboardYes, the default for data work
Legacy admin custom app tokenThe scopes set in the adminNever expiresUninstall and reinstall the app; never delete itOnly until migrated
Storefront API tokenPublic storefront dataUntil revokedRevoke in the adminNot for writes; it is public by design
Staff, collaborator or owner loginEverything the role allowsUntil the account is removedRemove the accountNever

Three details decide whether the middle lane is safe in practice. First, scopes come in read and write pairs, and you choose them per app version, so the agent’s token cannot reach a resource the version never declared. Shopify: access scopes. Second, rate limits are per app and store: the GraphQL Admin API restores 100 points a second on a standard plan, 200 on Advanced, 1,000 on Plus and 2,000 on Enterprise, and no single query may cost more than 1,000 points, so a badly written agent loop throttles itself rather than the store. Shopify: API limits. Third, versions: Shopify releases an API version every quarter and supports each for at least twelve months, so pin the version in every request and let the agent see the date in the URL. Shopify: API versioning

The pattern we ship is small. The client secret lives in a secrets manager, a short script exchanges it for a 24-hour token, and the agent’s environment receives only that token. Putting the exchange behind a small integration service that owns the secret and issues nothing longer-lived than the job is what turns rotation from a calendar reminder into a property of the system.

Exchange a client secret for a 24-hour token, then run one scoped readjavascript
// token.mjs: a 24-hour token for a Dev Dashboard custom app, then one read.
// The client secret lives in your secrets manager, never in the agent's prompt.
const shop = process.env.SHOPIFY_SHOP; // your-store.myshopify.com

const grant = await fetch(`https://${shop}/admin/oauth/access_token`, {
  method: "POST",
  headers: { "Content-Type": "application/json" },
  body: JSON.stringify({
    client_id: process.env.SHOPIFY_CLIENT_ID,
    client_secret: process.env.SHOPIFY_CLIENT_SECRET,
    grant_type: "client_credentials",
  }),
});
const { access_token, expires_in } = await grant.json(); // expires_in: 86399

// Hand the agent only access_token. It dies in 24 hours and carries only the
// scopes on the app version, so read_products here cannot touch an order.
const res = await fetch(`https://${shop}/admin/api/2026-07/graphql.json`, {
  method: "POST",
  headers: { "Content-Type": "application/json", "X-Shopify-Access-Token": access_token },
  body: JSON.stringify({ query: "{ products(first: 5) { nodes { id title } } }" }),
});
const { data, extensions } = await res.json();
console.log(data.products.nodes, extensions.cost.throttleStatus); // points left in the bucket

One more line of defence costs nothing: Shopify tokens carry recognisable prefixes, and GitHub’s secret scanning lists Shopify access tokens among its partner patterns, so a token that lands in a repository is flagged rather than sitting there quietly. Treat the flag as a rotation, not a false positive. GitHub: supported secret scanning patterns

What breaks in production

For this guide we went through our own Shopify delivery records. Client names are withheld. These are the access failures that actually cost time or trust, and the rule each one taught.

  1. Write the scope list before the prompt. If you cannot name the scopes a job needs, the agent is not ready to run it. Read scopes are the default; a write scope is a decision with an owner.
  2. Preview themes and dry runs are the safety net, not the token. A perfectly scoped write_products token will still overwrite two thousand prices if the job has no dry run. Scope limits the blast radius; preview and rollback limit the damage inside it.
  3. Rotation is a property of the credential, not a task for a person. Choose credentials that expire, and put the ones that do not on a migration list.

The Agent Blast Radius Score

The Agent Blast Radius Score is our triage model for access an agent already holds. It does not say whether the agent is any good. It says how much a bad afternoon could cost, and how urgently to re-key.

Agent Blast Radius Score0–12
+4The agent holds a staff, collaborator or owner login, or a token from an app with every scope ticked
+3Write scopes wider than the job: write_orders or write_customers on a theme task, or write_themes pointed at the published theme
+2The token never expires and nobody owns rotation: a legacy admin app, or a secret pasted into a chat or a committed .env
+2Writes land on live data with no dry run, no preview theme and no way to roll back
+1Nobody reads the store activity log and the app has no named owner
0–2 · Run itScoped, expiring, previewed. Review the activity log weekly and re-check when the job changes.
3–6 · Narrow it firstSplit the app by job, drop to read scopes where you can, add the dry run, then re-score.
7–12 · Re-key todayRevoke what the agent holds, issue a scoped credential, and only then let it run again.

A theme agent on a Theme Access password against an unpublished theme, in a repository with Theme Check, scores one or two. The same agent given the founder’s login because it was quicker scores nine before it has done anything.

A real boundary: the app has to be born in the merchant’s organisation

01Merchant creates the appIn their own Dev Dashboard organisation
02Scopes per versionRead first; one write scope per job
03Secret into the vaultNever the agent’s prompt or a chat
0424-hour tokens per jobActivity log reviewed; secret rotated on exit

Recommendations by business type

UK DTC brand on a premade themeTheme Access, unpublished theme, nothing else

Your agent edits Liquid, sections and JSON templates. That needs write_themes and no data scope at all. One Theme Access password in CI, a preview theme per branch, and the founder’s login never leaves the founder.

High-SKU retailer running bulk jobsRead scopes first, one write scope per job

Let the agent read the catalogue with read_products and propose the change as a diff. Only the job that applies it gets write_products, on a 24-hour token, with a dry run and an export of the before state.

Merchant with legacy admin appsMigrate before you connect an agent

Every legacy app token never expires and rotates only by reinstall. Recreate each integration as a Dev Dashboard app with the same or narrower scopes, move the callers, then uninstall the legacy app. Do not delete it until the replacement is proven.

Agency or multi-store operatorOne app per client, born in the client’s organisation

Keep a human collaborator account for the humans and a scoped app for the agent. The client secret sits in your secrets manager against the client’s name, and rotating it on staff exit is a two-minute task, not an incident.

Our ruleAn agent gets a credential, not a login. If you cannot say what it reaches, when it expires and how you revoke it without touching a person, it is not ready to be handed over.

Frequently asked questions

Can I give Claude Code my Shopify admin login so it can make changes?
No. A staff, collaborator or store-owner login carries every permission the role has, cannot be scoped to one job, cannot expire on its own, and is protected by two-factor prompts built for a person. Give the agent a credential instead: a Theme Access password for theme work, or a custom app token with the narrowest scopes that fit for data work.
What is the difference between a Theme Access password and a custom app token?
A Theme Access password is created by store staff in the Theme Access app, is viewed once, grants write_themes and nothing else, and is revoked by deleting it. A custom app token carries whatever Admin API scopes the app version declares, from read_products up to write_orders, and for apps created in the Dev Dashboard it is issued through the client credentials grant and expires after 24 hours.
Do custom apps still exist after January 2026?
Yes, but they are created differently. Since 1 January 2026 you cannot create a new custom app in the Shopify admin under Develop apps. New custom apps are created in the Dev Dashboard and installed on stores in the same organisation. Existing admin-created apps keep working as legacy apps.
How do I rotate a Shopify Admin API token?
It depends on the app type. For a Dev Dashboard custom app, tokens from the client credentials grant expire after 24 hours, so rotation is a re-request, and the client secret itself can be rotated in the Dev Dashboard. For a legacy admin-created app the token never expires and the only rotation is to uninstall and reinstall the app, which issues a new token and breaks anything using the old one until it is updated. Never delete a legacy app: no replacement can be created.
Does the Shopify Dev MCP give an AI agent access to my store?
No. The Dev MCP server runs locally without authentication and gives the agent Shopify's documentation, GraphQL schema and validation tools. It does not hold a store credential. Anything that reads or writes real store data needs a separate, scoped token, and that token is the thing this guide is about.

Primary sources

Published 15 Sep 2026Reviewed 15 Sep 2026Reviewer Appycodes Editorial Team

Technical and operational guidance, not legal advice.

The engagements this writing comes from

UK · Europe · Worldwide

selected work

Where these numbers came from

Production systems with the delivery figures attached.

Creoate product interface01
B2B commerce

The engineering partnership behind a cross-border wholesale marketplace.

Next.js storefront, Python ingestion pipelines, DynamoDB data layer and AWS infrastructure.

8+ yearsone team, still shipping
Ontick product interface02
Event technology

A commission-free ticketing platform built for ownership and scale.

Multi-organiser commerce, Stripe instalments and two native apps in one connected platform.

£2M+processed since launch
Easyship product interface03
Global logistics

Embedded product engineering for a global shipping platform.

Rate, tax and duty calculators, server-rendered courier pages and a custom MongoDB CMS.

550+couriers on the calculator
TEFL.ie product interface04
Education & training

A course-commerce and learning platform wired into one system.

WordPress and WooCommerce, a Moodle LMS, Stripe deposits and Zoho CRM, tied together with Zapier automation.

8 yrsengineer & run, since 2017
All White Laser product interface05
Medical aesthetics

A bespoke platform that finances aesthetic machines on Direct Debit.

A lead-to-billing system on GoCardless Direct Debit, provider certification, and a React Native app for machine owners.

9 yrsbuild & run, since 2017
Decofetch product interface06
Luxury commerce

A custom furniture marketplace engineered from storefront to infrastructure.

Server-rendered Next.js commerce over a Laravel API, bespoke operations tooling and re-architected AWS infrastructure.

0→livecustom, front to back
BA Engine Room product interface07
AI operations

An AI-native operating system that runs a consultancy lead to invoice.

Discovery briefs, e-signed contracts, Stripe deposits, delivery milestones and time tracking in one operational system.

0→1built from the ground up
PlusHeat product interface08
Home services

A conversion platform for a growing UK boiler-cover provider.

Custom plan configuration, postcode-qualified lead journeys, CRM synchronisation and campaign landing pages.

5 yrsweb partner since 2021
Léonia product interface09
Beauty commerce

A custom Shopify store for a French beauty brand.

Custom theme, customer accounts, loyalty rewards, referrals and gift-with-purchase offers.

5 yrspartners since 2021
Shutters 365 product interface10
Home improvement

Made-to-measure shutters with live pricing.

A seven-step product builder with live previews, sample orders and supplier tools.

7-stepconfigurator, live pricing
Bloc Ads Manager product interface11
Advertising

A self-service advertising platform for venues.

Campaign creation, audience targeting, in-app ads and reporting linked to venue check-ins.

check-insclosed-loop attribution
Bloc product interface12
Social events

An events app with the tools to run it.

Mobile app, backend, advertising tools, a digital marketplace and website.

4+ yrsone team, five codebases
Zonely product interface13
Social mobile

Two mobile apps for real-time companionship.

Customer and buddy apps with per-minute billing, wallets, moderation and admin tools.

2 appsconsumer + buddy, iOS & Android
Player Profile Hub product interface14
Grassroots football

Player profiles and discovery for youth football.

Verified profiles, video highlights, coach discovery and safeguarding on web and mobile.

0→1built from the ground up
DeepSpatial product interface15
Geospatial AI

Websites and a talent platform for DeepSpatial.

Corporate and investor pages, the Xploor talent platform and ongoing releases on AWS Amplify.

2 yrsone team, ongoing
Yippee Malta product interface16
Travel

Tour bookings with a custom mobile-first checkout.

A multilingual website connected to the booking API, with deposits, coupons and affiliate tracking.

90+core web vitals, mobile & desktop
Professional Energy product interface17
Energy brokerage

One platform for tenders, contracts and accounts.

Supplier tenders, contract management, brokerage accounting and client records.

100+suppliers in one tender

Tell us what you are trying to build.

A thirty-minute call with the engineer who would run it.

Book a call