Skip to content

enhance: support Azure SPN credentials via ClientSecretCredential in IAM mode - #54582

Open
sarveshls wants to merge 12 commits into
milvus-io:masterfrom
sarveshls:pr/azure-spn-default-credential
Open

sarveshls wants to merge 12 commits into
milvus-io:masterfrom
sarveshls:pr/azure-spn-default-credential

Conversation

@sarveshls

@sarveshls sarveshls commented Oct 22, 2026 •

Copy link
Copy Markdown

What

When AZURE_CLIENT_SECRET is set, both the Go object storage client
(pkg/objectstorage/util.go) and the C++ chunk manager
(AzureBlobChunkManager.cpp) now build an explicit credential for SPN auth
instead of DefaultAzureCredential.

Why explicit credential instead of DefaultAzureCredential

DefaultAzureCredential builds a chain internally. If AZURE_CLIENT_ID
or AZURE_TENANT_ID are missing, EnvironmentCredential fails silently
inside the chain and DAC falls through to the next source (Workload Identity,
Managed Identity, Azure CLI). The result is that storage is accessed as
a different identity with no error at startup. Using ClientSecretCredential
(Go) / ClientSecretCredential (C++ Azure SDK) fails fast at construction
if any required variable is absent.

Credential selection order

Both Go and C++ now use WI → SPN → MI priority:

  1. AZURE_FEDERATED_TOKEN_FILE set → Workload Identity
  2. AZURE_CLIENT_SECRET set → explicit SPN credential (returns error if
    AZURE_TENANT_ID or AZURE_CLIENT_ID are missing)
  3. otherwise → Managed Identity

WI is checked before SPN so that pods with valid Workload Identity config
are not silently switched to SPN if a leftover or expired
AZURE_CLIENT_SECRET is present in the environment.

Repo PR
zilliztech/woodpecker Merged✅ #449
milvus-io/milvus-storage Merged✅ #742
zilliztech/milvus-operator Merged✅ #558

Dependency pin bumps ‼️

  • milvus-storage (internal/core/thirdparty/milvus-storage/CMakeLists.txt):
    pin advanced from 3bc763b → b420145, which is the merged commit for
    #742.
    The storage-v2 use_iam path (azure_fs_producer.cpp) now has the same
    WI→SPN→MI priority as the C++ chunk manager.
    The subsequent upstream commit (1067385, Paimon feature) was excluded
    because it requires rustc ≥ 1.94.0 and milvus CI currently has 1.92.0.
  • woodpecker (pkg/go.mod): #449
    is merged to upstream/master but not yet in a tagged release (post-v0.1.47).
    The go.mod pin will be bumped in a follow-up PR once v0.1.48 is released.
    Until then, the woodpecker WAL path in an SPN-only environment falls back
    to Managed Identity.

issue: #54702

…IAM mode

When AZURE_CLIENT_SECRET is set, both the Go object storage client
(pkg/objectstorage) and the C++ chunk manager (AzureBlobChunkManager)
now select DefaultAzureCredential before trying Workload Identity or
Managed Identity.

This enables SPN/service-principal auth via standard Azure env vars
(AZURE_CLIENT_ID, AZURE_CLIENT_SECRET, AZURE_TENANT_ID) without
requiring IMDS, a pod identity, or a VM-attached identity.

Credential priority matches DefaultAzureCredential's own chain order:
1. AZURE_CLIENT_SECRET set -> DefaultAzureCredential (SPN via EnvironmentCredential)
2. AZURE_FEDERATED_TOKEN_FILE set -> WorkloadIdentityCredential
3. otherwise -> ManagedIdentityCredential

Go: unit test added in util_test.go.
C++: no behaviour change to existing Workload Identity / Managed Identity paths.

/kind improvement

Signed-off-by: Sarvesh Srivastava <sarveshsrivastava72@gmail.com>
@sre-ci-robot sre-ci-robot added the kind/improvement Changes related to something improve, likes ut and code refactor label Oct 22, 2026
@sre-ci-robot

Copy link
Copy Markdown
Contributor

Welcome @sarveshls! It looks like this is your first PR to milvus-io/milvus 🎉

@sre-ci-robot

Copy link
Copy Markdown
Contributor

[APPROVALNOTIFIER] This PR is NOT APPROVED

This pull-request has been approved by:
To complete the pull request process, please assign foxspy after the PR has been reviewed.
You can assign the PR to them by writing /assign @foxspy in a comment when ready.

The full list of commands accepted by this bot can be found here.

Details Needs approval from an approver in each of these files:

Approvers can indicate their approval by writing /approve in a comment
Approvers can cancel approval by writing /approve cancel in a comment

@sre-ci-robot sre-ci-robot added the size/M Denotes a PR that changes 30-99 lines. label Oct 22, 2026
@mergify mergify Bot added dco-passed DCO check passed. kind/enhancement Issues or changes related to enhancement labels Oct 22, 2026
@sre-ci-robot

