Skip to content

Document the generalised library: quickstarts, options reference, migration, setup guide - #12

Open
neotrow wants to merge 6 commits into
feat/workload-identity-demofrom
docs/workload-identity
Open

neotrow wants to merge 6 commits into
feat/workload-identity-demofrom
docs/workload-identity

Conversation

@neotrow

@neotrow neotrow commented Sep 18, 2026

Copy link
Copy Markdown

Summary

Documentation for the generalised Csag.WorkloadIdentity library.

  • Package README (ships in the nupkg, absolute links only): the resource-first model; quickstart A — Azure SQL from Google Cloud Run (Provider: Google) end to end, SqlConnection.AccessToken and the EF Core factory; quickstart B — Azure SQL + Blob Storage from Azure App Service (Provider: ManagedIdentity, system- and user-assigned), BlobServiceClient on WorkloadIdentityTokenCredential; a full options reference for both providers plus RefreshAheadWindow / EnableBackgroundRefresh; a migration section from Csag.AzureSqlFederatedIdentity / Neolution.AzureSqlFederatedIdentity with before/after JSON and the AddWorkloadIdentity rename; notes on credential-free connection strings, ADC and the service-account identity, and what the background refresh actually does.
  • docs/cloud-identity-setup.md restructured as "choose your identity configuration": (A) Azure Managed Identity (enable system/user-assigned, CREATE USER … FROM EXTERNAL PROVIDER, Blob RBAC roles) — from Generalize project and rename it to Neolution.WorkloadIdentity #2's IDENTITY-SETUP.md; (B) Google Cloud → Azure federation, keeping the verified least-privilege content (roles/iam.serviceAccountOpenIdTokenCreator bound on the service account, iamcredentials.googleapis.com enabled, audience api://AzureADTokenExchange) and covering both holders of the federated credential — an app registration or a user-assigned managed identity — since GoogleOptions.ClientId accepts either; resource grants; "Configure the application" with the new keys; Generalize project and rename it to Neolution.WorkloadIdentity #2's "disable SQL authentication" hardening section. Microsoft Entra ID naming throughout.
  • Root README updated for the new name and model.
  • Changeset: patch (the README is part of the package).

Stacked on the Demo PR (it links the Demo README).

Validation

Every sample checked against the actual members, overloads and keys on the branch; every relative link resolves on the rebased head; absolute URLs return 200 except the nuget.org page of the not-yet-published package ID. Vendor facts re-checked. Adversarially verified.

🤖 Generated with Claude Code

Copilot AI lite review requested due to automatic review settings September 18, 2026 02:44

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🟡 Changes recommended

Documentation corrections remain for token caching, resource-specific credentials, configuration validation, role assignment, and provider-specific deployment behavior.

Get a fresh assessment by requesting another Copilot review.

Pull request overview

Documents the generalized Csag.WorkloadIdentity library for Azure SQL, Blob Storage, managed identities, and Google federation.

Changes:

  • Adds package quickstarts, options reference, and migration guidance.
  • Restructures cloud identity setup documentation.
  • Updates root and security documentation.
  • Adds a patch changeset.
File summaries
File Description
SECURITY.md Updates supported credential and resource descriptions.
README.md Refreshes project overview and quick-start guidance.
docs/cloud-identity-setup.md Adds identity, resource grant, configuration, and deployment instructions.
Csag.WorkloadIdentity/README.md Adds quickstarts, API/options reference, and migration guidance.
.changeset/workload-identity-docs.md Records the documentation patch release.
Review details

Suppressed comments (2)

Csag.WorkloadIdentity/README.md:224

  • The Azure SDK does not request a token from TokenCredential on every request; its bearer-token policy caches the returned AccessToken until it needs renewal. Please avoid implying a per-request credential call, since the adapter/provider refresh behavior and request latency are described incorrectly here.
Azure SQL works exactly as in quickstart A: `IAzureSqlTokenProvider` and `SqlConnection.AccessToken`, with plain ADO.NET or the EF Core factory. For Blob Storage inject the `BlobServiceClient`; the SDK asks the credential for a token on every request and the adapter answers from the held token:

docs/cloud-identity-setup.md:237

  • This role-assignment procedure does not cover the user-assigned managed identity used as the federated-credential holder in section B.2.2. Such an identity must be selected under Managed identity (using its principal), not only via the app-registration/service-principal path described here; otherwise the documented Google-federation Blob setup cannot grant the required data role.
