diff --git a/changelog/unreleased/pull-4799 b/changelog/unreleased/pull-4799 new file mode 100644 index 000000000..0179bc51a --- /dev/null +++ b/changelog/unreleased/pull-4799 @@ -0,0 +1,5 @@ +Enhancement: Add option to force use of Azure CLI credential + +A new environment variable `AZURE_FORCE_CLI_CREDENTIAL=true` allows forcing the use of Azure CLI credential, ignoring other credentials like managed identity. + +https://github.com/restic/restic/pull/4799 diff --git a/doc/030_preparing_a_new_repo.rst b/doc/030_preparing_a_new_repo.rst index 5ff26934a..62499a1d6 100644 --- a/doc/030_preparing_a_new_repo.rst +++ b/doc/030_preparing_a_new_repo.rst @@ -548,9 +548,23 @@ For authentication export one of the following variables: # For SAS $ export AZURE_ACCOUNT_SAS= -Alternatively, if run on Azure, restic will automatically uses service accounts configured +For authentication using ``az login`` ensure the user has +the minimum permissions of the role assignment ``Storage Blob Data Contributor`` on Azure RBAC +for the storage account. + +.. code-block:: console + + $ az login + +Alternatively, if run on Azure, restic will automatically use service accounts configured via the standard environment variables or Workload / Managed Identities. +To enforce the use of the Azure CLI credential when other credentials are present, set the following environment variable: + +.. code-block:: console + + $ export AZURE_FORCE_CLI_CREDENTIAL=true + Restic will by default use Azure's global domain ``core.windows.net`` as endpoint suffix. You can specify other suffixes as follows: diff --git a/doc/040_backup.rst b/doc/040_backup.rst index c917c3c29..621b07e2e 100644 --- a/doc/040_backup.rst +++ b/doc/040_backup.rst @@ -597,6 +597,7 @@ environment variables. The following lists these environment variables: AZURE_ACCOUNT_KEY Account key for Azure AZURE_ACCOUNT_SAS Shared access signatures (SAS) for Azure AZURE_ENDPOINT_SUFFIX Endpoint suffix for Azure Storage (default: core.windows.net) + AZURE_FORCE_CLI_CREDENTIAL Force the use of Azure CLI credentials for authentication B2_ACCOUNT_ID Account ID or applicationKeyId for Backblaze B2 B2_ACCOUNT_KEY Account Key or applicationKey for Backblaze B2 diff --git a/internal/backend/azure/azure.go b/internal/backend/azure/azure.go index 50be63d5a..4ccfb9664 100644 --- a/internal/backend/azure/azure.go +++ b/internal/backend/azure/azure.go @@ -102,10 +102,20 @@ func open(cfg Config, rt http.RoundTripper) (*Backend, error) { return nil, errors.Wrap(err, "NewAccountSASClientFromEndpointToken") } } else { - debug.Log(" - using DefaultAzureCredential") - cred, err := azidentity.NewDefaultAzureCredential(nil) - if err != nil { - return nil, errors.Wrap(err, "NewDefaultAzureCredential") + var cred azcore.TokenCredential + + if cfg.ForceCliCredential { + debug.Log(" - using AzureCLICredential") + cred, err = azidentity.NewAzureCLICredential(nil) + if err != nil { + return nil, errors.Wrap(err, "NewAzureCLICredential") + } + } else { + debug.Log(" - using DefaultAzureCredential") + cred, err = azidentity.NewDefaultAzureCredential(nil) + if err != nil { + return nil, errors.Wrap(err, "NewDefaultAzureCredential") + } } client, err = azContainer.NewClient(url, cred, opts) diff --git a/internal/backend/azure/config.go b/internal/backend/azure/config.go index d819b35aa..61c413efa 100644 --- a/internal/backend/azure/config.go +++ b/internal/backend/azure/config.go @@ -3,6 +3,7 @@ package azure import ( "os" "path" + "strconv" "strings" "github.com/restic/restic/internal/errors" @@ -13,12 +14,13 @@ import ( // Config contains all configuration necessary to connect to an azure compatible // server. type Config struct { - AccountName string - AccountSAS options.SecretString - AccountKey options.SecretString - EndpointSuffix string - Container string - Prefix string + AccountName string + AccountSAS options.SecretString + AccountKey options.SecretString + ForceCliCredential bool + EndpointSuffix string + Container string + Prefix string Connections uint `option:"connections" help:"set a limit for the number of concurrent connections (default: 5)"` } @@ -73,6 +75,11 @@ func (cfg *Config) ApplyEnvironment(prefix string) { cfg.AccountSAS = options.NewSecretString(os.Getenv(prefix + "AZURE_ACCOUNT_SAS")) } + var forceCliCred, err = strconv.ParseBool(os.Getenv(prefix + "AZURE_FORCE_CLI_CREDENTIAL")) + if err == nil { + cfg.ForceCliCredential = forceCliCred + } + if cfg.EndpointSuffix == "" { cfg.EndpointSuffix = os.Getenv(prefix + "AZURE_ENDPOINT_SUFFIX") }