Why isn't the `read_users` access scope documented as "custom app" only?

Hey y’all,

I’m hitting a wall here and just curious if anyone else has experience with the StaffMember object. In our Plus-only app (Onboard B2B) we give merchants the ability to assign sales staff to companies during the Company approval process - but the staff user has to have access our app first in order for us to be able to access them (because we don’t have access to read_users). This isn’t an ideal merchant experience because some of our shops don’t want to give their sales staff access to apps.

According to the docs here, we have to reach out to Support to enable access to this scope.

Requires read_users access scope. Also: The app must be a finance embedded app or installed on a Shopify Plus or Advanced store. Contact Shopify Support to enable this scope for your app.

When reaching out to support, they’re saying that this read_users is restricted to Plus stores using Custom apps. This is not documented anywhere in the docs and it’s really odd that it would be “restricted” to custom apps.

1 Like

Hi @Jivan! You’re right that this should be documented more clearly. The restriction is mentioned in the REST Admin API User resource docs:

“The User resource is available for private apps and custom apps installed on Shopify Plus stores.”

But the GraphQL StaffMember docs and the main access scopes page don’t mention this - they just say “contact support to enable.” I’ve flagged this with the docs team internally to get this aligned. Thanks for pointing this out!

My understanding of the underlying reason is that read_users exposes staff member data (emails, permissions, etc.), which Shopify restricts to apps that have a direct trust relationship with the merchant - i.e., custom apps they’ve explicitly created and installed themselves. Public apps, even Plus-only ones, don’t have that same trust model.

Hey @Donal-Shopify, I appreciate the clarification here. The reasoning behind does make sense, although with customer PII we at least get a chance to request that in Partners (which one could argue is more sensitive than merchant staff data).

At the very least getting the email for a StaffMember would be great, but there’s no way to request this.

Also, on staffMembers docs here there’s no notice about needing access scopes until I go to nodes > [staffMember!] and actually click through to staffMember.

When querying in GraphiQL, staffMembers also gives me access denied.

Hey @Jivan, good point about needing at least StaffMember.email - that’s valid feedback and I’ve logged it as a feature request internally.

For your immediate use case, the workaround would be to use online access tokens to associate the currently logged-in staff member with app data via app metafields. This lets you track which staff member is performing actions without needing to query the full staffMembers list. Not ideal for showing a dropdown of all available staff during assignment flows, but it avoids needing read_users entirely.

On your note about the staffMembers query giving access denied - that’s expected behavior since the query itself requires read_users. The docs could be clearer about this at the query level rather than only showing it on the object definition. I’ve included that in my feedback to the team.

Been trying to get access to “read_users” scope since are app is primarily used by plus stores and those are generally managed by Agencies and we are having issues where the critical updates go to stores default admin email id and emails regarding quote getting over gets missed as a lot of these high end plus stores default emails id are support@ info@ help@
And these emails dont end up with the correct person resulting in app features being disabled since no one actually so the emails

@Donal-Shopify
So clearly your flagging in dec hasnt made any difference as the doc still says the same

Even the doucmentation doesnt mention the app cant be a public app “Requires read_users access scope. Also: The app must be a finance embedded app or installed on a Shopify Plus or Advanced store. Contact Shopify Support to enable this scope for your app.”

It just says either finance or app installed on plus stores

And Shopify supports first reply is oh your app is not a Finance app and totally ignores their own doc which says “OR” installed on plus stores.

1 Like

Hey @Robin_Singh thanks for calling this out (you’re right to).

The wording on the StaffMember docs still reads like “finance embedded OR installed on Plus/Advanced + contact Support” (StaffMember), but it doesn’t clearly spell out the app distribution constraints. In practice, if you’re building a public app, it’s expected that Support will deny read_users (even if your installs are primarily Plus).

I’m going to raise this again with the docs team so we can (a) make the “custom app only” restriction explicit where read_users is referenced, and (b) add a clear note on the query pages (for example staffMembers) so you don’t have to click through to the object definition to understand why you’re seeing access denied.

In the meantime, if your immediate goal is to identify the currently logged-in staff member (vs listing all staff), you can use an online access token via token exchange which returns an associated_user without needing read_users.

I’ll update this thread once I hear back from the team that owns the docs change - thanks again for bumping this thread

1 Like

Thanks, though, should be available for public apps as more and more app providers collaborate with agencies and apps are installed by vendors/freelancers/agencies specially for plus stores

3 Likes

Hey Donal,

To clarify - we are using the online access tokens method to identify users in our app but they need to access the app first before the store admin can add them to workflows. Which is a bit messy of a conversation to have with these merchants (especially since sales staff don’t typically get access to apps).

Thanks for the context Jivan! While I agree it is cumbersome for your use case, that’s currently the only supported method for non-Custom Apps.

I have added your feedback to an open feature request for the scope to be expanded to Public apps and non-Plus stores also, we can’t make any promises as to when or whether that will be implemented but hopefully this can be considered by the Users team for future release!

1 Like

@Donal-Shopify Another problem with identifying users via the online access token is that it doesn’t guarantee data freshness. If a user changes their email, there’s no way to know unless they open the app and trigger another token exchange.

Getting the contact email for the true Shopify Plus organization owner is also challenging, since shop.accountOwner is protected by the same read_users scope. I wrote more about this here: Shop.email isn't the shop owner email - any way to access shop.accountOwner?

3 Likes

@Donal-Shopify Certainly. I appreciate the feature request. To be clear, our app is a Plus only product since it directly relates to B2B primitives.

1 Like

@Patrick_Jakubik you raise a good point - the online access token workaround is far from perfect.

I’ve added your context about these specific shortcomings to the existing feature request internally. The more feedback we get on this, the more likely it is to be reviewed by the product team - so thanks to everyone for the input.

I’ll update here if there’s any movement on this.

2 Likes