Skip to content

Support configurable scheduler token audiences and government defaults - #806

Open
Bernd Verst (berndverst) wants to merge 1 commit into
mainfrom
configurable-token-audience
Open

Bernd Verst (berndverst) wants to merge 1 commit into
mainfrom
configurable-token-audience

Conversation

@berndverst

@berndverst Bernd Verst (berndverst) commented Sep 26, 2026 •

Copy link
Copy Markdown
Member

Summary

What changed?

  • Extend the existing DurableTaskSchedulerClientOptions.ResourceId and DurableTaskSchedulerWorkerOptions.ResourceId properties with shared normalization and per-options-instance defaults. No constructor or overload signatures change.
  • Support case-insensitive ResourceId connection-string configuration for all authentication types, including forwarding through named client/worker builders. Preserve already-normalized values when copying options so meaningful repeated /.default URI segments are not stripped twice.
  • Select https://durabletask.azure.us for missing/null/empty audiences when REGION_NAME starts with usgov or usdod, case-insensitively; retain https://durabletask.io otherwise. Explicit audiences always win.
  • Keep audience, service endpoint, and credential authority independent. Add optional AuthorityHost connection-string forwarding for SDK-created credentials that support it; omission preserves Azure Identity's defaults and environment configuration. Managed identity and developer-tool cloud configuration remain separate.
  • Verify actual requested scopes through recording credentials and loopback gRPC calls, including expiry/RefreshOn, cached concurrent calls, DI overloads, channel recreation, sandbox declaration/removal, registration reconnects, anonymous authentication, and supplied call invokers.
  • Update public XML documentation, the government-cloud README example, sandbox guidance, changelog, and package release notes. No package or dependency versions change.

Why is this change needed?

Applications need explicit/custom audiences and predictable government-cloud defaults without silently changing endpoints or credential authority. Existing ResourceId options were not normalized or forwarded from connection strings.

Credential construction and authority-host rationale

The .NET SDK supports both caller-created credentials and SDK-created credentials. Credential construction from connection strings already existed before this PR; this PR does not introduce that ownership model.

Entry path Who constructs the credential? Authority responsibility
UseDurableTaskScheduler(endpointAddress, taskHubName, credential, ...) or setting options.Credential Caller Configure authority on the supplied credential. The SDK neither replaces it nor applies a per-request authority override.
UseDurableTaskScheduler(connectionString, ...) / DurableTaskSchedulerClientOptions.FromConnectionString(...) SDK, based on Authentication Optional AuthorityHost is passed into supported Azure Identity credential options before construction.
Worker connection-string equivalents SDK Same handling as the client.
UseSandboxWorker() SDK creates ManagedIdentityCredential Uses the hosting environment's identity endpoint; an Entra authority override does not apply.

Evidence at this PR's implementation commit:

Therefore the optional connection-string authority support is retained. No SDK authority property is added for caller-supplied credentials. Managed identity, Azure CLI, Azure PowerShell, and anonymous authentication do not receive this authority override; developer tools may need their own cloud configuration. Neither ResourceId nor REGION_NAME sets an authority or endpoint.

Issues / work items

Breaking Change

Type: behavioral
Impact: Applications with REGION_NAME beginning with usgov or usdod now default to the government token audience. Explicit audiences are normalized, and whitespace-only or empty-after-normalization values now throw actionable argument errors.
Migration: Set ResourceId=https://durabletask.io explicitly on both client and worker, or in their connection strings, to retain the prior audience in government regions. Correct invalid audience values. Configure the credential authority and endpoint separately when targeting a different cloud.

No binary or source breaking change: existing property and constructor signatures remain intact; the setter's nullability annotation is widened. Orchestration replay, serialization, protobuf fields, and token-cache implementation are unchanged.


Project checklist

  • Release notes are not required for the next release
    • Otherwise: Notes added to CHANGELOG.md and both AzureManaged RELEASENOTES.md files
  • Backport is not required
    • Otherwise: Backport tracked by issue/PR #issue_or_pr
  • All required tests have been added/updated (local unit and gRPC transport tests)
  • Breaking change?
    • If yes:
      • Impact: Government-region default and audience validation/normalization described above.
      • Migration guidance: Explicit public audience restores the former government-region behavior.

