Merge pull request #4799 from letmaik/letmaik/azure-force-cli-credential

Azure: add option to force use of CLI credential
This commit is contained in:
Michael Eischer 2024-05-18 20:22:15 +00:00 committed by GitHub
commit 9c5bac6f25
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
5 changed files with 43 additions and 14 deletions

View file

@ -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

View file

@ -550,17 +550,23 @@ For authentication export one of the following variables:
# For SAS # For SAS
$ export AZURE_ACCOUNT_SAS=<SAS_TOKEN> $ export AZURE_ACCOUNT_SAS=<SAS_TOKEN>
For authentication using ``az login`` set the resource group name and ensure the user has For authentication using ``az login`` ensure the user has
the minimum permissions of the role assignment ``Storage Blob Data Contributor`` on Azure RBAC. the minimum permissions of the role assignment ``Storage Blob Data Contributor`` on Azure RBAC
for the storage account.
.. code-block:: console .. code-block:: console
$ export AZURE_RESOURCE_GROUP=<RESOURCE_GROUP_NAME>
$ az login $ az login
Alternatively, if run on Azure, restic will automatically uses service accounts configured Alternatively, if run on Azure, restic will automatically use service accounts configured
via the standard environment variables or Workload / Managed Identities. 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. Restic will by default use Azure's global domain ``core.windows.net`` as endpoint suffix.
You can specify other suffixes as follows: You can specify other suffixes as follows:

View file

@ -673,6 +673,7 @@ environment variables. The following lists these environment variables:
AZURE_ACCOUNT_KEY Account key for Azure AZURE_ACCOUNT_KEY Account key for Azure
AZURE_ACCOUNT_SAS Shared access signatures (SAS) for Azure AZURE_ACCOUNT_SAS Shared access signatures (SAS) for Azure
AZURE_ENDPOINT_SUFFIX Endpoint suffix for Azure Storage (default: core.windows.net) 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_ID Account ID or applicationKeyId for Backblaze B2
B2_ACCOUNT_KEY Account Key or applicationKey for Backblaze B2 B2_ACCOUNT_KEY Account Key or applicationKey for Backblaze B2

View file

@ -102,10 +102,20 @@ func open(cfg Config, rt http.RoundTripper) (*Backend, error) {
return nil, errors.Wrap(err, "NewAccountSASClientFromEndpointToken") return nil, errors.Wrap(err, "NewAccountSASClientFromEndpointToken")
} }
} else { } else {
debug.Log(" - using DefaultAzureCredential") var cred azcore.TokenCredential
cred, err := azidentity.NewDefaultAzureCredential(nil)
if err != nil { if cfg.ForceCliCredential {
return nil, errors.Wrap(err, "NewDefaultAzureCredential") 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) client, err = azContainer.NewClient(url, cred, opts)

View file

@ -3,6 +3,7 @@ package azure
import ( import (
"os" "os"
"path" "path"
"strconv"
"strings" "strings"
"github.com/restic/restic/internal/backend" "github.com/restic/restic/internal/backend"
@ -13,12 +14,13 @@ import (
// Config contains all configuration necessary to connect to an azure compatible // Config contains all configuration necessary to connect to an azure compatible
// server. // server.
type Config struct { type Config struct {
AccountName string AccountName string
AccountSAS options.SecretString AccountSAS options.SecretString
AccountKey options.SecretString AccountKey options.SecretString
EndpointSuffix string ForceCliCredential bool
Container string EndpointSuffix string
Prefix string Container string
Prefix string
Connections uint `option:"connections" help:"set a limit for the number of concurrent connections (default: 5)"` 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")) 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 == "" { if cfg.EndpointSuffix == "" {
cfg.EndpointSuffix = os.Getenv(prefix + "AZURE_ENDPOINT_SUFFIX") cfg.EndpointSuffix = os.Getenv(prefix + "AZURE_ENDPOINT_SUFFIX")
} }