Copy link
Copy Markdown
Contributor

[ci-v2-notice]
Notice: New ci-v2 system is enabled for this PR.

To rerun ci-v2 checks, comment with:

  • /ci-rerun-code-check // for ci-v2/code-check
  • /ci-rerun-code-check-macos // for Code Checker MacOS (GitHub Actions)
  • /ci-rerun-build // for ci-v2/build
  • /ci-rerun-build-all // for ci-v2/build-all (multi-arch builds)
  • /ci-rerun-buildenv // for ci-v2/build-env (build milvus-env builder images; update .env after the new tag is ready)
  • /ci-rerun-ut-integration // for ci-v2/ut-integration, will rerun ci-v2/build
  • /ci-rerun-ut-go // for ci-v2/ut-go, will rerun ci-v2/build
  • /ci-rerun-ut-cpp // for ci-v2/ut-cpp
  • /ci-rerun-ut // for all ci-v2/ut-integration, ci-v2/ut-go, ci-v2/ut-cpp, will rerun ci-v2/build
  • /ci-rerun-e2e-default // for ci-v2/e2e-default
  • /ci-rerun-e2e-pulsar-wp // for ci-v2/e2e-pulsar-wp (GCP branch-equivalent Pulsar + Woodpecker Python E2E)
  • /ci-rerun-e2e-amd // for ci-v2/e2e-amd (e2e pool dispatcher)
  • /ci-rerun-e2e-dist-wp // for ci-v2/e2e-dist-wp (Tencent distributed woodpecker-service boundary)
  • /ci-rerun-build-ut-cov // for ci-v2/build-ut-cov (build + unit tests in one pipeline)
  • /ci-rerun-build-ut-cov-tcus // force TC-US build-ut-cov; respects Portal limit, never falls back to AWS
  • /ci-rerun-gosdk // for ci-v2/go-sdk (Go SDK E2E tests, ARM)
  • /ci-rerun-gosdk-std // for ci-v2/go-sdk-std (Go SDK E2E, standalone)
  • /ci-rerun-gosdk-dist-wp // for ci-v2/go-sdk-dist-wp (Go SDK E2E, distributed + Woodpecker service)

If you have any questions or requests, please contact @zhikunyao.

@sarveshls

sarveshls commented Oct 22, 2026 •

Copy link
Copy Markdown
Author

Related PRs applying the same credential selection pattern across the ecosystem:

# Repo PR URL Status
1 milvus-storage milvus-io/milvus-storage#742 Merged ✅
2 woodpecker zilliztech/woodpecker#449 Merged ✅
3 milvus-operator zilliztech/milvus-operator#558 Merged ✅

@sre-ci-robot

Copy link
Copy Markdown
Contributor

❌ CI Loop Results 8870959

Stage Result Duration Tests
✅ Build SUCCESS 14.3min -
❌ Code-Check FAILURE 2.4min -
✅ UT-Integration SUCCESS 64.5min -
✅ UT-GO SUCCESS 29.6min -
✅ UT-CPP-Cov SUCCESS 60.7min 22338 total, 22338 passed, 0 failed

Total: 120min | Pipeline | Artifacts

Overall Coverage: 77.5%
Diff Coverage: CPP 0.0% (0 hit, 10 miss, 10 measurable lines, 3 unmeasured) | Go N/A (0 hit, 0 miss, 0 measurable lines, 3 unmeasured)
Diff Coverage HTML: view changed lines
Go Patch Warning: WARNING: Go patch coverage unavailable; changed Go lines did not match the coverage profile.
Total Patch Coverage: N/A (untrusted: changed source lines have no coverage data)
Measured Patch Coverage: 0.0% (0/10 measurable lines, 6 unmeasured)

Failed Test Logs:

…name test

Signed-off-by: sarveshls <sarveshsrivastava72@gmail.com>
@sarveshls sarveshls changed the title enhance: support Azure SPN credentials via DefaultAzureCredential in IAM mode enhance: support Azure SPN credentials via ClientSecretCredential in IAM mode Oct 26, 2026
@sre-ci-robot

Copy link
Copy Markdown
Contributor

❌ CI Loop Results 87126b8

Stage Result Duration Tests
✅ Build SUCCESS 13.6min -
❌ Code-Check FAILURE 3.5min -
✅ UT-GO SUCCESS 31.0min -
❌ UT-CPP-Cov FAILURE 56.3min 22338 total, 22337 passed, 1 failed
✅ UT-Integration SUCCESS 48.4min 658 total, 650 passed, 0 failed, 8 skipped

Total: 102min | Pipeline | Artifacts

