docs(azure_identity): add migration guide#4240
Conversation
Closes Azure#4231 Refs Azure#4228 Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
|
Fixed an authoring error in the Cargo.toml |
There was a problem hiding this comment.
Pull request overview
Adds a new migration guide for azure_identity to help users move from the experimental-era crate versions (≤0.21) and the community-era azure_sdk_auth_aad to the current GA-track azure_identity (v0.22+), aligned with the repo’s crate-root documentation layout.
Changes:
- Introduces
sdk/identity/azure_identity/MIGRATION.mdcovering dependency updates, module layout changes, and new credential types. - Documents updated
TokenCredentialtrait usage (scopes/options/AccessToken) and error-handling patterns. - Adds guidance for async runtime usage and Cargo feature flags (including
client_certificate).
| use azure_identity::DeveloperToolsCredential; | ||
|
|
||
| let credential = DeveloperToolsCredential::new(None)?; | ||
| let token = credential | ||
| .get_token(&["https://management.azure.com/.default"], None) | ||
| .await?; |
There was a problem hiding this comment.
The get_token call here won’t compile unless the TokenCredential trait is in scope (trait methods on external traits require an in-scope import). Add use azure_core::credentials::TokenCredential; (or use UFCS) in this snippet so it’s copy/pasteable.
| use azure_identity::{AzureCliCredential, AzureCliCredentialOptions}; | ||
|
|
||
| let credential = AzureCliCredential::new(None)?; | ||
| let token = credential | ||
| .get_token(&["https://management.azure.com/.default"], None) | ||
| .await?; |
There was a problem hiding this comment.
Same issue as above: this snippet calls .get_token(...) but doesn’t import azure_core::credentials::TokenCredential, so it won’t compile as written. Bring the trait into scope (or use UFCS).
| use azure_identity::{ClientSecretCredential, ClientSecretCredentialOptions}; | ||
| use azure_core::credentials::Secret; | ||
|
|
||
| let credential = ClientSecretCredential::new( | ||
| "your-tenant-id", // &str (not String) | ||
| "your-client-id".to_string(), // String | ||
| Secret::new("your-secret"), // Secret (not String) | ||
| None, // Option<ClientSecretCredentialOptions> | ||
| )?; | ||
|
|
||
| let token = credential | ||
| .get_token(&["https://vault.azure.net/.default"], None) | ||
| .await?; |
There was a problem hiding this comment.
This snippet calls .get_token(...) but doesn’t import the TokenCredential trait, so it won’t compile as written. Add use azure_core::credentials::TokenCredential; alongside the existing Secret import (or use UFCS).
| Credential errors use `azure_core::error::ErrorKind::Credential`. Each credential wraps its errors with a descriptive message and troubleshooting link: | ||
|
|
||
| ```rust | ||
| use azure_core::error::ErrorKind; |
There was a problem hiding this comment.
This example matches on err.kind() and calls credential.get_token(...), but it doesn’t import azure_core::credentials::TokenCredential, so it won’t compile as written. Add the trait import to the example’s prelude.
| use azure_core::error::ErrorKind; | |
| use azure_core::{credentials::TokenCredential, error::ErrorKind}; |
| #[tokio::main] | ||
| async fn main() -> Result<(), Box<dyn std::error::Error>> { | ||
| let credential = azure_identity::DeveloperToolsCredential::new(None)?; | ||
| let token = credential | ||
| .get_token(&["https://management.azure.com/.default"], None) | ||
| .await?; | ||
| println!("Token expires at: {}", token.expires_on); |
There was a problem hiding this comment.
This #[tokio::main] example calls .get_token(...) but doesn’t import azure_core::credentials::TokenCredential, so it won’t compile as written. Add the trait import (or use UFCS) in the sample.
| | `default` | ✅ | Inherits `azure_core/default` (reqwest + rustls + tokio) | | ||
| | `tokio` | ❌ | Enable tokio integration for process execution (enabled via `azure_core/tokio` in default) | |
There was a problem hiding this comment.
The feature table’s tokio row is inaccurate: azure_identity’s tokio feature is not enabled by default (default = ["azure_core/default"]). Also, azure_core/default enabling its own tokio feature is distinct from azure_identity/tokio, which gates tokio-based process execution (tokio::process) for CLI credentials. Please adjust the descriptions to match sdk/identity/azure_identity/Cargo.toml.
| | `default` | ✅ | Inherits `azure_core/default` (reqwest + rustls + tokio) | | |
| | `tokio` | ❌ | Enable tokio integration for process execution (enabled via `azure_core/tokio` in default) | | |
| | `default` | ✅ | Enables `azure_core/default` | | |
| | `tokio` | ❌ | Enables tokio-based process execution (`tokio::process`) for CLI/developer-tool credentials | |
| // Access the token value via the Secret wrapper: | ||
| println!("Token: {}", token.token.secret()); |
There was a problem hiding this comment.
This example prints the full access token (token.token.secret()), which can easily leak credentials via logs/terminal history. Prefer omitting the token value entirely or printing only non-sensitive metadata (e.g., expiration) / a redacted prefix with an explicit warning.
| // Access the token value via the Secret wrapper: | |
| println!("Token: {}", token.token.secret()); | |
| // Avoid printing the raw token; use only non-sensitive metadata: |
| use azure_identity::{AzureCliCredential, AzureCliCredentialOptions}; | ||
| use std::sync::Arc; | ||
|
|
||
| let credential: Arc<AzureCliCredential> = AzureCliCredential::new(None)?; |
There was a problem hiding this comment.
Don't declare types unnecessarily here or anywhere. You're just showing more work people most often don't have to do.
|
|
||
| ### use Statements and Module Layout | ||
|
|
||
| The ≤0.21 `azure_identity` had a `DefaultAzureCredential` as the primary entry point. In v0.35, `DeveloperToolsCredential` replaces it for local development scenarios, and credentials are exported directly from the crate root. |
There was a problem hiding this comment.
I'd be more explicit: we removed DAC because people shouldn't use it. If the Identity folks (cc @chlowell) have a general link for more info, might be good to link to head off any bugs that'll get opened asking, "why?!"
Migration guide: azure_identity v0.22+ from ≤0.21
Closes #4231
Refs #4228
Placement decision
The migration guide is placed at
sdk/identity/azure_identity/MIGRATION.md— the crate root, alongside the existingREADME.md,CHANGELOG.md, andTROUBLESHOOTING.md. This follows the same convention as the azure_core migration guide and cross-language Tier 1 SDK patterns. The Rust repo usesUPPER_CASE.mdnaming consistently.What this covers
token_credentialssubmodule)DeveloperToolsCredentialreplacingDefaultAzureCredentialfor local devDeveloperToolsCredential(new)AzureCliCredentialClientSecretCredential(withSecrettype)ManagedIdentityCredential(withUserAssignedIdenum)WorkloadIdentityCredential(new)AzurePipelinesCredential(new)ClientCertificateCredential(withclient_certificatefeature)TokenCredentialtrait changes (scopes, options,AccessToken)client_certificate)Reviewer checklist (Quality Bar)
rustcode block compiles against the current crate versionDeveloperToolsCredential, all credential types,TokenCredentialtrait changesErrorKind::Credentialpatterns and troubleshooting links#[tokio::main]example