Skip to content

feat(backup): support identity-based auth methods for azure - #268

Open
techknowlogick wants to merge 1 commit into
longhorn:masterfrom
commitgo:azure-identity-auth
Open

techknowlogick wants to merge 1 commit into
longhorn:masterfrom
commitgo:azure-identity-auth

Conversation

@techknowlogick

@techknowlogick techknowlogick commented Jan 13, 2026 •

Copy link
Copy Markdown

What this PR does / why we need it:

To support non-static tokens for Azure backup targets. As of right now, if you want to use Azure Blob storage as a backup target (unless you use a fragile workaround with k8s secrets), you need to use a static key.

This PR adds support for Azure managed identity, AKS workload identity and service principals.

If you're still keen on using static tokens but want to scope permissions, you can use service principals. Although this PR is backward compatible with the previous code/configuration, so you can keep using Account Key.

longhorn/longhorn#12600

Additional documentation or context

https://learn.microsoft.com/en-us/entra/identity/managed-identities-azure-resources/overview
https://learn.microsoft.com/en-us/azure/aks/use-managed-identity
https://learn.microsoft.com/en-us/azure/azure-arc/kubernetes/conceptual-workload-identity

@derekbit

Copy link
Copy Markdown
Member

@techknowlogick Thanks for your contribution.
Could you create an IMPROVEMENT ticket in https://github.com/longhorn/longhorn/issues? It will help QA to verify the improvement. Thank you.

@codecov

codecov Bot commented Jan 17, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 29.78723% with 33 lines in your changes missing coverage. Please review.
✅ Project coverage is 5.18%. Comparing base (395c8e4) to head (58574dd).

Files with missing lines Patch % Lines
azblob/azblob_service.go 36.84% 23 Missing and 1 partial ⚠️
util/credential.go 0.00% 9 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff            @@
##           master    #268      +/-   ##
=========================================
+ Coverage    4.53%   5.18%   +0.64%     
=========================================
  Files          23      23              
  Lines        2051    2084      +33     
=========================================
+ Hits           93     108      +15     
- Misses       1950    1966      +16     
- Partials        8      10       +2     
Flag Coverage Δ
unittests 5.18% <29.78%> (+0.64%) ⬆️

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@derekbit

Copy link
Copy Markdown
Member

@techknowlogick Thanks for your contribution. Could you create an IMPROVEMENT ticket in longhorn/longhorn/issues? It will help QA to verify the improvement. Thank you.

ping @techknowlogick

@techknowlogick

Copy link
Copy Markdown
Author

@derekbit thanks for ping. You can find the issue reported here: longhorn/longhorn#12600

Signed-off-by: techknowlogick <techknowlogick@gitea.com>

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.

Pull request overview

Note

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

Adds Azure identity-based authentication support for Azure Blob backup targets, allowing non-static credentials (managed identity, workload identity, service principals) while keeping shared key auth working.

Changes:

  • Switch Azure Blob client creation from connection-string shared key only to SharedKeyCredential (if key present) or DefaultAzureCredential (otherwise).
  • Extend credential env-var setup to optionally set Azure identity env vars (client/tenant/secret) without overwriting webhook-injected values.
  • Add unit tests for parsing account name from URL and building the service URL.

Reviewed changes

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

Show a summary per file
File Description
util/credential.go Adds env-var wiring for Azure identity credentials and relaxes account-key-only validation.
types/types.go Introduces constants for AZURE_CLIENT_ID, AZURE_TENANT_ID, AZURE_CLIENT_SECRET.
azblob/azblob_service.go Uses SharedKeyCredential vs DefaultAzureCredential and adds URL helpers for account/service endpoint construction.
azblob/azblob_service_test.go Adds tests for the new URL helper functions.
go.mod Adds azidentity but also changes several unrelated dependency versions.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread azblob/azblob_service.go
Comment on lines 11 to +14
"github.com/Azure/azure-sdk-for-go/sdk/azcore"
"github.com/Azure/azure-sdk-for-go/sdk/azcore/streaming"
"github.com/Azure/azure-sdk-for-go/sdk/azidentity"
"github.com/Azure/azure-sdk-for-go/sdk/storage/azblob"

Copilot AI Apr 14, 2026

Copy link

Choose a reason for hiding this comment

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

azblobsvc is referenced but (in the shown import block) the azblob SDK package is imported as azblob. This will not compile unless there is an additional aliased import elsewhere in the file. Align the import name and usages (either import sdk/storage/azblob as azblobsvc, or update azblobsvc.* references to azblob.*) so the file compiles consistently.

Copilot uses AI. Check for mistakes.
Comment thread azblob/azblob_service.go
if err != nil {
return nil, err
}
opts := azblobsvc.ClientOptions{ClientOptions: azcore.ClientOptions{Transport: httpClient}}

Copilot AI Apr 14, 2026

Copy link

Choose a reason for hiding this comment

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

azblobsvc is referenced but (in the shown import block) the azblob SDK package is imported as azblob. This will not compile unless there is an additional aliased import elsewhere in the file. Align the import name and usages (either import sdk/storage/azblob as azblobsvc, or update azblobsvc.* references to azblob.*) so the file compiles consistently.