Overall Coverage: 77.4%
Diff Coverage: CPP 0.0% (0 hit, 14 miss, 14 measurable lines, 7 unmeasured) | Go N/A (0 hit, 0 miss, 0 measurable lines, 14 unmeasured)
Diff Coverage HTML: view changed lines
Go Patch Warning: WARNING: Go patch coverage unavailable; changed Go lines did not match the coverage profile.
Total Patch Coverage: N/A (untrusted: changed source lines have no coverage data)
Measured Patch Coverage: 0.0% (0/14 measurable lines, 21 unmeasured)

Failed Test Logs:

@tinswzy

tinswzy commented Oct 26, 2026

Copy link
Copy Markdown
Contributor

Must-fix issues introduced by this PR: 0
Merge recommendation: Mergeable as-is — this review found no must-fix issue introduced by this PR.
Also reported: 2 pre-existing hazards (real, but not introduced here — follow-up only, does not block this PR).

This PR adds a Service Principal (client secret) credential path for Azure Blob in both the Go and C++ object storage clients; review found one lint failure introduced by the new Go code, a coverage gap in the new test, a C++ validation gap, and two pre-existing dependency hazards that leave other Azure storage paths on Managed Identity.

Medium

  • pkg/objectstorage/util.go:207 — The new return nil, fmt.Errorf("SPN authentication requires ...") matches the rawmerrerror ruleguard pattern in pkg/rules.go:417, and none of that rule's exemptions cover pkg/objectstorage. CI code-checker runs make verifiers (which runs golangci-lint on the pkg module) → gocritic reports raw error returned from function body, golangci-lint exits 1, and the static check fails. Reproduced on the PR head with golangci-lint 2.11.3. Suggestion: return a typed merr error instead, e.g. merr.WrapErrParameterInvalidMsg(...) or merr.WrapErrServiceInternal(...). (raised by bigsheeper, tinswzy)

Low

  • internal/core/src/storage/azure/AzureBlobChunkManager.cpp:117 — The new SPN branch passes empty strings to Azure::Identity::ClientSecretCredential when AZURE_TENANT_ID or AZURE_CLIENT_ID is unset; azure-identity's ClientCredentialCore constructor only stores the tenant ID and performs no non-empty check, so this is inconsistent with the Go side (util.go:206-208) and with the PR description's fail-fast claim. useIAM=true with AZURE_CLIENT_SECRET set but tenant/client ID missing, and the C++ chunk manager constructed before or independently of the Go validation → construction succeeds and the first blob operation throws AuthenticationException after requesting a token from https://login.microsoftonline.com//oauth2/v2.0/token, with no pointer to the missing environment variable. Suggestion: validate both variables in the C++ branch and raise an explicit configuration error at construction time, matching the Go behavior. Also remove the newly added #include <azure/identity/default_azure_credential.hpp> on line 17; DefaultAzureCredential is not referenced anywhere in the file. (surfaced during verification)

  • pkg/objectstorage/util_test.go:586 — TestNewAzureClientSPNCredentialPath sets SkipBucketCheck: true, which bypasses the only operation that would request a token, and then asserts only on client.URL(). This proves NewClientSecretCredential constructs without error when all three variables are present, but it does not exercise the error branch at util.go:206-208 and would not catch mistakes such as swapped credential arguments. Suggestion: add at least one case where AZURE_TENANT_ID or AZURE_CLIENT_ID is missing and NewAzureObjectStorageClient is expected to return an error, plus a precedence case where both AZURE_FEDERATED_TOKEN_FILE and AZURE_CLIENT_SECRET are set and the Workload Identity path is taken. (raised by bigsheeper, tinswzy)

Pre-existing hazards — not introduced by this PR (follow-up only)

The following hazards are real but pre-existing and were not introduced by this PR. They should be tracked as separate follow-up work and do not block this PR.

  • internal/core/thirdparty/milvus-storage/CMakeLists.txt:17 — milvus-storage remains pinned at 3bc763b, whose cpp/src/filesystem/azure/azure_fs_producer.cpp use_iam branch only selects Workload Identity (when AZURE_FEDERATED_TOKEN_FILE is set) or ConfigureManagedIdentityCredential(client_id), and never reads AZURE_CLIENT_SECRET. StorageV2FSCache.cpp:50 forwards useIAM unchanged, so with storage v2 packed format enabled in an SPN-only environment → the Go and C++ chunk managers authenticate as the SPN while packed reads/writes still go through Managed Identity, failing without IMDS or silently using a different identity when another MI is attached to the VM. Upstream fix feat: support Azure SPN credentials via EnvironmentCredential in IAM mode milvus-storage#742 was still open at review time; no tracking issue yet. This is unrelated to this PR because the diff touches only AzureBlobChunkManager.cpp, util.go, and util_test.go, and the storage v2 MI behavior existed before it. Recommend merging that separate fix and bumping the pin before this PR, or stating in the PR description that storage v2 does not support SPN until then. (raised by bigsheeper)

  • pkg/go.mod:40 — woodpecker remains pinned at v0.1.46, whose common/objectstorage/azure_object_storage.go:209-228 is identical to the pre-PR Go code: Workload Identity when AZURE_FEDERATED_TOKEN_FILE is set, otherwise NewManagedIdentityCredential, with no SPN branch. pkg/streaming/walimpls/impls/wp/builder.go:51-52 calls wpStorageClient.NewObjectStorage for object-storage-backed WAL and builder.go:186 forwards MinioCfg.UseIAM unchanged, so with woodpecker as the WAL backend in an SPN-only environment → Milvus's own object storage client starts successfully but the streamingnode's WAL opener fails to obtain a Managed Identity token and all writes fail, or WAL data is accessed under another MI's identity if one is attached. Upstream fix enhance: support Azure SPN credentials via ClientSecretCredential in IAM mode zilliztech/woodpecker#449 was still open at review time and is not in the latest tag v0.1.47; no tracking issue yet. This is unrelated to this PR because the diff contains no changes to go.mod, pkg/go.mod, or the woodpecker WAL implementation. Recommend merging that separate fix and bumping the dependency before this PR, or stating in the PR description that WAL SPN support depends on a later bump. (raised by bigsheeper)