AI-assisted code disclosure (required)

Was an AI tool used? (select one)

  • No
  • Yes, AI helped write parts of this PR (e.g., GitHub Copilot)
  • Yes, an AI agent generated most of this PR

If AI was used:

  • Tool(s): GitHub Copilot App.
  • AI-assisted areas/files: Implementation, regression tests, public documentation, release notes, and this description.
  • What you changed after AI output: Agent iterated on compilation, tests, documentation example compilation, and government-environment regressions. Human review is pending.

AI verification (agent verification completed; human review pending):

  • I understand the code and can explain it
  • I verified referenced APIs/types exist and are correct
  • I reviewed edge cases/failure paths (timeouts, retries, cancellation, exceptions)
  • I reviewed concurrency/async behavior
  • I checked for unintended breaking or behavior changes

Testing

Automated tests

  • 358 AzureManaged tests passed: client 168, worker 164, shared 26. The full client/worker suites also passed with REGION_NAME=USGOVVIRGINIA (332 repeat executions).
  • 19 existing channel-recreation regressions passed: client 10, worker 9.
  • Release builds of Client.AzureManaged and Worker.AzureManaged passed for net6.0, net8.0, and net10.0, with existing repository analyzer/obsolete-API warnings. Sandbox packages compile with the net10.0 test projects.
  • Targeted dotnet format style --no-restore --verify-no-changes checks passed for changed authentication source and new tests; build-time .NET/StyleCop analyzers ran.
  • The whitespace formatter reports FINALNEWLINE: the existing .editorconfig requires insert_final_newline=false, while StyleCop requires a final newline. Existing final-newline conventions were retained rather than changing unrelated repository configuration. git diff --check passes with core.whitespace=cr-at-eol, preserving the changelog's existing CRLF format.
  • The government-cloud README example was compiled against the changed client and worker projects.

Manual validation (only if runtime/behavior changed)

  • Environment: Windows, .NET SDK 10.0.401.
  • Actual scope arguments are recorded at TokenCredential.GetTokenAsync; loopback gRPC servers exercise the configured client/worker channels and sandbox management/registration transports.
  • No live public-cloud or Azure Government authentication was performed. Recording-credential scope verification and example compilation do not establish live cloud service availability or validate tenant/identity permissions.

Notes for reviewers

  • The common audience matrix is compiled into both client and worker test projects to keep authentication-path coverage identical without duplicating test logic.
  • Previously environment-dependent assertions of an unconditional public default are replaced by the comprehensive recording-credential default matrix.
  • Sandbox transports already reuse scheduler channels; production sandbox changes are documentation only.
  • The token cache, refresh concurrency behavior, acquisition timing, and channel-recreation implementation were deliberately left unchanged.

Add ResourceId connection-string support and independent AuthorityHost forwarding. Preserve audience selection through DI, token refresh, and sandbox registration, with recording-credential regressions and government-cloud documentation.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Copilot AI lite review requested due to automatic review settings September 26, 2026 07:03
Comment on lines +85 to +86
{
}

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.

Note

Copilot was unable to run its full agentic suite in this review.

Copilot review overview

Review effort: Lite
Findings: 1 High severity · 1 Medium severity

Open (2)
What changed in this PR

This PR updates Azure Managed client/worker configuration to treat ResourceId as a normalized token audience with region-based defaults (including a behavior change for gov/DoD regions) and adds optional AuthorityHost support for SDK-created Azure Identity credentials, with expanded shared authentication test coverage and documentation.

Changes:

  • Normalize ResourceId token audience handling with per-options-instance defaults, plus explicit-copy behavior for channel recreation/reconnect scenarios.
  • Add AuthorityHost parsing to connection strings and flow it into Azure Identity credential options where applicable.
  • Add shared and sandbox authentication tests, and document the new behavior (README, release notes, changelog).
