Can I use a refresh token as a user API Token?

We would like to give our users the ability to create a token that does not expire, so they can give that credential to a third-party client (e.g. cli) and have it act as them (with their permissions) when calling our APIs.

I have created the following sequence flow diagram showing how this might work:

As you can see, this requires creating a single Application in Auth0, configuring it for refresh and password grants (ONLY, no client_credentials grant), and sharing that single application’s client_id and client_secret with all users.

I have seen the previous discussion around API tokens/keys (e.g. How to implement API keys using Auth0?) but none of those seemed to do quite what we want or have other management drawbacks. However, I’m nervous that we need to give all users the credentials for a single application in Auth0 - i.e. both the client_id and client_secret, despite the docs and my testing showing that you can’t get an access_token without a valid refresh_token or username and password.

Can anyone (especially Auth0) confirm whether this is a secure use of Auth0 or if not, what the issue(s) are and how we might best resolve them?

Thanks in advance.

Hi Alex,

This does not look secure to me. Without going into much detail, you are sharing a secret with everyone. That’s not a good start.

Having a token that never expires is a red flag for me.

There is a standard way for 3rd party apps to act on behalf of customers. Start here: https://auth0.com/docs/applications/concepts/app-types-first-third-party#third-party-applications

That should do what you need.

John

Thanks John.

Our use case was to create credentials that represent the user that never expire. The client_id/client_secret used by Auth0 applications do not expire (but can be rotated). I’m not sure I understand why non-expiry of credentials is a problem for users but not applications/clients?

In our case I think we were assuming we could create a single credential for a user that could be used with any client - ours, or a third party - without differentiation.

In reality the clients we want to grant access to at present are our own, so actually creating first-party applications to represent these and delivering the client_id and client_secret with the clients might be the best route for now. However I’d like to dig further in to your response to ensure I’m understanding correctly:

Third Party Applications
So I took a look at the third-party applications. All it appears to do is force the users to consent to actions taken by the client (which is not desirable in our use case as these are mainly machine-to-machine clients (e.g. CLIs) that do not have a way of presenting a UI to request consent). Perhaps I am missing something here?

They still have the drawback of creating separate applications, which slightly complicates managing through the dashboard, and potentially causes problems with our deployment model of using the Auth0 Deploy CLI tool with the AUTH0_ALLOW_DELETE flag set to delete unused configurations. Do you have any thoughts on this issue?

Sharing Secret
So a simple/obvious fix for the problem of sharing a single client_id/client_secret with all customers might be to provide an endpoint on our service that exchanges the refresh_token for an access_token on behalf of the user. In this way the client_id/client_secret are not made visible to the end users at any point. Do you see any issues with this approach?

Device Authorization Flow
Device Authorization Flow is not appropriate for our use case as it requires per-device registration triggered from the device, and we want the ability for customers to request a key ahead of time to be used with one or more devices.

Hey there @alex.broad!

I’m sure @john.gateley will cover that once he’s online!

1 Like

Hi Alex,

In brief, you use the 3rd party approach where the user, at the beginning, goes through the flow and consents. This flow results in a refresh token (which is also known as an offline access token) that can be used for your CLIs and M2M clients. Make sense?

John

@john.gateley, what is the third party approach? I assume you are referencing https://auth0.com/docs/api-auth/dynamic-client-registration?

It’s the link I gave in my first reply.

Basically, the 3rd party app redirects the user to the first party tenant, the user authenticates and consents in the tenant, then is redirected back to the third party with an auth code. The third party then exchanges the auth code for an access and refresh token.

Once the third party app has the refresh token, it can exchange that for a new access token when needed.

John

This flow works for web based clients, but not non-web clients (I.e. a CLI)., as there is no redirect url to redirect to.

Hi Alex,

I would suggest you consider using Auth0’s professional services: https://auth0.com/docs/services

If this is not a standard “3rd party approach”, the scenario is complex, and sounds to me like it would involve device flow as well. (But I am not sure I am getting the whole picture here). In that case, Professional Services would be good to ensure you get the right solution, and that it is secure.

To try to reply: the initial authentication has to be done via a web client, but once you receive the refresh token, that can be used by your back end without a web client.

John

1 Like

Hi John,

Thanks for all the feedback. Given right now all our clients are under our control and not third party clients, do you see an issue with my earlier suggestion for fixing the shared secret issue by hosting an endpoint that exchanges the refresh token with Auth0 on our clients’ behalf?

Thanks in advance, Alex.