Signed-off-by: sarveshls <sarveshsrivastava72@gmail.com>
@sre-ci-robot sre-ci-robot added size/L Denotes a PR that changes 100-499 lines. and removed size/M Denotes a PR that changes 30-99 lines. labels Oct 26, 2026
@mergify

mergify Bot commented Oct 26, 2026

Copy link
Copy Markdown
Contributor

@sarveshls Please associate the related issue to the body of your Pull Request. (eg. "issue: #")

@sarveshls

Copy link
Copy Markdown
Author

Must-fix issues introduced by this PR: 0
Merge recommendation: Mergeable as-is — this review found no must-fix issue introduced by this PR.
Also reported: 2 pre-existing hazards (real, but not introduced here — follow-up only, does not block this PR).

This PR adds a Service Principal (client secret) credential path for Azure Blob in both the Go and C++ object storage clients; review found one lint failure introduced by the new Go code, a coverage gap in the new test, a C++ validation gap, and two pre-existing dependency hazards that leave other Azure storage paths on Managed Identity.

Medium

  • pkg/objectstorage/util.go:207 — The new return nil, fmt.Errorf("SPN authentication requires ...") matches the rawmerrerror ruleguard pattern in pkg/rules.go:417, and none of that rule's exemptions cover pkg/objectstorage. CI code-checker runs make verifiers (which runs golangci-lint on the pkg module) → gocritic reports raw error returned from function body, golangci-lint exits 1, and the static check fails. Reproduced on the PR head with golangci-lint 2.11.3. Suggestion: return a typed merr error instead, e.g. merr.WrapErrParameterInvalidMsg(...) or merr.WrapErrServiceInternal(...). (raised by bigsheeper, tinswzy)

Low

  • internal/core/src/storage/azure/AzureBlobChunkManager.cpp:117 — The new SPN branch passes empty strings to Azure::Identity::ClientSecretCredential when AZURE_TENANT_ID or AZURE_CLIENT_ID is unset; azure-identity's ClientCredentialCore constructor only stores the tenant ID and performs no non-empty check, so this is inconsistent with the Go side (util.go:206-208) and with the PR description's fail-fast claim. useIAM=true with AZURE_CLIENT_SECRET set but tenant/client ID missing, and the C++ chunk manager constructed before or independently of the Go validation → construction succeeds and the first blob operation throws AuthenticationException after requesting a token from https://login.microsoftonline.com//oauth2/v2.0/token, with no pointer to the missing environment variable. Suggestion: validate both variables in the C++ branch and raise an explicit configuration error at construction time, matching the Go behavior. Also remove the newly added #include <azure/identity/default_azure_credential.hpp> on line 17; DefaultAzureCredential is not referenced anywhere in the file. (surfaced during verification)
  • pkg/objectstorage/util_test.go:586 — TestNewAzureClientSPNCredentialPath sets SkipBucketCheck: true, which bypasses the only operation that would request a token, and then asserts only on client.URL(). This proves NewClientSecretCredential constructs without error when all three variables are present, but it does not exercise the error branch at util.go:206-208 and would not catch mistakes such as swapped credential arguments. Suggestion: add at least one case where AZURE_TENANT_ID or AZURE_CLIENT_ID is missing and NewAzureObjectStorageClient is expected to return an error, plus a precedence case where both AZURE_FEDERATED_TOKEN_FILE and AZURE_CLIENT_SECRET are set and the Workload Identity path is taken. (raised by bigsheeper, tinswzy)

Pre-existing hazards — not introduced by this PR (follow-up only)

