Skip to content

docs(azure_identity): add migration guide#4240

Open
ronniegeraghty wants to merge 2 commits into
Azure:mainfrom
ronniegeraghty:migration-guide/azure-identity
Open

docs(azure_identity): add migration guide#4240
ronniegeraghty wants to merge 2 commits into
Azure:mainfrom
ronniegeraghty:migration-guide/azure-identity

Conversation

@ronniegeraghty
Copy link
Copy Markdown
Member

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 existing README.md, CHANGELOG.md, and TROUBLESHOOTING.md. This follows the same convention as the azure_core migration guide and cross-language Tier 1 SDK patterns. The Rust repo uses UPPER_CASE.md naming consistently.

What this covers

  • Cargo.toml version bump
  • Module restructuring (credentials at crate root, no more token_credentials submodule)
  • DeveloperToolsCredential replacing DefaultAzureCredential for local dev
  • Per-credential migration for all 7 credential types:
    • DeveloperToolsCredential (new)
    • AzureCliCredential
    • ClientSecretCredential (with Secret type)
    • ManagedIdentityCredential (with UserAssignedId enum)
    • WorkloadIdentityCredential (new)
    • AzurePipelinesCredential (new)
    • ClientCertificateCredential (with client_certificate feature)
  • TokenCredential trait changes (scopes, options, AccessToken)
  • Error handling with credential-specific messages and troubleshooting links
  • Feature flags (client_certificate)
  • Async/tokio requirement

Reviewer checklist (Quality Bar)

  • Compilable code samples — every rust code block compiles against the current crate version
  • Side-by-side before/after — every common operation shows old code and new code
  • Cargo.toml diff — includes a clear diff showing old → new dependency lines
  • Authentication migration — covers DeveloperToolsCredential, all credential types, TokenCredential trait changes
  • Error handling section — documents ErrorKind::Credential patterns and troubleshooting links
  • API docs link — links to docs.rs/azure_identity
  • Examples directory link — links to in-repo examples/
  • Feature flags table — lists all Cargo features with descriptions
  • Async runtime callout — states tokio requirement with #[tokio::main] example
  • No dead links — all links resolve

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>
@ronniegeraghty
Copy link
Copy Markdown
Member Author

Fixed an authoring error in the Cargo.toml diff blocks: marker characters had been doubled (`--`/`++`/`-+`/`+-`), which doesn't render as a real diff. Inside a diff fenced block the first column is the diff marker, so single -/+ is correct. The blocks now render as a clean removed/added pair.

@ronniegeraghty ronniegeraghty changed the title docs(azure_identity): add migration guide for v0.22+ GA release docs(azure_identity): add migration guide Apr 21, 2026
@ronniegeraghty ronniegeraghty marked this pull request as ready for review April 21, 2026 20:16
@ronniegeraghty ronniegeraghty requested a review from heaths as a code owner April 21, 2026 20:16
Copilot AI review requested due to automatic review settings April 21, 2026 20:16
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

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.md covering dependency updates, module layout changes, and new credential types.
  • Documents updated TokenCredential trait usage (scopes/options/AccessToken) and error-handling patterns.
  • Adds guidance for async runtime usage and Cargo feature flags (including client_certificate).

Comment on lines +140 to +145
use azure_identity::DeveloperToolsCredential;

let credential = DeveloperToolsCredential::new(None)?;
let token = credential
.get_token(&["https://management.azure.com/.default"], None)
.await?;
Copy link

Copilot AI Apr 21, 2026

Choose a reason for hiding this comment

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

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.

Copilot uses AI. Check for mistakes.
Comment on lines +157 to +162
use azure_identity::{AzureCliCredential, AzureCliCredentialOptions};

let credential = AzureCliCredential::new(None)?;
let token = credential
.get_token(&["https://management.azure.com/.default"], None)
.await?;
Copy link

Copilot AI Apr 21, 2026

Choose a reason for hiding this comment

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

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).

Copilot uses AI. Check for mistakes.
Comment on lines +183 to +195
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?;
Copy link

Copilot AI Apr 21, 2026

Choose a reason for hiding this comment

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

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).

Copilot uses AI. Check for mistakes.
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;
Copy link

Copilot AI Apr 21, 2026

Choose a reason for hiding this comment

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

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.

Suggested change
use azure_core::error::ErrorKind;
use azure_core::{credentials::TokenCredential, error::ErrorKind};

Copilot uses AI. Check for mistakes.
Comment on lines +366 to +372
#[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);
Copy link

Copilot AI Apr 21, 2026

Choose a reason for hiding this comment

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

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.

Copilot uses AI. Check for mistakes.
Comment on lines +397 to +398
| `default` | ✅ | Inherits `azure_core/default` (reqwest + rustls + tokio) |
| `tokio` | ❌ | Enable tokio integration for process execution (enabled via `azure_core/tokio` in default) |
Copy link

Copilot AI Apr 21, 2026

Choose a reason for hiding this comment

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

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.

Suggested change
| `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 |

Copilot uses AI. Check for mistakes.
Comment on lines +95 to +96
// Access the token value via the Secret wrapper:
println!("Token: {}", token.token.secret());
Copy link

Copilot AI Apr 21, 2026

Choose a reason for hiding this comment

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

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.

Suggested change
// Access the token value via the Secret wrapper:
println!("Token: {}", token.token.secret());
// Avoid printing the raw token; use only non-sensitive metadata:

Copilot uses AI. Check for mistakes.
Copy link
Copy Markdown
Member

@heaths heaths left a comment

Choose a reason for hiding this comment

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

A few specific comments, but also everything else I said in #4239 about making sure these are compiled, not declaring variable types unnecessarily e.g., let foo: Foo = Foo::new() - just let foo = Foo::new() - etc.

use azure_identity::{AzureCliCredential, AzureCliCredentialOptions};
use std::sync::Arc;

let credential: Arc<AzureCliCredential> = AzureCliCredential::new(None)?;
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

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.
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

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?!"

@github-project-automation github-project-automation Bot moved this from Untriaged to In Progress in Azure Identity SDK Improvements Apr 21, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Azure.Identity The azure_identity crate

Projects

Status: In Progress

Development

Successfully merging this pull request may close these issues.

Migration guide: azure_identity (from azure_identity ≤0.21.0 / azure_sdk_auth_aad)

3 participants