Copilot uses AI. Check for mistakes.
Comment thread azblob/azblob_service.go
if err != nil {
return nil, fmt.Errorf("failed to create SharedKeyCredential: %w", err)
}
serviceClient, err = azblobsvc.NewClientWithSharedKeyCredential(serviceURL, cred, &opts)

Copilot AI Apr 14, 2026

Copy link

Choose a reason for hiding this comment

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

azblobsvc is referenced but (in the shown import block) the azblob SDK package is imported as azblob. This will not compile unless there is an additional aliased import elsewhere in the file. Align the import name and usages (either import sdk/storage/azblob as azblobsvc, or update azblobsvc.* references to azblob.*) so the file compiles consistently.

Copilot uses AI. Check for mistakes.
Comment thread azblob/azblob_service.go
if err != nil {
return nil, fmt.Errorf("failed to create DefaultAzureCredential: %w", err)
}
serviceClient, err = azblobsvc.NewClient(serviceURL, cred, &opts)

Copilot AI Apr 14, 2026

Copy link

Choose a reason for hiding this comment

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

azblobsvc is referenced but (in the shown import block) the azblob SDK package is imported as azblob. This will not compile unless there is an additional aliased import elsewhere in the file. Align the import name and usages (either import sdk/storage/azblob as azblobsvc, or update azblobsvc.* references to azblob.*) so the file compiles consistently.

Copilot uses AI. Check for mistakes.
Comment thread azblob/azblob_service.go
Comment on lines +97 to +106
func extractAccountNameFromURL(u *url.URL) string {
if u.User != nil && u.Host != "" {
// Check if host contains ".blob." indicating full endpoint format
// e.g., "mystorageaccount.blob.core.windows.net"
if idx := strings.Index(u.Host, ".blob."); idx > 0 {
return u.Host[:idx]
}
}
return ""
}

Copilot AI Apr 14, 2026

Copy link

Choose a reason for hiding this comment

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

The account-name extraction is gated on u.User != nil, but the logic actually parses the account name from u.Host. This unnecessarily prevents extraction for valid URLs that omit userinfo (e.g., URLs that embed container in the path rather than container@host). Remove the u.User != nil condition (keep the u.Host != "" check) and add a test case covering a URL with a host like mystorageaccount.blob.core.windows.net but no user part.

Copilot uses AI. Check for mistakes.
Comment thread go.mod
Comment on lines +20 to +28
github.com/longhorn/go-common-libs v0.0.0-20260103034008-119bdcf1b2d6
github.com/pierrec/lz4/v4 v4.1.23
github.com/sirupsen/logrus v1.9.3
github.com/slok/goresilience v0.2.0
github.com/spf13/afero v1.11.0
github.com/stretchr/testify v1.11.1
github.com/stretchr/testify v1.10.0
github.com/urfave/cli v1.22.17
golang.org/x/net v0.49.0
golang.org/x/sys v0.40.0
golang.org/x/net v0.47.0
golang.org/x/sys v0.38.0

Copilot AI Apr 14, 2026

Copy link

Choose a reason for hiding this comment

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

This PR is focused on Azure identity auth, but go.mod also changes multiple unrelated dependencies (including apparent downgrades like logrus, testify, x/net, x/sys, x/text). That increases review surface and risk of regressions unrelated to the feature. Consider reverting the unrelated version changes (keeping only the new Azure identity deps), or splitting dependency churn into a separate PR with its own rationale/release notes.

Copilot uses AI. Check for mistakes.
Comment thread go.mod
Comment on lines +77 to +78
golang.org/x/crypto v0.44.0 // indirect
golang.org/x/text v0.31.0 // indirect

Copilot AI Apr 14, 2026

Copy link

Choose a reason for hiding this comment

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

This PR is focused on Azure identity auth, but go.mod also changes multiple unrelated dependencies (including apparent downgrades like logrus, testify, x/net, x/sys, x/text). That increases review surface and risk of regressions unrelated to the feature. Consider reverting the unrelated version changes (keeping only the new Azure identity deps), or splitting dependency churn into a separate PR with its own rationale/release notes.

Copilot uses AI. Check for mistakes.
Comment thread azblob/azblob_service.go
Comment on lines 43 to 45
accountName := os.Getenv("AZBLOB_ACCOUNT_NAME")
accountKey := os.Getenv("AZBLOB_ACCOUNT_KEY")
azureEndpoint := os.Getenv("AZBLOB_ENDPOINT")

Copilot AI Apr 14, 2026

Copy link

Choose a reason for hiding this comment

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

These env-var keys are hard-coded strings, while the repo already has types.AZBlobAccountName, types.AZBlobAccountKey, and types.AZBlobEndpoint. Using the constants here would reduce duplication/typos and keep env-var naming consistent across packages.

Copilot uses AI. Check for mistakes.

@derekbit derekbit left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

In general, LGTM.

@derekbit

Copy link
Copy Markdown
Member

@techknowlogick Could you address the comments from @copilot? Thank you.

@derekbit

Copy link
Copy Markdown
Member

@derekbit

Copy link
Copy Markdown
Member

@mantissahz @COLDTURNIP Please review the PR.

@mantissahz

Copy link
Copy Markdown
Contributor

In general, LGTM.
@techknowlogick, please fix the conflict. And could you explain why some packages are downgraded?
BTW, maybe we need to test the basic functionalities with the PR first.

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.

4 participants