Skip to content

{Profile} az login: Support automatic OIDC federated token refresh - #33989

Draft
MaddyMicrosoft wants to merge 5 commits into
Azure:devfrom
MaddyMicrosoft:feature/oidc-token-refresh
Draft

{Profile} az login: Support automatic OIDC federated token refresh#33989
MaddyMicrosoft wants to merge 5 commits into
Azure:devfrom
MaddyMicrosoft:feature/oidc-token-refresh

Conversation

@MaddyMicrosoft

@MaddyMicrosoft MaddyMicrosoft commented Aug 26, 2026

Copy link
Copy Markdown
Member

🤖 PR Validation — ⚠️ Review suggested

Breaking Changes Tests
⚠️ None ️✔️ 130/130
⚠️AzureCLI-BreakingChangeTest
⚠️profile
rule cmd_name rule_message suggest_message
⚠️ 1006 - ParaAdd login cmd login added parameter federated_identity
⚠️ 1006 - ParaAdd login cmd login added parameter federated_token_callback

Related command

az login

Description

Service-principal login with an OIDC federated token currently accepts only a static
token via --federated-token. That token expires in ~5–10 minutes and cannot be refreshed,
so long-running CI/CD tasks fail with AADSTS700024: Client assertion is not within its valid time range

This adds automatic, on-demand refresh by registering a callable client_assertion with
MSAL (the documented, recommended interface). When the access token expires and a new one is
needed, MSAL invokes the callback to fetch a fresh ID token — including in later az processes.

Three ways to supply the assertion (mutually exclusive with each other and with
--password/--certificate):

  • --federated-token <token> — static token (existing behavior, unchanged).
  • --federated-identity — auto-detects the CI/CD provider and refreshes the token itself.
    Supports GitHub Actions and Azure DevOps.
  • --federated-token-callback <command> (alias --federated-token-cmd) — provider-agnostic:
    runs a user-supplied command that prints a fresh token to stdout. Runs without a shell for safety.

Testing Guide

  • Unit tests in test_identity.py cover sentinel→callable resolution, GitHub and Azure DevOps
    token fetch (success + error paths), the no-shell callback behavior, and usage validation.
  • Manual: run az login --service-principal -u <id> -t <tenant> --federated-identity in a
    GitHub Actions (with id-token: write) or Azure DevOps (with System.AccessToken mapped)
    job and confirm a >10-minute task no longer fails with AADSTS700024.

History Notes

[Component Name 1] BREAKING CHANGE: az command a: Make some customer-facing breaking change
[Component Name 2] az command b: Add some customer-facing feature


This checklist is used to make sure that common guidelines for a pull request are followed.

MaddyMicrosoft and others added 3 commits August 25, 2026 08:23
… federated tokens

Static `--federated-token` values expire in ~10 minutes and cannot be refreshed,
so long-running CI/CD tasks fail with `AADSTS700024: Client assertion is not
within its valid time range`.

This registers a callable client_assertion with MSAL (the documented, recommended
interface) so an expired OIDC ID token is transparently re-fetched on every token
acquisition, including in later `az` processes. Wiring:

- New `FEDERATED_IDENTITY` sentinel persisted as the SP entry's client_assertion.
- `ServicePrincipalAuth.get_msal_client_credential()` resolves that sentinel to a
  provider dispatcher, `get_federated_id_token()`, instead of a static string.
