Skip to content

Commit d712758

Browse files
authored
Remove service credentials from DefaultAzureCredential (Azure#2123)
* Remove service credentials from DefaultAzureCredential Resolves Azure#2093 * Fix lint
1 parent 8c0b6ec commit d712758

File tree

4 files changed

+67
-146
lines changed

4 files changed

+67
-146
lines changed

eng/dict/rust-custom.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
bindgen
22
cfg
33
cfgs
4+
impls
45
newtype
56
oneshot
67
repr
Lines changed: 31 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,27 +1,47 @@
1-
# 0.20.0 (2024-02)
1+
# Release History
2+
3+
## 0.22.0 (Unreleased)
4+
5+
### Breaking Changes
6+
7+
- Removed service credentials from `DefaultAzureCredential` ([#2093](https://github.com/Azure/azure-sdk-for-rust/issues/2093))
8+
9+
## 0.20.0 (2024-02)
10+
11+
### Breaking Changes
212

313
- [#1532](https://github.com/Azure/azure-sdk-for-rust/pull/1532) add `azure_identity::create_credential()`, `SpecificAzureCredential`, `AppServiceManagedIdentityCredential`, `VirtualMachineManagedIdentityCredential`
4-
- BREAKING CHANGE: `DefaultAzureCredentialBuilder::build` now returns a `Result`. If fails when it is unable to create at least one source credential.
5-
- Most credentials may now fail earlier, when they are created, instead of only during `get_token`.
6-
- `DefaultAzureCredential::default()` has been removed, because creating the credential may fail. Please use `azure_identity::create_default_credential()?` or `azure_identity::create_credential()?` instead.
14+
- BREAKING CHANGE: `DefaultAzureCredentialBuilder::build` now returns a `Result`. If fails when it is unable to create at least one source credential.
15+
- Most credentials may now fail earlier, when they are created, instead of only during `get_token`.
16+
- `DefaultAzureCredential::default()` has been removed, because creating the credential may fail. Please use `azure_identity::create_default_credential()?` or `azure_identity::create_credential()?` instead.
717

18+
## 0.18.0 (2023-12)
819

9-
# 0.18.0 (2023-12)
20+
### Breaking Changes
1021

1122
- Removed AutoRefreshingTokenCredential, instead all token credentials now implement caching
1223

13-
# 0.3.0 (2022-05)
24+
## 0.3.0 (2022-05)
25+
26+
### Breaking Changes
1427

1528
- [#756](https://github.com/Azure/azure-sdk-for-rust/pull/756) Export credentials from azure_identity
16-
- BREAKING CHANGE: the credential types have moved. For example:
17-
- use `azure_identity::DefaultAzureCredential` instead of `azure_identity::token_credentials::DefaultAzureCredential`
29+
- BREAKING CHANGE: the credential types have moved. For example:
30+
- use `azure_identity::DefaultAzureCredential` instead of `azure_identity::token_credentials::DefaultAzureCredential`
31+
32+
### Bugs Fixed
33+
1834
- [#751](https://github.com/Azure/azure-sdk-for-rust/pull/751) datetime from azure cli token is in the local timezone
1935
- [#748](https://github.com/Azure/azure-sdk-for-rust/pull/748) adding option to specify client_id for MSI
2036

21-
# 0.2.0 (2022-05)
37+
## 0.2.0 (2022-05)
38+
39+
### Other Changes
2240

2341
- update to azure_core 0.2.1
2442

25-
# 0.1.1 (2022-01)
43+
## 0.1.1 (2022-01)
44+
45+
### Features Added
2646

27-
- initial publish to [crates.io](https://crates.io/crates/azure_identity)
47+
- Initial publish to [crates.io](https://crates.io/crates/azure_identity)

sdk/identity/azure_identity/src/credentials/default_credentials.rs

Lines changed: 33 additions & 135 deletions
Original file line numberDiff line numberDiff line change
@@ -3,31 +3,27 @@
33

44
#[cfg(not(target_arch = "wasm32"))]
55
use crate::AzureCliCredential;
6-
use crate::{
7-
credentials::cache::TokenCache, timeout::TimeoutExt, AppServiceManagedIdentityCredential,
8-
ImdsId, TokenCredentialOptions, VirtualMachineManagedIdentityCredential,
9-
};
6+
use crate::{credentials::cache::TokenCache, TokenCredentialOptions};
7+
#[cfg(not(target_arch = "wasm32"))]
8+
use azure_core::error::ResultExt;
109
use azure_core::{
1110
credentials::{AccessToken, TokenCredential},
12-
error::{Error, ErrorKind, ResultExt},
11+
error::{Error, ErrorKind},
1312
};
14-
use std::{sync::Arc, time::Duration};
13+
use std::sync::Arc;
1514

1615
/// Provides a mechanism of selectively disabling credentials used for a `DefaultAzureCredential` instance
1716
pub struct DefaultAzureCredentialBuilder {
1817
options: TokenCredentialOptions,
19-
include_app_service_managed_identity_credential: bool,
20-
include_virtual_machine_managed_identity_credential: bool,
2118
#[cfg(not(target_arch = "wasm32"))]
2219
include_azure_cli_credential: bool,
2320
}
2421

22+
#[cfg_attr(target_arch = "wasm32", allow(clippy::derivable_impls))]
2523
impl Default for DefaultAzureCredentialBuilder {
2624
fn default() -> Self {
2725
Self {
2826
options: TokenCredentialOptions::default(),
29-
include_app_service_managed_identity_credential: true,
30-
include_virtual_machine_managed_identity_credential: true,
3127
#[cfg(not(target_arch = "wasm32"))]
3228
include_azure_cli_credential: true,
3329
}
@@ -45,31 +41,6 @@ impl DefaultAzureCredentialBuilder {
4541
self
4642
}
4743

48-
/// Exclude using any managed identity credential
49-
pub fn exclude_managed_identity_credential(&mut self) -> &mut Self {
50-
self.include_app_service_managed_identity_credential = false;
51-
self.include_virtual_machine_managed_identity_credential = false;
52-
self
53-
}
54-
55-
/// Exclude using virtual machine managed identity credential
56-
pub fn exclude_virtual_machine_managed_identity_credential(&mut self) -> &mut Self {
57-
self.include_virtual_machine_managed_identity_credential = false;
58-
self
59-
}
60-
61-
/// Include using virtual machine managed identity credential
62-
pub fn include_virtual_machine_managed_identity_credential(&mut self) -> &mut Self {
63-
self.include_virtual_machine_managed_identity_credential = true;
64-
self
65-
}
66-
67-
/// Include using app service managed identity credential
68-
pub fn include_app_service_managed_identity_credential(&mut self) -> &mut Self {
69-
self.include_app_service_managed_identity_credential = true;
70-
self
71-
}
72-
7344
/// Exclude using credential from the cli
7445
#[cfg(not(target_arch = "wasm32"))]
7546
pub fn exclude_azure_cli_credential(&mut self) -> &mut Self {
@@ -79,13 +50,8 @@ impl DefaultAzureCredentialBuilder {
7950

8051
/// Get a list of the credential types to include.
8152
fn included(&self) -> Vec<DefaultAzureCredentialType> {
53+
#[cfg_attr(target_arch = "wasm32", allow(unused_mut))]
8254
let mut sources = Vec::new();
83-
if self.include_app_service_managed_identity_credential {
84-
sources.push(DefaultAzureCredentialType::AppService);
85-
}
86-
if self.include_virtual_machine_managed_identity_credential {
87-
sources.push(DefaultAzureCredentialType::VirtualMachine);
88-
}
8955
#[cfg(not(target_arch = "wasm32"))]
9056
if self.include_azure_cli_credential {
9157
sources.push(DefaultAzureCredentialType::AzureCli);
@@ -99,32 +65,25 @@ impl DefaultAzureCredentialBuilder {
9965
&self,
10066
included: &Vec<DefaultAzureCredentialType>,
10167
) -> azure_core::Result<Vec<DefaultAzureCredentialKind>> {
68+
#[cfg_attr(target_arch = "wasm32", allow(unused_mut))]
10269
let mut sources = Vec::<DefaultAzureCredentialKind>::with_capacity(included.len());
103-
let mut errors = Vec::new();
70+
let errors = Vec::new();
71+
72+
#[cfg_attr(target_arch = "wasm32", allow(clippy::never_loop))]
10473
for source in included {
10574
match source {
106-
DefaultAzureCredentialType::AppService => {
107-
match AppServiceManagedIdentityCredential::new(self.options.clone()) {
108-
Ok(credential) => {
109-
sources.push(DefaultAzureCredentialKind::AppService(credential))
110-
}
111-
Err(error) => errors.push(error),
112-
}
113-
}
114-
DefaultAzureCredentialType::VirtualMachine => {
115-
sources.push(DefaultAzureCredentialKind::VirtualMachine(
116-
VirtualMachineManagedIdentityCredential::new(
117-
ImdsId::SystemAssigned,
118-
self.options.clone(),
119-
)?,
120-
));
121-
}
12275
#[cfg(not(target_arch = "wasm32"))]
12376
DefaultAzureCredentialType::AzureCli => {
12477
if let Ok(credential) = AzureCliCredential::new() {
12578
sources.push(DefaultAzureCredentialKind::AzureCli(credential));
12679
}
12780
}
81+
#[cfg(target_arch = "wasm32")]
82+
_ => {
83+
return Err(Error::with_message(ErrorKind::Credential, || {
84+
"No credential providers available"
85+
}));
86+
}
12887
}
12988
}
13089
if sources.is_empty() {
@@ -149,69 +108,50 @@ impl DefaultAzureCredentialBuilder {
149108
/// Types that may be enabled for use by `DefaultAzureCredential`.
150109
#[derive(Debug, PartialEq)]
151110
enum DefaultAzureCredentialType {
152-
AppService,
153-
VirtualMachine,
154111
#[cfg(not(target_arch = "wasm32"))]
155112
AzureCli,
156113
}
157114

158115
/// Types of `TokenCredential` supported by `DefaultAzureCredential`
159116
#[derive(Debug)]
160117
pub(crate) enum DefaultAzureCredentialKind {
161-
/// `TokenCredential` from managed identity that has been assigned to an App Service.
162-
AppService(Arc<AppServiceManagedIdentityCredential>),
163-
/// `TokenCredential` from managed identity that has been assigned to a virtual machine.
164-
VirtualMachine(Arc<VirtualMachineManagedIdentityCredential>),
165118
#[cfg(not(target_arch = "wasm32"))]
166119
/// `TokenCredential` from Azure CLI.
167120
AzureCli(Arc<AzureCliCredential>),
168121
}
169122

170-
#[cfg_attr(target_arch = "wasm32", async_trait::async_trait(?Send))]
123+
#[cfg_attr(target_arch = "wasm32", async_trait::async_trait(?Send), allow(unused_variables))]
171124
#[cfg_attr(not(target_arch = "wasm32"), async_trait::async_trait)]
172125
impl TokenCredential for DefaultAzureCredentialKind {
173126
async fn get_token(&self, scopes: &[&str]) -> azure_core::Result<AccessToken> {
174127
match self {
175-
DefaultAzureCredentialKind::AppService(credential) => {
176-
credential.get_token(scopes).await.context(
177-
ErrorKind::Credential,
178-
"error getting managed identity credential for App Service",
179-
)
180-
}
181-
DefaultAzureCredentialKind::VirtualMachine(credential) => {
182-
// IMDS timeout is only limited to 1 second when used in DefaultAzureCredential
183-
credential
184-
.get_token(scopes)
185-
.timeout(Duration::from_secs(1))
186-
.await
187-
.context(
188-
ErrorKind::Credential,
189-
"getting virtual machine managed identity credential timed out",
190-
)?
191-
.context(
192-
ErrorKind::Credential,
193-
"error getting virtual machine managed identity credential",
194-
)
195-
}
196128
#[cfg(not(target_arch = "wasm32"))]
197129
DefaultAzureCredentialKind::AzureCli(credential) => {
198130
credential.get_token(scopes).await.context(
199131
ErrorKind::Credential,
200132
"error getting token credential from Azure CLI",
201133
)
202134
}
135+
#[cfg(target_arch = "wasm32")]
136+
_ => {
137+
return Err(Error::with_message(ErrorKind::Credential, || {
138+
"No credential providers available"
139+
}));
140+
}
203141
}
204142
}
205143

206144
/// Clear the credential's cache.
207145
async fn clear_cache(&self) -> azure_core::Result<()> {
208146
match self {
209-
DefaultAzureCredentialKind::AppService(credential) => credential.clear_cache().await,
210-
DefaultAzureCredentialKind::VirtualMachine(credential) => {
211-
credential.clear_cache().await
212-
}
213147
#[cfg(not(target_arch = "wasm32"))]
214148
DefaultAzureCredentialKind::AzureCli(credential) => credential.clear_cache().await,
149+
#[cfg(target_arch = "wasm32")]
150+
_ => {
151+
return Err(Error::with_message(ErrorKind::Credential, || {
152+
"No credential providers available"
153+
}));
154+
}
215155
}
216156
}
217157
}
@@ -324,24 +264,17 @@ mod tests {
324264
let builder = DefaultAzureCredentialBuilder::new();
325265
#[cfg(not(target_arch = "wasm32"))]
326266
assert!(builder.include_azure_cli_credential);
327-
assert!(builder.include_app_service_managed_identity_credential);
328-
assert!(builder.include_virtual_machine_managed_identity_credential);
329267

330268
#[cfg(not(target_arch = "wasm32"))]
331269
{
332270
let mut builder = DefaultAzureCredentialBuilder::new();
333271
builder.exclude_azure_cli_credential();
334272
assert!(!builder.include_azure_cli_credential);
335-
assert!(builder.include_app_service_managed_identity_credential);
336-
assert!(builder.include_virtual_machine_managed_identity_credential);
337273
}
338274

339-
let mut builder = DefaultAzureCredentialBuilder::new();
340-
builder.exclude_managed_identity_credential();
275+
let builder = DefaultAzureCredentialBuilder::new();
341276
#[cfg(not(target_arch = "wasm32"))]
342277
assert!(builder.include_azure_cli_credential);
343-
assert!(!builder.include_app_service_managed_identity_credential);
344-
assert!(!builder.include_virtual_machine_managed_identity_credential);
345278
}
346279

347280
#[test]
@@ -350,25 +283,7 @@ mod tests {
350283
let builder = DefaultAzureCredentialBuilder::new();
351284
assert_eq!(
352285
builder.included(),
353-
vec![
354-
DefaultAzureCredentialType::AppService,
355-
DefaultAzureCredentialType::VirtualMachine,
356-
DefaultAzureCredentialType::AzureCli,
357-
]
358-
);
359-
}
360-
361-
/// test excluding virtual machine managed identity credential
362-
#[test]
363-
fn test_exclude_virtual_machine_managed_identity_credential() {
364-
let mut builder = DefaultAzureCredentialBuilder::new();
365-
builder.exclude_virtual_machine_managed_identity_credential();
366-
assert_eq!(
367-
builder.included(),
368-
vec![
369-
DefaultAzureCredentialType::AppService,
370-
DefaultAzureCredentialType::AzureCli,
371-
]
286+
vec![DefaultAzureCredentialType::AzureCli,]
372287
);
373288
}
374289

@@ -377,23 +292,6 @@ mod tests {
377292
fn test_exclude_azure_cli_credential() {
378293
let mut builder = DefaultAzureCredentialBuilder::new();
379294
builder.exclude_azure_cli_credential();
380-
assert_eq!(
381-
builder.included(),
382-
vec![
383-
DefaultAzureCredentialType::AppService,
384-
DefaultAzureCredentialType::VirtualMachine,
385-
]
386-
);
387-
}
388-
389-
/// test excluding managed identity credential
390-
#[test]
391-
fn test_exclude_managed_identity_credential() {
392-
let mut builder = DefaultAzureCredentialBuilder::new();
393-
builder.exclude_managed_identity_credential();
394-
assert_eq!(
395-
builder.included(),
396-
vec![DefaultAzureCredentialType::AzureCli,]
397-
);
295+
assert!(builder.included().is_empty());
398296
}
399297
}

sdk/identity/azure_identity/src/timeout.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ pub(crate) struct Timeout<F, D> {
2323
}
2424

2525
impl<F, D> Timeout<F, D> {
26+
#[allow(dead_code)]
2627
pub(crate) fn new(future: F, deadline: D) -> Self {
2728
Self {
2829
future,
@@ -59,6 +60,7 @@ impl<F: Future, D: Future> Future for Timeout<F, D> {
5960
}
6061
}
6162

63+
#[allow(dead_code)]
6264
pub(crate) trait TimeoutExt: Future {
6365
fn timeout(self, duration: Duration) -> Timeout<Self, Sleep>
6466
where

0 commit comments

Comments
 (0)