I’m trying to implement a user-facing API in which users can programmatically pull an access token to query our API, but can’t seem to find any documentation for this particular use case.
Is this a use-case supported by Auth0? All of the user flows seem to depend on either a native or web app.
From what I can tell, third-party app user consent still involves a web-flow with an authentication prompt.
I don’t even want to register a third-party app. I just want user-level access to my API, where an individual user can programmatically get an access token (e.g., with curl) that can be used to hit the API.
Thanks for the clarification. Is access of those user’s apps restricted to resources belonging to the users themselves, or are you wanting to give general access to an API, where no resource owner exists?
The more appropriate OAuth way would be to use Third-Party clients to allow access to the API, and Device Flow or Client Credentials Flow to issue tokens. This will involve getting user consent at least once. You can use refresh_token to only ask for consent once, in a similar fashion than Github or Twitter do, among others.
Option B - Resource Owner Password Grant
Using ROPG is not advised, because it involves passing the password to the /oauth/token each time a token needs to be issue, among other security caveats.
With that in mind, this is the only option that would allow your individual users’ CLI apps to get access to the users’ resources without prompting for consent.
You’re correct. Client credentials intends to authenticate the app. There could be ways for you to know what data is the client restricted to access, without necessarily representing that user. For example, if every user gets a client of their own, you could use a Client Credentials Hook to add custom claims to the access_token to help your app identify what type of access the client has.
The idea of using third-party apps is that you can create clients (Applications) that don’t have administrative access to your tenant (via Management API). That’s why they should be distinct from First-Party clients.
Good question. In the case of Client Credential, you would expose the client_id and client_secret of the Third-Party app that your user created via your own app. This would allow them to obtain tokens with that app. You would use the Client Credentials Hook rule (if needed) to add custom claims that could help your app identify what resource the customer’s client is supposed to access.
The idea that each user is its own “app” feels hacky and cumbersome to implement.
This seems like a relatively common use case, but the lack of straightforward documentation seems to suggest that Auth0 isn’t really built to support this kind of flow. Is that wrong to think?
I understand what you mean. There’s definitely other ways of granting API access to users. For example, you can generate API tokens that you store on your side, or on the user’s app_metadata in Auth0, that their apps pass to your API via a header in a format like email:api_key. Your app would search for the user, verify if the API key matches, and grant access. This is definitely a feasible implementation, with its own security caveats However, it wouldn’t be OAuth.
If you want to use OAuth to give users access to their data via your API, then it will involve creation of Clients, or have the users’ apps to send email + password to use Resources Owner Password Grant (as I mentioned before, not recommended). That’s how the protocol was designed. You can see this implementation in place for websites like Github, Twitter, Facebook, etc.
I want to circle back around to the Authorization Code Flow question because it’s still not clear to me why I couldn’t set up a first-party app that does nothing but issues refresh tokens to users.
Couldn’t I then have those users hit our api with their refresh tokens, and request new access tokens as needed, so long as the client secret stays on the server side?
Are you thinking of getting a refresh_token as part of their authentication process, and sharing it with the users? Or instead having a separate auth flow where they enable API access in their settings screen, for example?
That could work. However, you also need to give the user a way to revoke the refresh_token, in case it gets exposed. This would mean having to ask them to re-authenticate to obtain a new one. Their app session would be linked to their CLI sessions. Additionally, if they want to setup multiple CLI apps to access the API, all of them would share the same refresh_token. If revoked, they would need to update all the apps.
Have you considered using Device Flow? Each CLI app would be a device that the user has to authorize once. The advantage is that you could show the user all the devices that they’ve authorized, and allow for refresh_token revocation for each of them independently. I know this adds the extra step of the initial authorization per each of the user’s app, but it’s definitely a superior solution in terms of security.