The following hazards are real but pre-existing and were not introduced by this PR. They should be tracked as separate follow-up work and do not block this PR.

  • internal/core/thirdparty/milvus-storage/CMakeLists.txt:17 — milvus-storage remains pinned at 3bc763b, whose cpp/src/filesystem/azure/azure_fs_producer.cpp use_iam branch only selects Workload Identity (when AZURE_FEDERATED_TOKEN_FILE is set) or ConfigureManagedIdentityCredential(client_id), and never reads AZURE_CLIENT_SECRET. StorageV2FSCache.cpp:50 forwards useIAM unchanged, so with storage v2 packed format enabled in an SPN-only environment → the Go and C++ chunk managers authenticate as the SPN while packed reads/writes still go through Managed Identity, failing without IMDS or silently using a different identity when another MI is attached to the VM. Upstream fix feat: support Azure SPN credentials via EnvironmentCredential in IAM mode milvus-storage#742 was still open at review time; no tracking issue yet. This is unrelated to this PR because the diff touches only AzureBlobChunkManager.cpp, util.go, and util_test.go, and the storage v2 MI behavior existed before it. Recommend merging that separate fix and bumping the pin before this PR, or stating in the PR description that storage v2 does not support SPN until then. (raised by bigsheeper)
  • pkg/go.mod:40 — woodpecker remains pinned at v0.1.46, whose common/objectstorage/azure_object_storage.go:209-228 is identical to the pre-PR Go code: Workload Identity when AZURE_FEDERATED_TOKEN_FILE is set, otherwise NewManagedIdentityCredential, with no SPN branch. pkg/streaming/walimpls/impls/wp/builder.go:51-52 calls wpStorageClient.NewObjectStorage for object-storage-backed WAL and builder.go:186 forwards MinioCfg.UseIAM unchanged, so with woodpecker as the WAL backend in an SPN-only environment → Milvus's own object storage client starts successfully but the streamingnode's WAL opener fails to obtain a Managed Identity token and all writes fail, or WAL data is accessed under another MI's identity if one is attached. Upstream fix enhance: support Azure SPN credentials via ClientSecretCredential in IAM mode zilliztech/woodpecker#449 was still open at review time and is not in the latest tag v0.1.47; no tracking issue yet. This is unrelated to this PR because the diff contains no changes to go.mod, pkg/go.mod, or the woodpecker WAL implementation. Recommend merging that separate fix and bumping the dependency before this PR, or stating in the PR description that WAL SPN support depends on a later bump. (raised by bigsheeper)

Thanks for reviewing @tinswzy. I've made the changes you've addressed in the code.

@sarveshls

Copy link
Copy Markdown
Author

@bigsheeper (not able to mention zwd1208)
Please review the changes.

@sarveshls

Copy link
Copy Markdown
Author

@foxspy - your approval is required on one of the CIs please

@sre-ci-robot

Copy link
Copy Markdown
Contributor

❌ CI Loop Results b2a8358

Stage Result Duration Tests
✅ Build SUCCESS 5.7min -
❌ Code-Check FAILURE 2.4min -
✅ UT-Integration SUCCESS 54.8min -
❌ UT-GO FAILURE 30.9min -
✅ UT-CPP-Cov SUCCESS 41.3min 22338 total, 22338 passed, 0 failed

Total: 104min | Pipeline | Artifacts

Overall Coverage: 77.5%
Diff Coverage: CPP 0.0% (0 hit, 16 miss, 16 measurable lines, 7 unmeasured) | Go N/A (0 hit, 0 miss, 0 measurable lines, 14 unmeasured)
Diff Coverage HTML: view changed lines
Go Patch Warning: WARNING: Go patch coverage unavailable; changed Go lines did not match the coverage profile.
Total Patch Coverage: N/A (untrusted: changed source lines have no coverage data)
Measured Patch Coverage: 0.0% (0/16 measurable lines, 21 unmeasured)

Failed Test Logs:

TestNewAzureClientWITakesPriorityOverSPN previously set CLIENT_ID and
TENANT_ID to non-empty UUIDs. With those values set, NewWorkloadIdentity-
Credential construction succeeds (token file is not read until GetToken,
not at construction time), so NewAzureObjectStorageClient returns nil error
and require.Error failed.

Fix: clear CLIENT_ID and TENANT_ID. The WI branch is still entered first
(FEDERATED_TOKEN_FILE is set), but NewWorkloadIdentityCredential now fails
at construction with a missing-tenant/client error — distinct from the SPN
validation error ('SPN authentication requires...'), which is what the
assert.NotContains assertion verifies.

Signed-off-by: sarveshls <sarveshsrivastava72@gmail.com>
Fix two formatting issues detected by Code-Check CI:
- Reformat has_client_secret bool assignment to fit ColumnLimit: 80
- Split long string literal in throw std::invalid_argument() across two lines

Signed-off-by: sarveshls <sarveshsrivastava72@gmail.com>
@sre-ci-robot

Copy link
Copy Markdown
Contributor

