Azure / azure-dev

A developer CLI that reduces the time it takes for you to get started on Azure. The Azure Developer CLI (azd) provides a set of developer-friendly commands that map to key stages in your workflow - code, build, deploy, monitor, repeat.
https://aka.ms/azd
MIT License
388 stars 177 forks source link

Call `azd login` for the user if they invoke an `azd` command and are not authenticated #1391

Open savannahostrowski opened 1 year ago

savannahostrowski commented 1 year ago

If user is not authenticated when they run an azd command we should call azd login under the hood, prompt them to login and then continue the command flow.

Today, if you call azd up and are not authenticated, you get an error. You then have to go call azd login and then azd up again. image

The flow would ideally be:

  1. User calls azd up (or other command) unauth'd
  2. User sees prompt to authenticate
  3. User visits browser to authenticate
  4. User comes back to terminal/VS Code/Codespaces etc.
  5. azd up begins normal flow asking user for env, sub, region once authentication has succeeded.

Additional repercussions of this current behaviour: In VS Code, there is no azd login in the context menu/command palette so the experience is inconsistent if you are invoking commands from the context menu or command palette because you can call all other commands from those interfaces but have to use the embedded terminal for azd login.

vhvb1989 commented 1 year ago

This would be forcing the interactive login flow (or the device-code flow on codespaces, I guess). IMO, the user should decide what flow they want to use (interactive, device, service-principal, etc.). IIRC, we are behaving similarly to the Azure CLI, which will ask you to first run az login before running commands

Also, as part of the multi-tenant support, user can run azd login multiple times and the credentials are accumulated.

This would be also problematic for customers using azd as part of some automated pipeline. If they forgot to log in, the automated process will try to do it automatically and make it hard for customers to understand what's the error (compared to a simple error not logged in)

savannahostrowski commented 1 year ago

We already know when something is interactive mode or not though, right? We already have that logic in place to run azd in CI/CD without prompts. If we know that then we can feasibly just not call login in non-interactive contexts.

Speaking to your point about multi-tenant scenarios, I'm not sure that's actually a concern from a UX perspective. If a developer is working on a multi-tenant project, then they need to authenticate multiple times before they could successfully up. We aren't introducing a new point of failure for them because as it stands if they were to run up prematurely (before that acquisition of all of the right credentials), they'd still hit an error. They can still run azd login however many times before azd up-ing in this new paradigm.

By prefacing our commands with authentication, we eliminate a step (a user can go straight to azd up'ing) for a very high percentage of our users. I also want us to think deeply about what the best user experience is for azd, regardless of what other tools are doing. Different user base, different goals.

ellismg commented 1 year ago

I personally like these being separated. Most tools that I interact with segment logging in from general day to day actions (for example, both the az and gh CLIs behave this way) and I think that's valuable. Random commands popping up a browser to authenticate feels a little weird to me (and in general, I want to log in once and stay logged in, so if I end up logged out I almost prefer an error message instead of silently trying to fix it, because it gives me a hint as a developer that something is wrong with my setup).

The integration with VS Code is interesting - I think we need to expose an azd login action via the VS Code extension anyway? - imagine if a user has multiple accounts and wants to switch between them, how would they do that today?

savannahostrowski commented 1 year ago

I think there are also plenty of examples that swing in the opposite direction and strap an authentication flow on to the front of each command. However, I again want us to have what we think is the user experience which feels smoothest for the greatest number of developers. To your point, this authentication should happen somewhat rarely. This issue I filed is really meant to streamline that first azd experience that a developer has.

In the example you mention about wanting an error as opposed to being pointed at logging in, I'm not actually sure that the user wouldn't come to the same conclusion, that they are logged out. If it's not your first time using the tool, you'd still be able to deduce that your credentials are no longer being stored/in the keychain etc.

weikanglim commented 1 year ago

I wonder if issues around Conditional Access Policy / MFA like #1516 pretty much push us towards an interactive logon on login failures. It is extremely difficult to convey to the user what set of login parameters is required. It can be:

  1. azd login --tenant-id <specific tenant in-question>
  2. azd login --scope <scope> -- we don't currently support this, but I believe AAD policies can be applied on different resources and hence without providing a scope, we won't actually trigger the right MFA prompts.
weikanglim commented 1 year ago

I implemented #1516 that addresses the type of issues users could find when running azd pipeline config, which requires modifying service principals that could be subjected tenant access policies that requires a login prompt.

I don't really feel good about presenting more complicated login commands to the user instead of automatically trying. However, I also see arguments against introducing interactive logins in the command flow:

  1. Infinite login loops. What could happen is that azd incorrectly detects a login error, thus prompting never stops.
  2. Multiple login prompts. Multiple different resources require access, user will be prompted multiple times. It's possible that showing the user the required commands, allows the user to shell script a combined command that solves all the authentication/authorization issue. Whereas an interactive prompt hides the commands needed to be run, and thus the user feels hopeless in being prompted.

If we to implement any kind of automatic prompting, it needs to respect --no-prompt. This helps in the following user scenarios:

  1. VSCode. User should not suddenly receive an invisible prompt when running a command.
  2. CI/CD. Should never hang the pipeline execution.
AnkitSDesai commented 1 year ago

Here is a similar issue I faced. any suggestions is appreciated. https://github.com/Azure-Samples/dotNET-FrontEnd-to-BackEnd-on-Azure-Container-Apps/issues/38 Sounds like it is recommending using AZD login, but when I tried that I get following error. image

rajeshkamal5050 commented 1 year ago

@savannahostrowski @ellismg Moving this to Gallium. Don't think we can make this change for GA.

weikanglim commented 1 year ago

One consideration we need to factor in, if we do this, is how we handle login flags that are specific to the client environment.

For example, azd auth login currently allows the user to choose whether to perform interactive or device code login. If we automatically prompt the user, what authentication flow should be chosen? I do wish if auth was simpler and there was a single flow that worked, that this would be easier.

We could make deviceCode a machine-level configuration which maybe makes more sense.