File Description
test/​Worker/​AzureManaged.Tests/​Worker.AzureManaged.Tests.csproj Includes shared auth test code and defines SCHEDULER_WORKER to compile worker-specific shared tests.
test/​Worker/​AzureManaged.Tests/​SandboxAuthenticationTests.cs Adds worker sandbox registration/auth reconnect tests validating audience + token cache behavior.
test/​Worker/​AzureManaged.Tests/​DurableTaskSchedulerWorkerOptionsTests.cs Updates tests for new default ResourceId behavior (no longer fixed to durabletask.io).
test/​Worker/​AzureManaged.Tests/​DurableTaskSchedulerWorkerExtensionsTests.cs Updates extension tests for new default ResourceId behavior.
test/​Shared/​AzureManaged/​SchedulerAuthenticationTests.cs Adds shared authentication tests (client/worker via #if) and a local gRPC test server & credential recorder.
test/​Shared/​AzureManaged.Tests/​DurableTaskSchedulerConnectionStringTests.cs Adds tests for AuthorityHost preservation/validation in connection string credential option creation.
test/​Client/​AzureManaged.Tests/​SandboxAuthenticationTests.cs Adds client sandbox management/auth tests validating audience + token cache behavior.
test/​Client/​AzureManaged.Tests/​DurableTaskSchedulerClientOptionsTests.cs Updates tests for new default ResourceId behavior.
test/​Client/​AzureManaged.Tests/​DurableTaskSchedulerClientExtensionsTests.cs Updates extension tests for new default ResourceId behavior.
test/​Client/​AzureManaged.Tests/​Client.AzureManaged.Tests.csproj Includes shared auth test code for the client test project.
src/​Worker/​AzureManaged/​RELEASENOTES.md Documents ResourceId normalization/default behavior change and AuthorityHost support.
src/​Worker/​AzureManaged/​DurableTaskSchedulerWorkerOptions.cs Implements per-instance default ResourceId, normalization, AuthorityHost credential options forwarding, and copy semantics.
src/​Worker/​AzureManaged/​DurableTaskSchedulerWorkerExtensions.cs Ensures ResourceId is copied from connection options when configuring via extensions.
src/​Worker/​AzureManaged.Sandboxes/​DurableTaskSchedulerSandboxWorkerExtensions.cs Documents shared audience behavior for worker + sandbox registration.
src/​Shared/​AzureManaged/​DurableTaskSchedulerResourceId.cs Adds shared default resolution + normalization for token audience URIs.
src/​Shared/​AzureManaged/​DurableTaskSchedulerConnectionString.cs Adds connection-string ResourceId property and AuthorityHost-aware credential options creation.
src/​Client/​AzureManaged/​RELEASENOTES.md Documents ResourceId normalization/default behavior change and AuthorityHost support.
src/​Client/​AzureManaged/​DurableTaskSchedulerClientOptions.cs Mirrors worker changes for client options (per-instance default, normalization, copy semantics, authority host forwarding).
src/​Client/​AzureManaged/​DurableTaskSchedulerClientExtensions.cs Ensures ResourceId is copied from connection options when configuring via extensions.
src/​Client/​AzureManaged.Sandboxes/​SandboxActivitiesClientServiceCollectionExtensions.cs Documents that sandbox management reuses the configured client channel/audience.
samples/​on-demand-sandbox/​README.md Adds guidance for gov cloud audience + authority configuration.
README.md Adds comprehensive documentation on token audiences, gov defaults, normalization, and AuthorityHost.
CHANGELOG.md Captures behavior change and new connection-string support.

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

@@ -1,6 +1,7 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License.

Comment on lines +326 to +333
public override ValueTask<AccessToken> GetTokenAsync(TokenRequestContext requestContext, CancellationToken cancellationToken)
{
this.scopes.Enqueue(Assert.Single(requestContext.Scopes));
return ValueTask.FromResult(new AccessToken(
"recorded-token",
expireFirstToken && this.scopes.Count == 1 ? DateTimeOffset.UtcNow.AddMinutes(-1) : DateTimeOffset.UtcNow.AddHours(1),
refreshFirstToken && this.scopes.Count == 1 ? DateTimeOffset.UtcNow.AddMinutes(-1) : null));
}
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.

2 participants