- Dispatcher implements GitHub Actions; other environments raise a clear error
  pointing at `--federated-token`. Azure DevOps is a planned follow-up (Azure#28708).
- New `az login --federated-identity` flag, mutually exclusive with
  `--federated-token` and only valid with `--service-principal`.

Adds unit tests covering the sentinel-to-callable resolution, the GitHub fetch
(success and HTTP error), and the unsupported/no-provider branches.

Partially addresses Azure#28708

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…token refresh

Extends `--federated-identity` (GitHub Actions only) to also refresh OIDC federated
tokens on Azure DevOps Pipelines, so long-running pipeline tasks no longer fail with
`AADSTS700024`.

The provider dispatcher now detects Azure DevOps and POSTs to the pipeline oidctoken
API, following the documented Azure DevOps / azure-identity `AzurePipelinesCredential`
contract. Because the refresh runs in a later `az` process, the three required inputs
are read from the environment:

- request URL:  ARM_OIDC_REQUEST_URL, else SYSTEM_OIDCREQUESTURI
- access token: ARM_OIDC_REQUEST_TOKEN, else SYSTEM_ACCESSTOKEN (System.AccessToken)
- service conn: ARM_OIDC_AZURE_SERVICE_CONNECTION_ID

Missing variables produce a clear, actionable error. Adds unit tests for the Azure
DevOps success path, missing-environment handling, and updates the help text.

Partially addresses Azure#28708

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…oken refresh

Adds a provider-agnostic escape hatch alongside the built-in `--federated-identity`
providers. `--federated-token-callback <command>` takes any command that prints a
fresh OIDC token to stdout; Azure CLI wraps it as the MSAL client_assertion callable
and re-runs it on demand, so token refresh works with any CI/CD system (not just the
built-in GitHub Actions / Azure DevOps providers) without platform-specific logic in
the CLI.

- The command is persisted (client_assertion_callback) so later `az` processes rebuild
  the callable and refresh independently.
- Mutually exclusive with --federated-token and --federated-identity; service principal
  only. Clear errors on non-zero exit or empty output. The token value is never logged.

The three flags now cover the full spectrum: static token (--federated-token),
built-in providers (--federated-identity), and universal callback
(--federated-token-callback).

Partially addresses Azure#28708

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot AI lite review requested due to automatic review settings August 26, 2026 01:28
@MaddyMicrosoft
MaddyMicrosoft requested a review from a team as a code owner August 26, 2026 01:28

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

This PR extends Azure CLI service-principal login to support automatically refreshing OIDC federated tokens, avoiding long-running job failures due to expired assertions. It does so by introducing a provider-detected refresh mode (--federated-identity) and a generic “run a command to fetch a fresh token” mode (--federated-token-callback) that can be persisted and re-used by later az processes.

Changes:

  • Adds --federated-identity and --federated-token-callback arguments to az login and wires them into SP credential construction.
  • Introduces a persisted sentinel (FEDERATED_IDENTITY) and refresh callbacks in ServicePrincipalAuth.get_msal_client_credential().
  • Adds unit tests covering sentinel persistence, callback wrapping, and CI-provider token retrieval.

Reviewed changes

Copilot reviewed 4 out of 4 changed files in this pull request and generated 5 comments.

File Description
src/azure-cli/azure/cli/command_modules/profile/custom.py Adds new az login parameters and validation; passes new federated options into SP credential creation.
src/azure-cli/azure/cli/command_modules/profile/init.py Exposes new CLI arguments (--federated-identity, --federated-token-callback) and help text.
src/azure-cli-core/azure/cli/core/auth/identity.py Implements provider-detected token refresh, a persisted sentinel, and a command-based assertion callback path.
src/azure-cli-core/azure/cli/core/auth/tests/test_identity.py Adds unit tests for federated identity sentinel behavior, callback behavior, and provider detection flows.

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment thread src/azure-cli-core/azure/cli/core/auth/identity.py Outdated
Comment thread src/azure-cli-core/azure/cli/core/auth/identity.py
Comment thread src/azure-cli/azure/cli/command_modules/profile/custom.py Outdated
Comment thread src/azure-cli/azure/cli/command_modules/profile/custom.py
Comment thread src/azure-cli/azure/cli/command_modules/profile/__init__.py Outdated
@MaddyMicrosoft
MaddyMicrosoft marked this pull request as draft August 26, 2026 01:55
MaddyMicrosoft and others added 2 commits August 26, 2026 04:52
- Harden --federated-token-callback: parse the command into an argv list and run it
  without a shell (shell=False), so a tampered token cache cannot become arbitrary
  code execution. Users needing pipes/redirection use a script or wrap in bash -c.
- Reject combining --federated-token/--federated-identity/--federated-token-callback
  with --password or --certificate (previously the secret silently won and refresh
  was silently disabled).
- Fix the GitHub OIDC request URL to append the audience with the correct separator
  when the URL has no existing query string.
- Correct the misleading --service-principal usage error to list all credential modes.
- Align --federated-identity help text with the actual mutual-exclusion validation.
- Add tests for the no-shell argv behavior and the query-less GitHub URL case.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…on-length linter

The --federated-token-callback option (26 chars) exceeds azure-cli's 22-char
option-length threshold, so add the shorter --federated-token-cmd alias.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@yonzhan

Copy link
Copy Markdown
Collaborator

Feature/OIDC token refresh

@MaddyMicrosoft MaddyMicrosoft removed this from the October 2026 (2026-10-06) milestone Aug 26, 2026
@MaddyMicrosoft MaddyMicrosoft changed the title Feature/OIDC token refresh {Profile} az login: Support automatic OIDC federated token refresh Aug 26, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants