Skip to content

Demo: resource-first configuration and Blob Storage via the TokenCredential adapter - #11

Open
neotrow wants to merge 3 commits into
feat/workload-identityfrom
feat/workload-identity-demo
Open

neotrow wants to merge 3 commits into
feat/workload-identityfrom
feat/workload-identity-demo

Conversation

@neotrow

@neotrow neotrow commented Sep 18, 2026

Copy link
Copy Markdown

Summary

The Demo on the generalised library — the Blob Storage half of #2, done properly.

  • appsettings.json uses the resource-first Csag.WorkloadIdentity shape: AzureSql over the Google provider (the Demo deploys to Cloud Run) with empty placeholders, BlobStorage as an optional example, and a BlobStorageTestFile section (Endpoint, FilePath as container/blob).
  • Blob Storage: BlobServiceClient is built on the library's WorkloadIdentityTokenCredential over IBlobStorageTokenProvider — no hand-rolled DelegateTokenCredential with a faked 55-minute expiry as in Generalize project and rename it to Neolution.WorkloadIdentity #2. The blob pieces register only when both BlobStorage and the test file are configured; otherwise /test returns the SQL rows with blobSkipped: true, so the container smoke test with placeholder settings keeps working.
  • Azure.Storage.Blobs 12.29.2 added (Demo only, via central package management).
  • CI Docker job: placeholder env vars follow the new keys (Csag.WorkloadIdentity__AzureSql__Provider=Google, …__AzureSql__Google__TenantId, __ClientId, __ServiceAccountEmail).
  • Demo README rewritten for the resource-first configuration: Google on Cloud Run as the main path, a short Managed Identity variant for Azure-hosted runs, the exact keys, the optional blob test file, docker commands.
  • Empty changeset (package unchanged).

Stacked on the library PR.

Validation

Proven on Docker 29.x from the repo root: docker build -f Csag.WorkloadIdentity.Demo/Dockerfile -t csag-demo . ✅; container started with the placeholder env vars, GET / returns the greeting ✅, runs unprivileged (id -u ≠ 0) ✅; /test without Blob configuration takes the blobSkipped path ✅. dotnet build / dotnet test green in the worktree. 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

One or more issues must be addressed before approval.

Get a fresh assessment by requesting another Copilot review.

Pull request overview

Adds optional Azure Blob Storage support to the Demo using the resource-first workload identity configuration and WorkloadIdentityTokenCredential.

Changes:

  • Adds Blob Storage client/service registration and blob download response fields.
  • Updates configuration, documentation, CI placeholders, and package dependencies.
  • Adds optional Blob Storage test-file settings.
File summaries
File Description
README.md Updated as part of this pull request.
Directory.Packages.props Updated as part of this pull request.
Csag.WorkloadIdentity.Demo/Services/IBlobStorageService.cs Updated as part of this pull request.
Csag.WorkloadIdentity.Demo/Services/BlobStorageService.cs Updated as part of this pull request.
Csag.WorkloadIdentity.Demo/README.md Updated as part of this pull request.
Csag.WorkloadIdentity.Demo/Program.cs Updated as part of this pull request.
Csag.WorkloadIdentity.Demo/packages.lock.json Updated as part of this pull request.
Csag.WorkloadIdentity.Demo/Extensions/BlobStorageExtensions.cs Updated as part of this pull request.
Csag.WorkloadIdentity.Demo/Csag.WorkloadIdentity.Demo.csproj Updated as part of this pull request.
Csag.WorkloadIdentity.Demo/appsettings.json Updated as part of this pull request.
.github/workflows/ci.yml Updated as part of this pull request.
.changeset/workload-identity-demo.md Updated as part of this pull request.
Review details
  • Files reviewed: 12/12 changed files
  • Comments generated: 2
  • 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.Demo/Program.cs
Comment thread Csag.WorkloadIdentity.Demo/README.md
@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 feat/workload-identity-demo branch from fbb9931 to 55c7e90 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.

🔵 Needs a closer look

Three moderate issues remain in optional Blob registration, /test dependency handling, and the documented JSON configuration.

Review details

Suppressed comments (3)

Csag.WorkloadIdentity.Demo/Extensions/BlobStorageExtensions.cs:19

  • This condition only skips the Demo's BlobServiceClient; AddWorkloadIdentity has already registered the library's background refresh service, which refreshes every configured resource. When BlobStorage is present but either test-file setting is missing, /test is skipped but the app still resolves IBlobStorageTokenProvider and performs Blob token exchanges (and retries/logs failures) unnecessarily. Gate the Blob resource/background refresh as well, or require that the resource is not configured unless the test file is complete.
            if (!resourceSection.Exists() || string.IsNullOrWhiteSpace(endpoint) || string.IsNullOrWhiteSpace(filePath))

