diff --git a/providers/azure/azure.go b/providers/azure/azure.go index 5689dc6..d447872 100644 --- a/providers/azure/azure.go +++ b/providers/azure/azure.go @@ -46,6 +46,8 @@ var DefaultConfig = Config{ // Config Azure storage configuration. type Config struct { + ClientSecret string `yaml:"client_secret"` + TenantID string `yaml:"tenant_id"` StorageAccountName string `yaml:"storage_account"` StorageAccountKey string `yaml:"storage_account_key"` StorageConnectionString string `yaml:"storage_connection_string"` @@ -84,6 +86,10 @@ func (conf *Config) validate() error { errMsg = append(errMsg, "user_assigned_id cannot be set when using storage_connection_string authentication") } + if (conf.TenantID != "" || conf.ClientSecret != "") && (conf.TenantID == "" || conf.ClientSecret == "") { + errMsg = append(errMsg, "tenant_id, user_assigned_id, and client_secret must be set together") + } + if conf.StorageAccountKey != "" && conf.StorageConnectionString != "" { errMsg = append(errMsg, "storage_account_key and storage_connection_string cannot both be set") } diff --git a/providers/azure/azure_test.go b/providers/azure/azure_test.go index a96dcef..5a3d42f 100644 --- a/providers/azure/azure_test.go +++ b/providers/azure/azure_test.go @@ -140,6 +140,27 @@ container: "MyContainer"`), storage_account_key: "" user_assigned_id: "1234-56578678-655" storage_connection_string: "myConnectionString" +container: "MyContainer"`), + wantFailParse: false, + wantFailValidate: true, + }, + { + name: "Valid TenantID, ClientID, ClientSecret", + config: []byte(`storage_account: "myAccount" +storage_account_key: "" +tenant_id: "1234-56578678-655" +user_assigned_id: "1234-56578678-655" +client_secret: "1234-56578678-655" +container: "MyContainer"`), + wantFailParse: false, + wantFailValidate: false, + }, + { + name: "Valid ClientID and ClientSecret but missing TenantID", + config: []byte(`storage_account: "myAccount" +storage_account_key: "" +user_assigned_id: "1234-56578678-655" +client_secret: "1234-56578678-655" container: "MyContainer"`), wantFailParse: false, wantFailValidate: true, diff --git a/providers/azure/helpers.go b/providers/azure/helpers.go index deb86d0..697b8a6 100644 --- a/providers/azure/helpers.go +++ b/providers/azure/helpers.go @@ -71,18 +71,7 @@ func getContainerClient(conf Config, wrapRoundtripper func(http.RoundTripper) ht } // Otherwise use a token credential - var cred azcore.TokenCredential - - // Use Managed Identity Credential if a user assigned ID is set - if conf.UserAssignedID != "" { - msiOpt := &azidentity.ManagedIdentityCredentialOptions{} - msiOpt.ID = azidentity.ClientID(conf.UserAssignedID) - cred, err = azidentity.NewManagedIdentityCredential(msiOpt) - } else { - // Otherwise use Default Azure Credential - cred, err = azidentity.NewDefaultAzureCredential(nil) - } - + cred, err := getTokenCredential(conf) if err != nil { return nil, err } @@ -94,3 +83,17 @@ func getContainerClient(conf Config, wrapRoundtripper func(http.RoundTripper) ht return containerClient, nil } + +func getTokenCredential(conf Config) (azcore.TokenCredential, error) { + if conf.UserAssignedID == "" { + return azidentity.NewDefaultAzureCredential(nil) + } + + if conf.ClientSecret != "" && conf.TenantID != "" { + return azidentity.NewClientSecretCredential(conf.TenantID, conf.UserAssignedID, conf.ClientSecret, &azidentity.ClientSecretCredentialOptions{}) + } + + msiOpt := &azidentity.ManagedIdentityCredentialOptions{} + msiOpt.ID = azidentity.ClientID(conf.UserAssignedID) + return azidentity.NewManagedIdentityCredential(msiOpt) +}