1. In the Azure portal open the storage account (or the container) and go to **Access control (IAM)** > **Add** > **Add role assignment**.
2. Select the role. On the **Members** tab choose **Managed identity** and pick the identity (a system-assigned identity is listed under its resource type, for example App Service), or choose **User, group, or service principal** and search for the app registration by name.
  • Files reviewed: 5/5 changed files
  • Comments generated: 3
  • Review effort level: Lite

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

Comment thread Csag.WorkloadIdentity/README.md Outdated
Comment thread docs/cloud-identity-setup.md Outdated
Comment thread docs/cloud-identity-setup.md Outdated
@neotrow
neotrow added this pull request to stack #13 September 18, 2026 15:30
Copilot AI review requested due to automatic review settings September 18, 2026 16:02
@neotrow
neotrow force-pushed the docs/workload-identity branch from 6c2786d to 0f2a88d Compare September 18, 2026 16:02

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🟡 Changes recommended

Address the critical SQL cleanup guidance and the two moderate documentation inaccuracies.

Get a fresh assessment by requesting another Copilot review.

Review details

Suppressed comments (2)

Csag.WorkloadIdentity/README.md:297

  • AddWorkloadIdentity is not harmless when called more than once: RegisterWorkloadIdentityServices uses AddHostedService<TokenRefreshService>() (not a TryAdd), so each call registers another hosted refresh loop and can duplicate token requests. Please remove this claim or document the single-registration requirement until the registration code is made idempotent.
The options are validated when the host starts: no resource section at all, a missing value in a configured resource's provider section, or a non-positive `RefreshAheadWindow` throws an `OptionsValidationException` that names every offending value by its path, for example `AzureSql:Google:ServiceAccountEmail must be provided.` A `Provider` value other than `ManagedIdentity` or `Google` fails earlier, when the configuration is bound. Calling `AddWorkloadIdentity` more than once is harmless. Both token providers are always registered; resolving the provider of a resource whose section is absent throws an `InvalidOperationException` that names the missing section.

docs/cloud-identity-setup.md:290

  • This migration instruction produces the wrong JSON shape if followed literally: the existing resource must still contain a ManagedIdentity property, with ClientId inside it. As written, replacing the section with { "ClientId": ... } leaves AzureSql.ManagedIdentity absent and fails options validation. Clarify that the contents of the ManagedIdentity object are replaced, or show the full resource snippet.
For a user-assigned identity replace the `ManagedIdentity` section with `{ "ClientId": "<client-id>" }`. For the identity configuration B, with Azure SQL only:
  • Files reviewed: 5/5 changed files
  • Comments generated: 1
  • Review effort level: Lite

Comment thread docs/cloud-identity-setup.md Outdated
Copilot AI review requested due to automatic review settings September 18, 2026 16:37
@neotrow
neotrow force-pushed the docs/workload-identity branch from 0f2a88d to e78053d Compare September 18, 2026 16:37

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🔵 Needs a closer look

Remove or properly document the unsupported AKS Workload Identity guidance.

Review details

Suppressed comments (2)

Csag.WorkloadIdentity/README.md:154

  • This quickstart also lists AKS as a supported host, but the implementation constructs only ManagedIdentityCredential; AKS Workload Identity normally requires WorkloadIdentityCredential and projected-token configuration. Please remove AKS here unless the library is extended/configured for that credential flow.
An application on App Service (or Container Apps, Functions, a virtual machine, AKS) has a managed identity, so both tokens come from the `ManagedIdentity` provider. Blob Storage is reached through the Azure SDK, with `WorkloadIdentityTokenCredential` adapting the library's provider to the `TokenCredential` the SDK expects.

Csag.WorkloadIdentity/README.md:10

  • ManagedIdentityCredential is the only credential this library creates, but standard AKS Workload Identity uses a projected Kubernetes service-account token with WorkloadIdentityCredential, not the managed-identity endpoint selected here. As written, this makes AKS look supported by this provider when the quickstart supplies no required AKS federation setup; please remove AKS from this list or document a supported AKS configuration separately.
- **`ManagedIdentity`.** The library requests the token from the managed identity endpoint of the Azure resource the application runs on (App Service, Container Apps, Functions, a virtual machine, AKS and so on), as the system-assigned identity of that resource or as a user-assigned identity selected by its client ID.
  • Files reviewed: 5/5 changed files
  • Comments generated: 0 new
  • Review effort level: Lite

Copilot AI review requested due to automatic review settings September 18, 2026 17:03
@neotrow
neotrow force-pushed the docs/workload-identity branch from e78053d to 66b65e1 Compare September 18, 2026 17:03

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🟢 Approval recommended