Csag.WorkloadIdentity.Demo/Program.cs:21

  • [FromServices] is resolved by Minimal APIs through the DI service lookup, and nullable reference type annotations do not make an unregistered service optional. When Blob Storage is not configured, this registration is skipped, so /test fails while binding the handler with a missing IBlobStorageService instead of entering the body and returning blobSkipped: true. Inject IServiceProvider (or register an explicit no-op service) and call GetService<IBlobStorageService>() inside the handler.
app.MapGet("/test", async ([FromServices] IAppDbContextFactory dbFactory, [FromServices] IBlobStorageService? blobService, [FromServices] ILogger<Program> logger, CancellationToken cancellationToken) =>

Csag.WorkloadIdentity.Demo/appsettings.json:19

  • Uncommenting the BlobStorage example as the Demo README instructs produces invalid JSON because the existing AzureSql property has no trailing comma before this block. Add the comma to the AzureSql closing line so the documented opt-in configuration can actually be enabled.
    // Optional. Together with "BlobStorageTestFile" below, this makes /test also download a blob.
    // "BlobStorage": {
  • Files reviewed: 12/12 changed files
  • Comments generated: 0 new
  • Review effort level: Lite

Copilot AI review requested due to automatic review settings September 18, 2026 16:37
@neotrow
neotrow force-pushed the feat/workload-identity-demo branch from 55c7e90 to 5ceaa85 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.

🟢 Approval recommended

Only a minor configuration-example comma nit was identified; no blocking issues remain.

Review details
  • Files reviewed: 14/14 changed files
  • Comments generated: 1
  • Review effort level: Lite

Comment thread Csag.WorkloadIdentity.Demo/appsettings.json Outdated
Copilot AI review requested due to automatic review settings September 18, 2026 17:03
@neotrow
neotrow force-pushed the feat/workload-identity-demo branch from 5ceaa85 to d9ce29d 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.

🔵 Needs a closer look

Two moderate unresolved findings require validation and dependency-release clarification.

Review details

Suppressed comments (2)

Csag.WorkloadIdentity.Demo/Extensions/BlobStorageExtensions.cs:19

  • This gate only checks for non-empty strings, so malformed Endpoint or FilePath values are accepted and validation is deferred to the BlobServiceClient/BlobStorageService factories. Those services are resolved during minimal-API parameter binding, before the handler's try block, so /test fails outside the documented Results.Problem() response and application log. Validate the URI and <container>/<blob> shape here (or via startup options validation) before registering the services.
            var endpoint = configuration["BlobStorageTestFile:Endpoint"];
            var filePath = configuration["BlobStorageTestFile:FilePath"];
            if (!resourceSection.Exists() || string.IsNullOrWhiteSpace(endpoint) || string.IsNullOrWhiteSpace(filePath))

Directory.Packages.props:14

  • This is not a Demo-only dependency change: Azure.Core is a direct reference of Csag.WorkloadIdentity.csproj, and this bump changes the library lockfile/package dependency from 1.53.0 to 1.62.0. That materially affects NuGet consumers while the PR description says the package is unchanged and uses an empty changeset; either keep the library's dependency unchanged (while satisfying the Blob SDK separately) or add the appropriate package release/change rationale.
    <PackageVersion Include="Azure.Core" Version="1.62.0" />
  • Files reviewed: 14/14 changed files
  • Comments generated: 0 new
  • Review effort level: Lite

neotrow and others added 3 commits September 18, 2026 14:27
… file

- appsettings.json uses the Csag.WorkloadIdentity resource shape: AzureSql over
  the Google provider with empty placeholders, BlobStorage as a commented
  example, and a BlobStorageTestFile section (Endpoint, FilePath).
- The BlobServiceClient is built on the library's WorkloadIdentityTokenCredential
  over IBlobStorageTokenProvider; BlobStorageService downloads
  <container>/<blob>. Both are registered only when the BlobStorage resource and
  the test file are configured, so /test returns the SQL rows with
  blobSkipped=true otherwise and the placeholder container smoke test still works.
- Azure.Storage.Blobs 12.29.2 added for the Demo through central package
  management; the Demo lock file is updated.
- The CI docker smoke test passes Csag.WorkloadIdentity__AzureSql__Provider=Google.
- The Demo README covers Google on Cloud Run, the managed identity variant for
  Azure hosts, the exact configuration keys, the optional blob test and the
  docker commands.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
…s requires

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
…ed; run the local container as the host user

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 feat/workload-identity-demo branch from d9ce29d to f3dd5ed 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.

🟢 Approval recommended

No unresolved review issues were identified.

Review details
  • Files reviewed: 14/14 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