Dear reader, thank you for the awesome service! Event though there seems an extreme amount of different authentication scenarios considered I get frustrated by the fact that there doesn’t seem to be any documentation on how to setup an authentication mechanism that can be run on the client’s computer but without any graphical shell available. Think Heroku CLI, the user has an account on my service but I want the user to login on his server and use the platform without any graphical shell being available. I’ve considered the following
@advanderveer there isn’t a lot of data on this on the web sadly. In fact it isn’t so straight forward. When a CLI needs a token issued on behalf of a user the only flow that satisfies all use cases for a CLI is the Device Flow. Unfortunately Auth0 does not currently support the device flow.
Another option is the Authorization Code + PKCE flow, but this doesn’t work for all use cases and has some concerns to consider. First, Authorization Code + PKCE requires a web browser which is a deal break when you need a CLI that is runnable on a headless machine (think SSH). There are OOB (out of band) implementation on the web, but in my opinion these aren’t really the best choice. Secondly, in order to get an in-band or specification complain Auth Code + PKCE working in a CLI your application needs to be able to listen on the loopback ip. This means any application running on the machine can steal the code. Good news is the PKCE mitigates that code from being used by an application eaves dropping on the loopback taking the code and trying to exchange it for tokens.
The Device Flow fixes some of the problems with Authorization Code Flow + PKCE, but it adds an extra manual step for users. If you’ve ever used an app on Roku or Apple TV you may be familiar with this flow. The application will present a URL and a one time code to you. The user is then instructed to open a web browser, enter the URL, and then the authorization server prompts the user for credentials. After the credentials are accepted the user enters in the one time code. If all these challenges are passed then the authorization server says this user is good to go. While all these steps are happening the application is polling the authorization server waiting for notification that authentication was completed and then the tokens are issued.
This may seem like an odd flow for a CLI at first, but let me explain why this might be good. It can’t be assumed that a CLI runs in an environment where there is a browser or a browser that can be run under current situation. I a user is on a headless OS or has accessed the machine via SSH.
I think the best implementation of a CLI auth that I’ve seen is the Azure CLI. They use device flow and it works great. I’ve seen a number of other approaches too. Teleport as a tsh client that uses Authorization Code + PKCE, Azure uses tokens saved to a profile, and more. All this aside I’d say device flow is the best approach for this.