OAuth-in app and scopes

@nayelyz @Itati

I have a browser-based tool (with backend) much like the advanced MySmartThings app, but offering some additional capabilities. It was originally implemented to use PATs, which has worked great. I’m now converting it to use oauth, but am running into some issues that might be showstoppers. I’m hoping you can help me.

1) When creating an oauth-in app using the CLI, there is a very limited list of scopes to choose from. Specifically, here is the list available via the CLI prompts:

r:devices:*, w:devices:*, x:devices:*, r:hubs:*, r:locations:*, x:locations:*, r:scenes:*, x:scenes:*, r:rules:*, w:rules:*, r:installedapps

but here is the list I need, based on the various API calls my app can make for the user:

r:apps:*,r:channels:*,r:customcapability,r:deviceprofiles,l:devices,r:devices:*,w:devices:*,x:devices:*,r:drivers:*,w:drivers:*,r:installedapps:*,l:installedapps,r:invitations,r:locations:*,x:locations:*,r:rules:*,w:rules:*,x:rules:*,r:scenes:*,x:scenes:*,r:schedules

2) When redirecting to the SmartThings Login page, you present the user with a list of locations with only one to be selected. However I need to allow users to select from their list of locations from within my app and perform various API calls accordingly. I don’t want them to have to sign out and sign back in again every time they want to switch to a different location. (Using PATs, there’s no issue.).

Unfortunately the login page is returning a server error for me right now when a location is selected, but before the ‘Authorize’ button is even clicked, which is a whole other problem. Let’s deal with that separately.

Is the oauth process intentionally designed to limit API access as I found above? Is there a way to provide a more expansive list of scopes when creating an app with the CLI? And is the oauth login process always going to limit me to a specific location?

It may be possible to add some extra scopes via the CLI (it falls under the apps:oauth section) but I think the problem you will hit is the same one that has left me desperately clinging on to about three remaining PATs to avoid rendering an app I have been working with for seven years effectively useless. The issue is that PATs work at the USER level and you need that to a) access user account specific things such as apps and device profiles, and b) see all your Locations at once.

The OAuth-In apps work at the LOCATION level, giving you access to a single Location, but the API Reference implies you can opt to use the USER level too, and indeed that is what the CLI is using. However I had no joy with this. @nayelyz made some enquiries and it turned out that USER requires bespoke tweaks on the ST end and is more of an internal thing.

So that was me hosed. There doesn’t seem to be any way to get a renewable USER level token. Even being able to create a 24 hour PAT via an API call would be helpful.

I have also had many issues with scopes, though probably more with Webhook apps. The API reference, the CLI and the Developer Workspace are gloriously inconsistent about what is needed and what is available (things like w:devices versus w:devices:*) and bizarrely the API Reference mentions the mobile and service scopes as if they are public knowledge. On many occasions I have created an app with a list of scopes that couldn’t be authorised. If I split the list in half I could narrow down the problem scope. Then I could do it again and again and end up with no scopes left.

I have been known to ‘borrow’ the CLI token when doing stuff manually (it has its own scope that can occasionally do things a PAT can’t). Then I discovered a little while ago that if you logout and log back in to the CLI you get the same token back with it’s original expiry date, and indeed that it keeps working after logout anyway. So if you accidentally expose your CLI token (or someone reads it from the config file) it is squeaky bum time as you can’t disable it.

So if there is a path forward I’d be interested to hear about it too.

Like an AI agent?

Sir - you are a fountain of knowledge as always. Thank-you for sharing your experience.

Hi, @TAustin
I only see an issue with the “r:locations:, x:locations:” scopes since the API_ONLY app can access a single location’s information.

They don’t need to log out and back in to their account. If they enter the “Authorization” URL again, they’ll see the corresponding page to select another location. If the token generated for an authorized location hasn’t expired, it will remain valid, and if they go through the authorization process, the same token will be returned.
But, indeed, you won’t be able to list the user’s locations, but perhaps you can keep a record of “known locations” listing the ones that you already had access before and refresh the access token accordingly.

About this issue, can you share the complete URL to check it from my side, please? You can do it through a DM.

Thanks for reply @nayelyz !

So you are confirming what @orangebucket had indicated: that I cannot use any APIs associated with the user, and not the location?

Regarding re-authorizing for another location: will the login page return a different code to my redirect URL, and I still have to exchange it for a token - even though the token I get back might be the same as the prior location?

Regarding the login page server error - I will DM you the URL; maybe there is a problem there.

The token will be different per location. What I meant before is that if the user authorizes access to a location A. Then goes to authorize a new location B, then it will get another token.
If the user goes back through the authorization page and selects Location A again, the token retrieved when the code is exchanged will be the same (if it is still valid).

Yes, I confirm that with the token gotten after the authorization to a specific location, you’ll only be able to see info within it. Other calls outside that limit will return a 403 error.
I’ll share your comment with the engineering team as well since we’ve seen more cases where having a “user level” access would be useful so they’re aware of the requirement.

Hi, @TAustin
Thank you for sending the URL.
So, when you whitelist the scopes for the API_ONLY app, all of them are used when asking the user to authorize access. Technically, adding it to the URL you present to the user isn’t necessary.

I removed that parameter from your URL, and it was added automatically when I selected the location.
I noticed that the difference between them is that you separated the scopes with , and they must be separated with a single space.