❌ CI Loop Results 6753f9c

Stage Result Duration Tests
✅ Build SUCCESS 4.7min -
❌ Code-Check FAILURE 2.1min -
✅ UT-Integration SUCCESS 56.0min -
✅ UT-GO SUCCESS 9.0min -
✅ UT-CPP-Cov SUCCESS 41.2min 22338 total, 22338 passed, 0 failed

Total: 80min | Pipeline | Artifacts

Overall Coverage: 77.5%
Diff Coverage: CPP 0.0% (0 hit, 16 miss, 16 measurable lines, 7 unmeasured) | Go N/A (0 hit, 0 miss, 0 measurable lines, 14 unmeasured)
Diff Coverage HTML: view changed lines
Go Patch Warning: WARNING: Go patch coverage unavailable; changed Go lines did not match the coverage profile.
Total Patch Coverage: N/A (untrusted: changed source lines have no coverage data)
Measured Patch Coverage: 0.0% (0/16 measurable lines, 21 unmeasured)

Failed Test Logs:

Match the &&-continuation style used for has_federated_token above it,
which is what clang-format-15 (ColumnLimit:80, AlignAfterOpenBracket:
Align) produces — break at && and align the second operand, not
break-after-= as Apple clang-format v21 did.

Signed-off-by: sarveshls <sarveshsrivastava72@gmail.com>
@sre-ci-robot

Copy link
Copy Markdown
Contributor

❌ CI Loop Results 45bd0cb

Stage Result Duration Tests
✅ Build SUCCESS 5.3min -
❌ Code-Check FAILURE 6.7min -
✅ UT-Integration SUCCESS 55.4min -
✅ UT-GO SUCCESS 30.2min -
✅ UT-CPP-Cov SUCCESS 59.5min 22338 total, 22338 passed, 0 failed

Total: 106min | Pipeline | Artifacts

Overall Coverage: 77.5%
Diff Coverage: CPP 0.0% (0 hit, 16 miss, 16 measurable lines, 8 unmeasured) | Go N/A (0 hit, 0 miss, 0 measurable lines, 14 unmeasured)
Diff Coverage HTML: view changed lines
Go Patch Warning: WARNING: Go patch coverage unavailable; changed Go lines did not match the coverage profile.
Total Patch Coverage: N/A (untrusted: changed source lines have no coverage data)
Measured Patch Coverage: 0.0% (0/16 measurable lines, 22 unmeasured)

Failed Test Logs:

Use the exact output of clang-format-15.0.0 (with project .clang-format):
break after = and use IndentWidth continuation for the boolean, matching
the formatter's preference over &&-alignment for this expression length.

Signed-off-by: sarveshls <sarveshsrivastava72@gmail.com>
…SPN validation

The segcore error boundary check requires every throw in internal/core/src
to use a milvus-typed exception (SegcoreError via ThrowInfo) so that it
reaches the cgo boundary with a proper ErrorCode rather than UnexpectedError.

Replace throw std::invalid_argument(...) with ThrowInfo(ConfigInvalid, ...)
and add #include "common/EasyAssert.h" to bring in ThrowInfo/ConfigInvalid.

Signed-off-by: sarveshls <sarveshsrivastava72@gmail.com>
@sre-ci-robot

Copy link
Copy Markdown
Contributor

❌ CI Loop Results e5daa42

Stage Result Duration Tests
❌ Build FAILURE 8.8min -
❌ Code-Check SKIPPED - -
❌ UT-Integration SKIPPED - -
❌ UT-GO SKIPPED - -
❌ UT-CPP-Cov SKIPPED - -

Total: 14min | Pipeline | Artifacts

Failed Test Logs:

…Manager

ThrowInfo(ConfigInvalid, ...) failed to compile because ConfigInvalid
lives in the milvus namespace and AzureBlobChunkManager.cpp is in the
azure namespace with no using-directive. Use milvus::ErrorCode::ConfigInvalid
to match the pattern used in loon_ffi/util.cpp (the only other file
outside the milvus namespace that throws this code).

issue: milvus-io#54702
Signed-off-by: sarveshls <sarveshsrivastava72@gmail.com>
@sre-ci-robot

Copy link
Copy Markdown
Contributor

❌ CI Loop Results 3cfab61

Stage Result Duration Tests
✅ Build SUCCESS 4.6min -
❌ Code-Check FAILURE 2.3min -
✅ UT-Integration SUCCESS 55.9min -
✅ UT-GO SUCCESS 3.6min -
✅ UT-CPP-Cov SUCCESS 39.3min 22338 total, 22338 passed, 0 failed

Total: 77min | Pipeline | Artifacts