The documentation changes have been reviewed and no blocking issues remain.

Review details

Suppressed comments (1)

docs/cloud-identity-setup.md:292

  • The replacement example omits the ManagedIdentity property name, so copying it into the preceding JSON would produce invalid configuration. Keep the resource property and replace only its value, e.g. "ManagedIdentity": { "ClientId": "<client-id>" }.
For a user-assigned identity replace the `ManagedIdentity` section with `{ "ClientId": "<client-id>" }`. For the identity configuration B, with Azure SQL only:
  • Files reviewed: 5/5 changed files
  • Comments generated: 1
  • Review effort level: Lite

Comment thread Csag.WorkloadIdentity/README.md Outdated
neotrow and others added 6 commits September 18, 2026 14:27
Package README: the resource-first model, two quickstarts (Azure SQL from Google Cloud Run over workload identity federation; Azure SQL and Blob Storage from Azure App Service with a system- or user-assigned managed identity, including a BlobServiceClient built on WorkloadIdentityTokenCredential), a reference of every option for both providers, and a migration section from Neolution.AzureSqlFederatedIdentity with the before/after configuration and the AddWorkloadIdentity rename. Every C# sample compiles against the library.

Setup guide: restructured as a choice between an Azure managed identity and Google Cloud to Azure federation, with both holders of the federated credential (app registration or user-assigned managed identity), the Azure SQL and Blob Storage grants, the new configuration keys, App Service and Cloud Run deployment, and Microsoft Entra-only authentication. Vendor facts and every URL verified.

Root README, SECURITY.md and a patch changeset follow the new name and model.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
An unrecognised Provider value is rejected by the configuration binder
before options validation runs, and AKS pods do not use the resource
Identity setting.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
…ll needs a resource section; runtime flow per provider

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
…ned password users automatically

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
… AccessTokenCallback for a single pool

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Copilot AI review requested due to automatic review settings September 18, 2026 17:27
@neotrow
neotrow force-pushed the docs/workload-identity branch from 66b65e1 to eddfae1 Compare September 18, 2026 17:27

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🔵 Needs a closer look

Fix the AKS support guidance and correct the AccessTokenCallback API example.

Review details

Suppressed comments (2)

Csag.WorkloadIdentity/README.md:154

  • This quickstart lists AKS as a supported host for ManagedIdentity, but the library constructs Azure.Identity.ManagedIdentityCredential, which requires an Azure managed-identity endpoint. Standard AKS workload identity exposes a projected token and is consumed with WorkloadIdentityCredential, not this credential, so users following this guide on AKS will fail to obtain a token. Remove AKS from this list (or document a separately supported AKS identity integration).
An application on App Service (or Container Apps, Functions, a virtual machine, AKS) has a managed identity, so both tokens come from the `ManagedIdentity` provider. Blob Storage is reached through the Azure SDK, with `WorkloadIdentityTokenCredential` adapting the library's provider to the `TokenCredential` the SDK expects.

Csag.WorkloadIdentity/README.md:347

  • The AccessTokenCallback example calls the wrong API shape: IAzureSqlTokenProvider exposes GetAzureSqlAccessTokenAsync, while GetAccessTokenAsync is inherited from IAccessTokenProvider and returns Task<Azure.Core.AccessToken>. Please reference the inherited method explicitly (and its Azure.Core.AccessToken result) so readers do not try to compile a nonexistent IAzureSqlTokenProvider.GetAccessTokenAsync overload.
- **Token handling.** The provider holds the token; do not cache or persist it yourself. `AccessToken` is part of the `SqlClient` connection pool key, so a refreshed token starts a new pool, which is expected. If your connection string sets `Min Pool Size` above zero, call `SqlConnection.ClearPool` with a connection that carries the old token once it has expired; otherwise the pool keeps that token's physical connections open indefinitely (see the [`AccessToken` remarks](https://learn.microsoft.com/en-us/dotnet/api/microsoft.data.sqlclient.sqlconnection.accesstoken)). Alternatively, set `SqlConnection.AccessTokenCallback` (Microsoft.Data.SqlClient 5.2 or later) to a delegate that returns `new SqlAuthenticationToken(token.Token, token.ExpiresOn)` from `IAzureSqlTokenProvider.GetAccessTokenAsync`: the callback keeps a single pool across token refreshes.
  • Files reviewed: 5/5 changed files
  • Comments generated: 0 new
  • Review effort level: Lite

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