Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add support for authenticating using azureauth cli #1464

Merged
merged 15 commits into from
Nov 29, 2023

Conversation

demoray
Copy link
Contributor

@demoray demoray commented Nov 16, 2023

This PR adds support for calling out to the azureauth CLI.

https://github.com/AzureAD/microsoft-authentication-cli

Copy link
Contributor

@kyle-rader-msft kyle-rader-msft left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you so much @demoray for jumping on this! This will unlock easy usage across a lot of developer tools!

@demoray demoray changed the title Add support for authenticationg using azureauth cli Add support for authenticating using azureauth cli Nov 17, 2023
@heaths
Copy link
Member

heaths commented Nov 17, 2023

After discussing with some members of the Azure SDK Identity team, they have no plans to support azureauth at this time but are aware of it and have talked with the team; however, they were fine with the idea to make it an optional feature in rust - something our other languages don't enjoy. If/when we support azureauth we can revisit but our understanding is that this is mostly (only) an internal-only tool at this point.

So can you instead put this behind an optional off-by-default feature?

@kyle-rader-msft
Copy link
Contributor

kyle-rader-msft commented Nov 17, 2023

@heaths That is understandable, we very much appreciate the inclusion as an optional feature :) (ty, Rust).

AzureAuth is OSS and might be used outside the company, but we explicitly have no inherent telemetry as we care about data privacy first and foremost.

@demoray
Copy link
Contributor Author

demoray commented Nov 17, 2023

After discussing with some members of the Azure SDK Identity team, they have no plans to support azureauth at this time but are aware of it and have talked with the team; however, they were fine with the idea to make it an optional feature in rust - something our other languages don't enjoy. If/when we support azureauth we can revisit but our understanding is that this is mostly (only) an internal-only tool at this point.

So can you instead put this behind an optional off-by-default feature?

Done.

@demoray demoray closed this Nov 17, 2023
@demoray demoray reopened this Nov 17, 2023
Copy link
Contributor

@kyle-rader-msft kyle-rader-msft left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the feature flag, 2 remaining small comments :)

All,
#[cfg(target_os = "windows")]
IntegratedWindowsAuth,
Broker,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
Broker,
#[cfg(target_os = "windows")]
Broker,

Broker would also need it's own cfg atribute right?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@demoray ping.

self
}

fn get_access_token(&self, resource: &str) -> azure_core::Result<CliTokenResponse> {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could we take scopes: &Vec<String> or similar here instead of a single resource?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@demoray After reading the TokenCredential trait source, I see that resource here is actually a space separated list of scopes, or potentially the concept of a resource as parsed by the az CLI. But MSAL only takes a list of scopes, which AzureAuth will turn --resource into, but we recommend passing --scope repeatedly for each scope needed.

I think we need to test this a little further and likely split this "resource" (maybe rename it scopes), and pass each value as it's own --scope for azureauth to correctly handle them.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would prefer to do this as a follow-up PR, as I think the underlying trait should be updated to take a list of scopes.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So long as this doesn't ship, a follow up PR seems okay. I do not think this will work as is.

@kyle-rader-msft
Copy link
Contributor

kyle-rader-msft commented Nov 20, 2023

@demoray , One more flag we highly encourage passing when using AzureAuth is the --prompt-hint flag, which, if possible, when there is an auth prompt, will be added to the auth prompt title bar. This only works, at present for WAM dialogs on Windows, but it aides with telemetry (if using it) and in the future will hopefully have better display options on Mac/Linux.

Perhaps to future proof, we can add a with_args method to take an arbitrary list of extra args one might want to add to their usage?

@kyle-rader-msft
Copy link
Contributor

Oh, @demoray sorry, I realized that method takes a resource, because the Trait requires it to do so... Perhaps, we can adhere to that, but internally pass --scope <resource/.default, and provide the extra args extensibility point to allow adding more scopes or any args you want.

@demoray
Copy link
Contributor Author

demoray commented Nov 21, 2023

@demoray , One more flag we highly encourage passing when using AzureAuth is the --prompt-hint flag, which, if possible, when there is an auth prompt, will be added to the auth prompt title bar. This only works, at present for WAM dialogs on Windows, but it aides with telemetry (if using it) and in the future will hopefully have better display options on Mac/Linux.

Perhaps to future proof, we can add a with_args method to take an arbitrary list of extra args one might want to add to their usage?

I've added --prompt-hint.

@kyle-rader-msft
Copy link
Contributor

@demoray While testing this internally, we quickly found (and confirmed by reading the source for Credential, that each header construction invokes the get token method. So, internally we've tried adding to the AzureAuthTokenCredential a Mutex<Option<TokenCliResponse>> to cache the token in memory, and only proceed with calling azureauth if the token we have is valid for <= 2 minutes (which could be another ctor arg).

Calling AzureAuth can be expensive (300-1000ms depending on what's going on under the hood). So caching this will be important for performance in developer facing scenarios, which is exactly where AzureAuth is designed to be used :).

@johnbatty
Copy link
Contributor

johnbatty commented Nov 22, 2023

@kyle-rader-msft Regarding token caching, there's an existing wrapper for this - see AutoRefreshingTokenCredential.

See my azure_devops_rust_api example code for typical usage.

This is clearly not a great situation, as it is too easy for people to use the existing credential providers with no caching. Ideally we would integrate the token caching into the credential providers so that it is done by default (which the other Azure SDKs seem to do).

I raised an issue about this earlier this year, but have not yet had a chance to implement it:
#1228

One further snippet on token caching - we had an issue raised previously which observed that the token cache needs to be per-resource. I fixed this in AutoRefreshingTokenCredential, but worth being aware of it:
#1225

Copy link
Contributor

@kyle-rader-msft kyle-rader-msft left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we still need 1 cfg on the broker mode (I could also see just leaving out the concept of modes and instead taking an arbitrary list of extra args to pass, so that as the args evolve over time this wrapper need not chance).

The other question I have is on the "resource" passed and it actually being a space separated list of scopes.

@kyle-rader-msft
Copy link
Contributor

@johnbatty - Thank you for calling that out!!

@demoray
Copy link
Contributor Author

demoray commented Nov 28, 2023

I think we still need 1 cfg on the broker mode (I could also see just leaving out the concept of modes and instead taking an arbitrary list of extra args to pass, so that as the args evolve over time this wrapper need not chance).

The other question I have is on the "resource" passed and it actually being a space separated list of scopes.

@demoray demoray closed this Nov 28, 2023
@demoray demoray reopened this Nov 28, 2023
Copy link
Contributor

@kyle-rader-msft kyle-rader-msft left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍 given impending follow up PR.

@cataggar cataggar dismissed heaths’s stale review November 29, 2023 16:18

Functionality was placed behind a feature gate. utf8 encoding was verified.

@@ -50,6 +50,7 @@ development = []
test_e2e = []
client_certificate = ["openssl"]
vendored_openssl = ["openssl/vendored"]
azureauth-cli = []
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: we use_ in the other features

@demoray demoray merged commit 88d55f4 into Azure:main Nov 29, 2023
19 checks passed
@demoray demoray deleted the add-azureauth-support branch November 29, 2023 17:02
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

5 participants