Overall Coverage: 77.5%
Diff Coverage: CPP 0.0% (0 hit, 16 miss, 16 measurable lines, 8 unmeasured) | Go N/A (0 hit, 0 miss, 0 measurable lines, 14 unmeasured)
Diff Coverage HTML: view changed lines
Go Patch Warning: WARNING: Go patch coverage unavailable; changed Go lines did not match the coverage profile.
Total Patch Coverage: N/A (untrusted: changed source lines have no coverage data)
Measured Patch Coverage: 0.0% (0/16 measurable lines, 22 unmeasured)

Failed Test Logs:

Advances the milvus-storage pin from 3bc763b to 1067385 so that the
storage-v2 Azure filesystem path (azure_fs_producer.cpp use_iam) gains
WI→SPN→MI credential priority in the same release as the C++ chunk
manager.

Key commits pulled in:
- b420145 feat: support Azure SPN credentials via EnvironmentCredential in IAM mode (milvus-io#742)
- 5523f37 fix: retry initial Azure SAS broker credential requests (milvus-io#743)
- f943ea5 fix: invalidate manifest indexes by field ID (milvus-io#744)
- dd87daa enhance: [StorageV2] Replace the footer LRU with file contexts (milvus-io#738)

Note: woodpecker's Azure SPN fix (zilliztech/woodpecker#449) is merged
to upstream/master but not yet tagged (post-v0.1.47). The go.mod pin
will be bumped in a follow-up once v0.1.48 is released.

issue: milvus-io#54702
Signed-off-by: sarveshls <sarveshsrivastava72@gmail.com>
@sre-ci-robot

Copy link
Copy Markdown
Contributor

❌ CI Loop Results 7b2b429

Stage Result Duration Tests
❌ Build FAILURE 1.7min -
❌ Code-Check SKIPPED - -
❌ UT-Integration SKIPPED - -
❌ UT-GO SKIPPED - -
❌ UT-CPP-Cov SKIPPED - -

Total: 6min | Pipeline | Artifacts

Failed Test Logs:

@sre-ci-robot

Copy link
Copy Markdown
Contributor

❌ CI Loop Results a543dd8

Stage Result Duration Tests
✅ Build SUCCESS 3.7min -
❌ Code-Check FAILURE 4.6min -
✅ UT-Integration SUCCESS 54.2min -
✅ UT-GO SUCCESS 9.2min -
✅ UT-CPP-Cov SUCCESS 40.4min 22338 total, 22338 passed, 0 failed

Total: 80min | Pipeline | Artifacts

Overall Coverage: 77.5%
Diff Coverage: CPP 0.0% (0 hit, 16 miss, 16 measurable lines, 8 unmeasured) | Go N/A (0 hit, 0 miss, 0 measurable lines, 14 unmeasured)
Diff Coverage HTML: view changed lines
Go Patch Warning: WARNING: Go patch coverage unavailable; changed Go lines did not match the coverage profile.
Total Patch Coverage: N/A (untrusted: changed source lines have no coverage data)
Measured Patch Coverage: 0.0% (0/16 measurable lines, 22 unmeasured)

Failed Test Logs:

Paimon commit 1067385 pulls in paimon@0.4.0 which requires rustc >=1.94.0;
milvus CI has 1.92.0 and fails. b420145 includes the Azure SPN fix (milvus-io#742)
without the Paimon feature, so CI can build again.

Signed-off-by: sarveshls <sarveshsrivastava72@gmail.com>
@sre-ci-robot

Copy link
Copy Markdown
Contributor

✅ CI Loop Results 4eaa71a

Stage Result Duration Tests
✅ Build SUCCESS 4.9min -
✅ Code-Check SUCCESS 6.8min -
✅ UT-Integration SUCCESS 55.7min -
✅ UT-GO SUCCESS 30.8min -
✅ UT-CPP-Cov SUCCESS 67.4min 22338 total, 22338 passed, 0 failed

Total: 106min | Pipeline | Artifacts

Overall Coverage: 77.5%
Diff Coverage: CPP 0.0% (0 hit, 15 miss, 15 measurable lines, 10 unmeasured) | Go N/A (0 hit, 0 miss, 0 measurable lines, 14 unmeasured)
Diff Coverage HTML: view changed lines
Go Patch Warning: WARNING: Go patch coverage unavailable; changed Go lines did not match the coverage profile.
Total Patch Coverage: N/A (untrusted: changed source lines have no coverage data)
Measured Patch Coverage: 0.0% (0/15 measurable lines, 24 unmeasured)

chasingegg pushed a commit to chasingegg/milvus-storage that referenced this pull request Oct 27, 2026
…mode (milvus-io#742)

## What

When `AZURE_CLIENT_SECRET` is set, `AzureFileSystemProducer` now selects
`ConfigureEnvironmentCredential()` (which reads `AZURE_CLIENT_ID`,
`AZURE_CLIENT_SECRET`, and `AZURE_TENANT_ID`) instead of falling through
to Managed Identity. This enables SPN/service-principal auth without
requiring IMDS access.

## Credential selection order

The selection now uses **WI → SPN → MI** priority:

1. `AZURE_FEDERATED_TOKEN_FILE` set →
`ConfigureWorkloadIdentityCredential()`
2. `AZURE_CLIENT_SECRET` set → `ConfigureEnvironmentCredential()` (SPN)
3. otherwise → `ConfigureManagedIdentityCredential()`

WI is checked before SPN so that existing deployments with valid
Workload
Identity config are not silently switched to a different identity if
`AZURE_CLIENT_SECRET` happens to be present in the environment.

When `AZURE_CLIENT_SECRET` is set, `AZURE_CLIENT_ID` and
`AZURE_TENANT_ID`
are validated upfront — returning a clear error at startup rather than
silently falling through to another credential type.

A startup log line is emitted per branch so the selected credential type
is visible.

## Related PRs

Same credential selection pattern applied across the ecosystem:

| Repo | PR |
|------|----|
| zilliztech/woodpecker |
[milvus-io#449](zilliztech/woodpecker#449) |
| zilliztech/milvus-operator |
[milvus-io#558](zilliztech/milvus-operator#558) |
| milvus-io/milvus |
[#54582](milvus-io/milvus#54582) |

---------

Signed-off-by: Sarvesh Srivastava <sarveshsrivastava72@gmail.com>
Signed-off-by: sarveshls <sarveshsrivastava72@gmail.com>
@sre-ci-robot

Copy link
Copy Markdown
Contributor

✅ CI Loop Results ba88154

Stage Result Duration Tests
✅ Build SUCCESS 5.8min -
✅ Code-Check SUCCESS 7.1min -
✅ UT-Integration SUCCESS 55.9min -
✅ UT-GO SUCCESS 3.5min -
✅ UT-CPP-Cov SUCCESS 42.4min 22338 total, 22338 passed, 0 failed

Total: 81min | Pipeline | Artifacts

Overall Coverage: 77.5%
Diff Coverage: CPP 0.0% (0 hit, 15 miss, 15 measurable lines, 10 unmeasured) | Go N/A (0 hit, 0 miss, 0 measurable lines, 14 unmeasured)
Diff Coverage HTML: view changed lines
Go Patch Warning: WARNING: Go patch coverage unavailable; changed Go lines did not match the coverage profile.
Total Patch Coverage: N/A (untrusted: changed source lines have no coverage data)
Measured Patch Coverage: 0.0% (0/15 measurable lines, 24 unmeasured)

@sarveshls

Copy link
Copy Markdown
Author

@bigsheeper @tinswzy - CI Loop has passed. I've updated the milvus-storage hash in 'internal/core/thirdparty/milvus-storage/CMakeLists.txt', but the Woodpecker tag still needs to updated in the go.mod, what should we do about that?

@mergify mergify Bot added the ci-passed label Oct 27, 2026
@sarveshls

Copy link
Copy Markdown
Author

@bigsheeper @tinswzy - All checks have passed, awaiting your review/approval on the PR

@sarveshls

Copy link
Copy Markdown
Author

Hey @bigsheeper @tinswzy , requesting your review and approval on this PR

@sarveshls

Copy link
Copy Markdown
Author

Hey @bigsheeper @tinswzy , requesting your review and approval on this PR

FYI - operator PR is now merged.

@mergify mergify Bot removed the ci-passed label Oct 29, 2026
@sre-ci-robot

Copy link
Copy Markdown
Contributor

✅ CI Loop Results f617354

Stage Result Duration Tests
✅ Build SUCCESS 5.5min -
✅ Code-Check SUCCESS 6.6min -
✅ UT-Integration SUCCESS 54.5min -
✅ UT-GO SUCCESS 35.0min -
✅ UT-CPP-Cov SUCCESS 40.7min 22633 total, 22633 passed, 0 failed

Total: 112min | Pipeline | Artifacts

Overall Coverage: 78.0%
Diff Coverage: CPP 0.0% (0 hit, 15 miss, 15 measurable lines, 10 unmeasured) | Go N/A (0 hit, 0 miss, 0 measurable lines, 14 unmeasured)
Diff Coverage HTML: view changed lines
Go Patch Warning: WARNING: Go patch coverage unavailable; changed Go lines did not match the coverage profile.
Total Patch Coverage: N/A (untrusted: changed source lines have no coverage data)
Measured Patch Coverage: 0.0% (0/15 measurable lines, 24 unmeasured)

@mergify mergify Bot added the ci-passed label Oct 29, 2026
@sarveshls

Copy link
Copy Markdown
Author

Merge conflicts resolved. @bigsheeper @tinswzy pls review the PR

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area/compilation ci-passed dco-passed DCO check passed. kind/enhancement Issues or changes related to enhancement kind/improvement Changes related to something improve, likes ut and code refactor size/L Denotes a PR that changes 100-499 lines.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants