diff --git a/go.mod b/go.mod
index 4e8956f83..dd81a604f 100644
--- a/go.mod
+++ b/go.mod
@@ -33,11 +33,11 @@ require (
cloud.google.com/go/compute/metadata v0.7.0 // indirect
dario.cat/mergo v1.0.2 // indirect
github.com/42wim/httpsig v1.2.3 // indirect
- github.com/Azure/azure-sdk-for-go/sdk/azcore v1.18.0 // indirect
- github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.10.0 // indirect
- github.com/Azure/azure-sdk-for-go/sdk/internal v1.11.1 // indirect
+ github.com/Azure/azure-sdk-for-go/sdk/azcore v1.19.1 // indirect
+ github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.12.0 // indirect
+ github.com/Azure/azure-sdk-for-go/sdk/internal v1.11.2 // indirect
github.com/Azure/go-ansiterm v0.0.0-20250102033503-faa5f7b0171c // indirect
- github.com/AzureAD/microsoft-authentication-library-for-go v1.4.2 // indirect
+ github.com/AzureAD/microsoft-authentication-library-for-go v1.5.0 // indirect
github.com/BurntSushi/toml v1.5.0 // indirect
github.com/MakeNowJust/heredoc v1.0.0 // indirect
github.com/Masterminds/goutils v1.1.1 // indirect
@@ -83,7 +83,7 @@ require (
github.com/gobwas/glob v0.2.3 // indirect
github.com/gogo/protobuf v1.3.2 // indirect
github.com/golang-jwt/jwt/v4 v4.5.2 // indirect
- github.com/golang-jwt/jwt/v5 v5.2.2 // indirect
+ github.com/golang-jwt/jwt/v5 v5.3.0 // indirect
github.com/golang/groupcache v0.0.0-20241129210726-2c02b8208cf8 // indirect
github.com/google/btree v1.1.3 // indirect
github.com/google/gnostic-models v0.6.9 // indirect
diff --git a/go.sum b/go.sum
index fadb0b434..bdac03d54 100644
--- a/go.sum
+++ b/go.sum
@@ -8,20 +8,20 @@ github.com/42wim/httpsig v1.2.3 h1:xb0YyWhkYj57SPtfSttIobJUPJZB9as1nsfo7KWVcEs=
github.com/42wim/httpsig v1.2.3/go.mod h1:nZq9OlYKDrUBhptd77IHx4/sZZD+IxTBADvAPI9G/EM=
github.com/AdaLogics/go-fuzz-headers v0.0.0-20240806141605-e8a1dd7889d6 h1:He8afgbRMd7mFxO99hRNu+6tazq8nFF9lIwo9JFroBk=
github.com/AdaLogics/go-fuzz-headers v0.0.0-20240806141605-e8a1dd7889d6/go.mod h1:8o94RPi1/7XTJvwPpRSzSUedZrtlirdB3r9Z20bi2f8=
-github.com/Azure/azure-sdk-for-go/sdk/azcore v1.18.0 h1:Gt0j3wceWMwPmiazCa8MzMA0MfhmPIz0Qp0FJ6qcM0U=
-github.com/Azure/azure-sdk-for-go/sdk/azcore v1.18.0/go.mod h1:Ot/6aikWnKWi4l9QB7qVSwa8iMphQNqkWALMoNT3rzM=
-github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.10.0 h1:j8BorDEigD8UFOSZQiSqAMOOleyQOOQPnUAwV+Ls1gA=
-github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.10.0/go.mod h1:JdM5psgjfBf5fo2uWOZhflPWyDBZ/O/CNAH9CtsuZE4=
+github.com/Azure/azure-sdk-for-go/sdk/azcore v1.19.1 h1:5YTBM8QDVIBN3sxBil89WfdAAqDZbyJTgh688DSxX5w=
+github.com/Azure/azure-sdk-for-go/sdk/azcore v1.19.1/go.mod h1:YD5h/ldMsG0XiIw7PdyNhLxaM317eFh5yNLccNfGdyw=
+github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.12.0 h1:wL5IEG5zb7BVv1Kv0Xm92orq+5hB5Nipn3B5tn4Rqfk=
+github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.12.0/go.mod h1:J7MUC/wtRpfGVbQ5sIItY5/FuVWmvzlY21WAOfQnq/I=
github.com/Azure/azure-sdk-for-go/sdk/azidentity/cache v0.3.2 h1:yz1bePFlP5Vws5+8ez6T3HWXPmwOK7Yvq8QxDBD3SKY=
github.com/Azure/azure-sdk-for-go/sdk/azidentity/cache v0.3.2/go.mod h1:Pa9ZNPuoNu/GztvBSKk9J1cDJW6vk/n0zLtV4mgd8N8=
-github.com/Azure/azure-sdk-for-go/sdk/internal v1.11.1 h1:FPKJS1T+clwv+OLGt13a8UjqeRuh0O4SJ3lUriThc+4=
-github.com/Azure/azure-sdk-for-go/sdk/internal v1.11.1/go.mod h1:j2chePtV91HrC22tGoRX3sGY42uF13WzmmV80/OdVAA=
+github.com/Azure/azure-sdk-for-go/sdk/internal v1.11.2 h1:9iefClla7iYpfYWdzPCRDozdmndjTm8DXdpCzPajMgA=
+github.com/Azure/azure-sdk-for-go/sdk/internal v1.11.2/go.mod h1:XtLgD3ZD34DAaVIIAyG3objl5DynM3CQ/vMcbBNJZGI=
github.com/Azure/go-ansiterm v0.0.0-20250102033503-faa5f7b0171c h1:udKWzYgxTojEKWjV8V+WSxDXJ4NFATAsZjh8iIbsQIg=
github.com/Azure/go-ansiterm v0.0.0-20250102033503-faa5f7b0171c/go.mod h1:xomTg63KZ2rFqZQzSB4Vz2SUXa1BpHTVz9L5PTmPC4E=
github.com/AzureAD/microsoft-authentication-extensions-for-go/cache v0.1.1 h1:WJTmL004Abzc5wDB5VtZG2PJk5ndYDgVacGqfirKxjM=
github.com/AzureAD/microsoft-authentication-extensions-for-go/cache v0.1.1/go.mod h1:tCcJZ0uHAmvjsVYzEFivsRTN00oz5BEsRgQHu5JZ9WE=
-github.com/AzureAD/microsoft-authentication-library-for-go v1.4.2 h1:oygO0locgZJe7PpYPXT5A29ZkwJaPqcva7BVeemZOZs=
-github.com/AzureAD/microsoft-authentication-library-for-go v1.4.2/go.mod h1:wP83P5OoQ5p6ip3ScPr0BAq0BvuPAvacpEuSzyouqAI=
+github.com/AzureAD/microsoft-authentication-library-for-go v1.5.0 h1:XkkQbfMyuH2jTSjQjSoihryI8GINRcs4xp8lNawg0FI=
+github.com/AzureAD/microsoft-authentication-library-for-go v1.5.0/go.mod h1:HKpQxkWaGLJ+D/5H8QRpyQXA1eKjxkFlOMwck5+33Jk=
github.com/BurntSushi/toml v1.5.0 h1:W5quZX/G/csjUnuI8SUYlsHs9M38FC7znL0lIO+DvMg=
github.com/BurntSushi/toml v1.5.0/go.mod h1:ukJfTF/6rtPPRCnwkur4qwRxa8vTRFBF0uk2lLoLwho=
github.com/MakeNowJust/heredoc v1.0.0 h1:cXCdzVdstXyiTqTvfqk9SDHpKNjxuom+DOlyEeQ4pzQ=
@@ -169,8 +169,8 @@ github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q=
github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q=
github.com/golang-jwt/jwt/v4 v4.5.2 h1:YtQM7lnr8iZ+j5q71MGKkNw9Mn7AjHM68uc9g5fXeUI=
github.com/golang-jwt/jwt/v4 v4.5.2/go.mod h1:m21LjoU+eqJr34lmDMbreY2eSTRJ1cv77w39/MY0Ch0=
-github.com/golang-jwt/jwt/v5 v5.2.2 h1:Rl4B7itRWVtYIHFrSNd7vhTiz9UpLdi6gZhZ3wEeDy8=
-github.com/golang-jwt/jwt/v5 v5.2.2/go.mod h1:pqrtFR0X4osieyHYxtmOUWsAWrfe1Q5UVIyoH402zdk=
+github.com/golang-jwt/jwt/v5 v5.3.0 h1:pv4AsKCKKZuqlgs5sUmn4x8UlGa0kEVt/puTpKx9vvo=
+github.com/golang-jwt/jwt/v5 v5.3.0/go.mod h1:fxCRLWMO43lRc8nhHWY6LGqRcf+1gQWArsqaEUEa5bE=
github.com/golang/groupcache v0.0.0-20241129210726-2c02b8208cf8 h1:f+oWsMOmNPc8JmEHVZIycC7hBoQxHH9pNKQORJNozsQ=
github.com/golang/groupcache v0.0.0-20241129210726-2c02b8208cf8/go.mod h1:wcDNUvekVysuuOpQKo3191zZyTpiI6se1N1ULghS0sw=
github.com/golang/mock v1.4.4/go.mod h1:l3mdAwkq5BuhzHwde/uurv3sEJeZMXNpwsxVWU71h+4=
@@ -402,8 +402,8 @@ github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/
github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=
-github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA=
-github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
+github.com/stretchr/testify v1.11.1 h1:7s2iGBzp5EwR7/aIZr8ao5+dra3wiQyKjjFuvgVKu7U=
+github.com/stretchr/testify v1.11.1/go.mod h1:wZwfW3scLgRK+23gO65QZefKpKQRnfz6sD981Nm4B6U=
github.com/vmihailenco/go-tinylfu v0.2.2 h1:H1eiG6HM36iniK6+21n9LLpzx1G9R3DJa2UjUjbynsI=
github.com/vmihailenco/go-tinylfu v0.2.2/go.mod h1:CutYi2Q9puTxfcolkliPq4npPuofg9N9t8JVrjzwa3Q=
github.com/vmihailenco/msgpack/v5 v5.3.4/go.mod h1:7xyJ9e+0+9SaZT0Wt1RGleJXzli6Q/V5KbhBonMG9jc=
diff --git a/vendor/github.com/Azure/azure-sdk-for-go/sdk/azcore/CHANGELOG.md b/vendor/github.com/Azure/azure-sdk-for-go/sdk/azcore/CHANGELOG.md
index 926ed3882..1799c6ef2 100644
--- a/vendor/github.com/Azure/azure-sdk-for-go/sdk/azcore/CHANGELOG.md
+++ b/vendor/github.com/Azure/azure-sdk-for-go/sdk/azcore/CHANGELOG.md
@@ -1,12 +1,41 @@
# Release History
+## 1.19.1 (2025-09-11)
+
+### Bugs Fixed
+
+* Fixed resource identifier parsing for provider-specific resource hierarchies containing "resourceGroups" segments.
+
+### Other Changes
+
+* Improved error fall-back for improperly authored long-running operations.
+* Upgraded dependencies.
+
+## 1.19.0 (2025-08-21)
+
+### Features Added
+
+* Added `runtime.APIVersionLocationPath` to be set by clients that set the API version in the path.
+
+## 1.18.2 (2025-07-31)
+
+### Bugs Fixed
+
+* Fixed a case in which `BearerTokenPolicy` didn't ensure an authentication error is non-retriable
+
+## 1.18.1 (2025-07-10)
+
+### Bugs Fixed
+
+* Fixed incorrect request/response logging try info when logging a request that's being retried.
+* Fixed a data race in `ResourceID.String()`
+
## 1.18.0 (2025-04-03)
### Features Added
* Added `AccessToken.RefreshOn` and updated `BearerTokenPolicy` to consider nonzero values of it when deciding whether to request a new token
-
## 1.17.1 (2025-03-20)
### Other Changes
diff --git a/vendor/github.com/Azure/azure-sdk-for-go/sdk/azcore/arm/internal/resource/resource_identifier.go b/vendor/github.com/Azure/azure-sdk-for-go/sdk/azcore/arm/internal/resource/resource_identifier.go
index d9a4e36dc..b8348b7d8 100644
--- a/vendor/github.com/Azure/azure-sdk-for-go/sdk/azcore/arm/internal/resource/resource_identifier.go
+++ b/vendor/github.com/Azure/azure-sdk-for-go/sdk/azcore/arm/internal/resource/resource_identifier.go
@@ -27,7 +27,8 @@ var RootResourceID = &ResourceID{
}
// ResourceID represents a resource ID such as `/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/myRg`.
-// Don't create this type directly, use ParseResourceID instead.
+// Don't create this type directly, use [ParseResourceID] instead. Fields are considered immutable and shouldn't be
+// modified after creation.
type ResourceID struct {
// Parent is the parent ResourceID of this instance.
// Can be nil if there is no parent.
@@ -85,28 +86,6 @@ func ParseResourceID(id string) (*ResourceID, error) {
// String returns the string of the ResourceID
func (id *ResourceID) String() string {
- if len(id.stringValue) > 0 {
- return id.stringValue
- }
-
- if id.Parent == nil {
- return ""
- }
-
- builder := strings.Builder{}
- builder.WriteString(id.Parent.String())
-
- if id.isChild {
- builder.WriteString(fmt.Sprintf("/%s", id.ResourceType.lastType()))
- if len(id.Name) > 0 {
- builder.WriteString(fmt.Sprintf("/%s", id.Name))
- }
- } else {
- builder.WriteString(fmt.Sprintf("/providers/%s/%s/%s", id.ResourceType.Namespace, id.ResourceType.Type, id.Name))
- }
-
- id.stringValue = builder.String()
-
return id.stringValue
}
@@ -144,9 +123,9 @@ func newResourceIDWithProvider(parent *ResourceID, providerNamespace, resourceTy
}
func chooseResourceType(resourceTypeName string, parent *ResourceID) ResourceType {
- if strings.EqualFold(resourceTypeName, resourceGroupsLowerKey) {
+ if strings.EqualFold(resourceTypeName, resourceGroupsLowerKey) && isSubscriptionResource(parent) {
return ResourceGroupResourceType
- } else if strings.EqualFold(resourceTypeName, subscriptionsKey) && parent != nil && parent.ResourceType.String() == TenantResourceType.String() {
+ } else if strings.EqualFold(resourceTypeName, subscriptionsKey) && isTenantResource(parent) {
return SubscriptionResourceType
}
@@ -185,6 +164,15 @@ func (id *ResourceID) init(parent *ResourceID, resourceType ResourceType, name s
id.isChild = isChild
id.ResourceType = resourceType
id.Name = name
+ id.stringValue = id.Parent.String()
+ if id.isChild {
+ id.stringValue += "/" + id.ResourceType.lastType()
+ if id.Name != "" {
+ id.stringValue += "/" + id.Name
+ }
+ } else {
+ id.stringValue += fmt.Sprintf("/providers/%s/%s/%s", id.ResourceType.Namespace, id.ResourceType.Type, id.Name)
+ }
}
func appendNext(parent *ResourceID, parts []string, id string) (*ResourceID, error) {
@@ -194,12 +182,12 @@ func appendNext(parent *ResourceID, parts []string, id string) (*ResourceID, err
if len(parts) == 1 {
// subscriptions and resourceGroups are not valid ids without their names
- if strings.EqualFold(parts[0], subscriptionsKey) || strings.EqualFold(parts[0], resourceGroupsLowerKey) {
+ if strings.EqualFold(parts[0], subscriptionsKey) && isTenantResource(parent) || strings.EqualFold(parts[0], resourceGroupsLowerKey) && isSubscriptionResource(parent) {
return nil, fmt.Errorf("invalid resource ID: %s", id)
}
// resourceGroup must contain either child or provider resource type
- if parent.ResourceType.String() == ResourceGroupResourceType.String() {
+ if isResourceGroupResource(parent) {
return nil, fmt.Errorf("invalid resource ID: %s", id)
}
@@ -208,7 +196,7 @@ func appendNext(parent *ResourceID, parts []string, id string) (*ResourceID, err
if strings.EqualFold(parts[0], providersKey) && (len(parts) == 2 || strings.EqualFold(parts[2], providersKey)) {
// provider resource can only be on a tenant or a subscription parent
- if parent.ResourceType.String() != SubscriptionResourceType.String() && parent.ResourceType.String() != TenantResourceType.String() {
+ if !isSubscriptionResource(parent) && !isTenantResource(parent) {
return nil, fmt.Errorf("invalid resource ID: %s", id)
}
@@ -237,3 +225,18 @@ func splitStringAndOmitEmpty(v, sep string) []string {
return r
}
+
+// isTenantResource returns true if the resourceID represents a tenant resource. The condition is resource ID matched with TenantResourceType and has no parent.
+func isTenantResource(resourceID *ResourceID) bool {
+ return resourceID != nil && strings.EqualFold(resourceID.ResourceType.String(), TenantResourceType.String()) && resourceID.Parent == nil
+}
+
+// isSubscriptionResource returns true if the resourceID represents a subscription resource. The condition is resource ID matched with SubscriptionResourceType and its parent is a tenant resource.
+func isSubscriptionResource(resourceID *ResourceID) bool {
+ return resourceID != nil && strings.EqualFold(resourceID.ResourceType.String(), SubscriptionResourceType.String()) && isTenantResource(resourceID.Parent)
+}
+
+// isResourceGroupResource returns true if the resourceID represents a resource group resource. The condition is resource ID matched with ResourceGroupResourceType and its parent is a subscription resource.
+func isResourceGroupResource(resourceID *ResourceID) bool {
+ return resourceID != nil && strings.EqualFold(resourceID.ResourceType.String(), ResourceGroupResourceType.String()) && isSubscriptionResource(resourceID.Parent)
+}
diff --git a/vendor/github.com/Azure/azure-sdk-for-go/sdk/azcore/ci.yml b/vendor/github.com/Azure/azure-sdk-for-go/sdk/azcore/ci.yml
index 99348527b..b81b62103 100644
--- a/vendor/github.com/Azure/azure-sdk-for-go/sdk/azcore/ci.yml
+++ b/vendor/github.com/Azure/azure-sdk-for-go/sdk/azcore/ci.yml
@@ -27,3 +27,5 @@ extends:
template: /eng/pipelines/templates/jobs/archetype-sdk-client.yml
parameters:
ServiceDirectory: azcore
+ TriggeringPaths:
+ - /eng/
diff --git a/vendor/github.com/Azure/azure-sdk-for-go/sdk/azcore/internal/exported/request.go b/vendor/github.com/Azure/azure-sdk-for-go/sdk/azcore/internal/exported/request.go
index e3e2d4e58..9b3f5badb 100644
--- a/vendor/github.com/Azure/azure-sdk-for-go/sdk/azcore/internal/exported/request.go
+++ b/vendor/github.com/Azure/azure-sdk-for-go/sdk/azcore/internal/exported/request.go
@@ -71,7 +71,8 @@ func (ov opValues) get(value any) bool {
// NewRequestFromRequest creates a new policy.Request with an existing *http.Request
// Exported as runtime.NewRequestFromRequest().
func NewRequestFromRequest(req *http.Request) (*Request, error) {
- policyReq := &Request{req: req}
+ // populate values so that the same instance is propagated across policies
+ policyReq := &Request{req: req, values: opValues{}}
if req.Body != nil {
// we can avoid a body copy here if the underlying stream is already a
@@ -117,7 +118,8 @@ func NewRequest(ctx context.Context, httpMethod string, endpoint string) (*Reque
if !(req.URL.Scheme == "http" || req.URL.Scheme == "https") {
return nil, fmt.Errorf("unsupported protocol scheme %s", req.URL.Scheme)
}
- return &Request{req: req}, nil
+ // populate values so that the same instance is propagated across policies
+ return &Request{req: req, values: opValues{}}, nil
}
// Body returns the original body specified when the Request was created.
diff --git a/vendor/github.com/Azure/azure-sdk-for-go/sdk/azcore/internal/shared/constants.go b/vendor/github.com/Azure/azure-sdk-for-go/sdk/azcore/internal/shared/constants.go
index 85514db3b..8aebe5ce5 100644
--- a/vendor/github.com/Azure/azure-sdk-for-go/sdk/azcore/internal/shared/constants.go
+++ b/vendor/github.com/Azure/azure-sdk-for-go/sdk/azcore/internal/shared/constants.go
@@ -40,5 +40,5 @@ const (
Module = "azcore"
// Version is the semantic version (see http://semver.org) of this module.
- Version = "v1.18.0"
+ Version = "v1.19.1"
)
diff --git a/vendor/github.com/Azure/azure-sdk-for-go/sdk/azcore/policy/policy.go b/vendor/github.com/Azure/azure-sdk-for-go/sdk/azcore/policy/policy.go
index bb37a5efb..368a2199e 100644
--- a/vendor/github.com/Azure/azure-sdk-for-go/sdk/azcore/policy/policy.go
+++ b/vendor/github.com/Azure/azure-sdk-for-go/sdk/azcore/policy/policy.go
@@ -103,7 +103,7 @@ type RetryOptions struct {
// RetryDelay specifies the initial amount of delay to use before retrying an operation.
// The value is used only if the HTTP response does not contain a Retry-After header.
// The delay increases exponentially with each retry up to the maximum specified by MaxRetryDelay.
- // The default value is four seconds. A value less than zero means no delay between retries.
+ // The default value is 800 milliseconds. A value less than zero means no delay between retries.
RetryDelay time.Duration
// MaxRetryDelay specifies the maximum delay allowed before retrying an operation.
diff --git a/vendor/github.com/Azure/azure-sdk-for-go/sdk/azcore/runtime/policy_api_version.go b/vendor/github.com/Azure/azure-sdk-for-go/sdk/azcore/runtime/policy_api_version.go
index e5309aa6c..c3646feb5 100644
--- a/vendor/github.com/Azure/azure-sdk-for-go/sdk/azcore/runtime/policy_api_version.go
+++ b/vendor/github.com/Azure/azure-sdk-for-go/sdk/azcore/runtime/policy_api_version.go
@@ -16,9 +16,10 @@ import (
// APIVersionOptions contains options for API versions
type APIVersionOptions struct {
- // Location indicates where to set the version on a request, for example in a header or query param
+ // Location indicates where to set the version on a request, for example in a header or query param.
Location APIVersionLocation
- // Name is the name of the header or query parameter, for example "api-version"
+ // Name is the name of the header or query parameter, for example "api-version".
+ // For [APIVersionLocationPath] the value is not used.
Name string
}
@@ -30,6 +31,8 @@ const (
APIVersionLocationQueryParam = 0
// APIVersionLocationHeader indicates a header
APIVersionLocationHeader = 1
+ // APIVersionLocationPath indicates a path segment
+ APIVersionLocationPath = 2
)
// newAPIVersionPolicy constructs an APIVersionPolicy. If version is "", Do will be a no-op. If version
@@ -55,7 +58,10 @@ type apiVersionPolicy struct {
// Do sets the request's API version, if the policy is configured to do so, replacing any prior value.
func (a *apiVersionPolicy) Do(req *policy.Request) (*http.Response, error) {
- if a.version != "" {
+ // for API versions in the path, the client is responsible for
+ // setting the correct path segment with the version. so, if the
+ // location is path the policy is effectively a no-op.
+ if a.location != APIVersionLocationPath && a.version != "" {
if a.name == "" {
// user set ClientOptions.APIVersion but the client ctor didn't set PipelineOptions.APIVersionOptions
return nil, errors.New("this client doesn't support overriding its API version")
diff --git a/vendor/github.com/Azure/azure-sdk-for-go/sdk/azcore/runtime/policy_bearer_token.go b/vendor/github.com/Azure/azure-sdk-for-go/sdk/azcore/runtime/policy_bearer_token.go
index 1950a2e5b..547e5a327 100644
--- a/vendor/github.com/Azure/azure-sdk-for-go/sdk/azcore/runtime/policy_bearer_token.go
+++ b/vendor/github.com/Azure/azure-sdk-for-go/sdk/azcore/runtime/policy_bearer_token.go
@@ -97,7 +97,9 @@ func (b *BearerTokenPolicy) authenticateAndAuthorize(req *policy.Request) func(p
as := acquiringResourceState{p: b, req: req, tro: tro}
tk, err := b.mainResource.Get(as)
if err != nil {
- return err
+ // consider this error non-retriable because if it could be resolved by
+ // retrying authentication, the credential would have done so already
+ return errorinfo.NonRetriableError(err)
}
req.Raw().Header.Set(shared.HeaderAuthorization, shared.BearerTokenPrefix+tk.Token)
return nil
diff --git a/vendor/github.com/Azure/azure-sdk-for-go/sdk/azcore/runtime/poller.go b/vendor/github.com/Azure/azure-sdk-for-go/sdk/azcore/runtime/poller.go
index 4f90e4474..a89ae9b7b 100644
--- a/vendor/github.com/Azure/azure-sdk-for-go/sdk/azcore/runtime/poller.go
+++ b/vendor/github.com/Azure/azure-sdk-for-go/sdk/azcore/runtime/poller.go
@@ -91,7 +91,7 @@ func NewPoller[T any](resp *http.Response, pl exported.Pipeline, options *NewPol
// this is a back-stop in case the swagger is incorrect (i.e. missing one or more status codes for success).
// ideally the codegen should return an error if the initial response failed and not even create a poller.
if !poller.StatusCodeValid(resp) {
- return nil, errors.New("the operation failed or was cancelled")
+ return nil, exported.NewResponseError(resp)
}
// determine the polling method
diff --git a/vendor/github.com/Azure/azure-sdk-for-go/sdk/azidentity/CHANGELOG.md b/vendor/github.com/Azure/azure-sdk-for-go/sdk/azidentity/CHANGELOG.md
index f5bd8586b..ab63f9c03 100644
--- a/vendor/github.com/Azure/azure-sdk-for-go/sdk/azidentity/CHANGELOG.md
+++ b/vendor/github.com/Azure/azure-sdk-for-go/sdk/azidentity/CHANGELOG.md
@@ -1,5 +1,40 @@
# Release History
+## 1.12.0 (2025-09-16)
+
+### Features Added
+- Added `DefaultAzureCredentialOptions.RequireAzureTokenCredentials`. `NewDefaultAzureCredential` returns an
+ error when this option is true and the environment variable `AZURE_TOKEN_CREDENTIALS` has no value.
+
+### Other Changes
+- `AzureDeveloperCLICredential` no longer hangs when AZD_DEBUG is set
+- `GetToken` methods of `AzureCLICredential` and `AzureDeveloperCLICredential` return an error when
+ `TokenRequestOptions.Claims` has a value because these credentials can't acquire a token in that
+ case. The error messages describe the action required to get a token.
+
+## 1.11.0 (2025-08-05)
+
+### Other Changes
+- `DefaultAzureCredential` tries its next credential when a dev tool credential such as
+ `AzureCLICredential` returns an error
+
+## 1.11.0-beta.1 (2025-07-15)
+
+### Features Added
+- `DefaultAzureCredential` allows selecting one of its credential types by name via environment variable
+ `AZURE_TOKEN_CREDENTIALS`. It will use only the selected type at runtime. For example, set
+ `AZURE_TOKEN_CREDENTIALS=WorkloadIdentityCredential` to have `DefaultAzureCredential` use only
+ `WorkloadIdentityCredential`.
+
+### Other Changes
+- By default, `ManagedIdentityCredential` retries IMDS requests for a maximum of ~70 seconds as recommended
+ in IMDS documentation. In previous versions, it would stop retrying after ~54 seconds by default.
+
+## 1.10.1 (2025-06-10)
+
+### Bugs Fixed
+- `AzureCLICredential` and `AzureDeveloperCLICredential` could wait indefinitely for subprocess output
+
## 1.10.0 (2025-05-14)
### Features Added
diff --git a/vendor/github.com/Azure/azure-sdk-for-go/sdk/azidentity/TOKEN_CACHING.MD b/vendor/github.com/Azure/azure-sdk-for-go/sdk/azidentity/TOKEN_CACHING.MD
index 2bda7f2a7..da2094e36 100644
--- a/vendor/github.com/Azure/azure-sdk-for-go/sdk/azidentity/TOKEN_CACHING.MD
+++ b/vendor/github.com/Azure/azure-sdk-for-go/sdk/azidentity/TOKEN_CACHING.MD
@@ -27,6 +27,7 @@ Persistent caches are encrypted at rest using a mechanism that depends on the op
| Linux | kernel key retention service (keyctl) | Cache data is lost on system shutdown because kernel keys are stored in memory. Depending on kernel compile options, data may also be lost on logout, or storage may be impossible because the key retention service isn't available. |
| macOS | Keychain | Building requires cgo and native build tools. Keychain access requires a graphical session, so persistent caching isn't possible in a headless environment such as an SSH session (macOS as host). |
| Windows | Data Protection API (DPAPI) | No specific limitations. |
+
Persistent caching requires encryption. When the required encryption facility is unuseable, or the application is running on an unsupported OS, the persistent cache constructor returns an error. This doesn't mean that authentication is impossible, only that credentials can't persist authentication data and the application will need to reauthenticate the next time it runs. See the package documentation for examples showing how to configure persistent caching and access cached data for [users][user_example] and [service principals][sp_example].
### Credentials supporting token caching
diff --git a/vendor/github.com/Azure/azure-sdk-for-go/sdk/azidentity/TROUBLESHOOTING.md b/vendor/github.com/Azure/azure-sdk-for-go/sdk/azidentity/TROUBLESHOOTING.md
index 10a4009c3..838601d69 100644
--- a/vendor/github.com/Azure/azure-sdk-for-go/sdk/azidentity/TROUBLESHOOTING.md
+++ b/vendor/github.com/Azure/azure-sdk-for-go/sdk/azidentity/TROUBLESHOOTING.md
@@ -18,7 +18,6 @@ This troubleshooting guide covers failure investigation techniques, common error
- [Troubleshoot EnvironmentCredential authentication issues](#troubleshoot-environmentcredential-authentication-issues)
- [Troubleshoot ManagedIdentityCredential authentication issues](#troubleshoot-managedidentitycredential-authentication-issues)
- [Azure App Service and Azure Functions managed identity](#azure-app-service-and-azure-functions-managed-identity)
- - [Azure Kubernetes Service managed identity](#azure-kubernetes-service-managed-identity)
- [Azure Virtual Machine managed identity](#azure-virtual-machine-managed-identity)
- [Troubleshoot WorkloadIdentityCredential authentication issues](#troubleshoot-workloadidentitycredential-authentication-issues)
- [Get additional help](#get-additional-help)
@@ -86,6 +85,7 @@ azlog.SetEvents(azidentity.EventAuthentication)
|"DefaultAzureCredential failed to acquire a token"|No credential in the `DefaultAzureCredential` chain provided a token|
- [Enable logging](#enable-and-configure-logging) to get further diagnostic information.
- Consult the troubleshooting guide for underlying credential types for more information.
- [EnvironmentCredential](#troubleshoot-environmentcredential-authentication-issues)
- [ManagedIdentityCredential](#troubleshoot-managedidentitycredential-authentication-issues)
- [AzureCLICredential](#troubleshoot-azureclicredential-authentication-issues)
|
|Error from the client with a status code of 401 or 403|Authentication succeeded but the authorizing Azure service responded with a 401 (Unauthorized), or 403 (Forbidden) status code|- [Enable logging](#enable-and-configure-logging) to determine which credential in the chain returned the authenticating token.
- If an unexpected credential is returning a token, check application configuration such as environment variables.
- Ensure the correct role is assigned to the authenticated identity. For example, a service specific role rather than the subscription Owner role.
|
|"managed identity timed out"|`DefaultAzureCredential` sets a short timeout on its first managed identity authentication attempt to prevent very long timeouts during local development when no managed identity is available. That timeout causes this error in production when an application requests a token before the hosting environment is ready to provide one.|Use [ManagedIdentityCredential](https://pkg.go.dev/github.com/Azure/azure-sdk-for-go/sdk/azidentity#ManagedIdentityCredential) directly, at least in production. It doesn't set a timeout on its authentication attempts.|
+|invalid AZURE_TOKEN_CREDENTIALS value "..."|AZURE_TOKEN_CREDENTIALS has an unexpected value|Specify a valid value as described in [DefaultAzureCredential documentation](https://pkg.go.dev/github.com/Azure/azure-sdk-for-go/sdk/azidentity#DefaultAzureCredential)
## Troubleshoot EnvironmentCredential authentication issues
@@ -119,7 +119,6 @@ azlog.SetEvents(azidentity.EventAuthentication)
|---|---|---|
|Azure Virtual Machines and Scale Sets|[Configuration](https://learn.microsoft.com/entra/identity/managed-identities-azure-resources/qs-configure-portal-windows-vm)|[Troubleshooting](#azure-virtual-machine-managed-identity)|
|Azure App Service and Azure Functions|[Configuration](https://learn.microsoft.com/azure/app-service/overview-managed-identity)|[Troubleshooting](#azure-app-service-and-azure-functions-managed-identity)|
-|Azure Kubernetes Service|[Configuration](https://azure.github.io/aad-pod-identity/docs/)|[Troubleshooting](#azure-kubernetes-service-managed-identity)|
|Azure Arc|[Configuration](https://learn.microsoft.com/azure/azure-arc/servers/managed-identity-authentication)||
|Azure Service Fabric|[Configuration](https://learn.microsoft.com/azure/service-fabric/concepts-managed-identity)||
@@ -158,14 +157,6 @@ curl "$IDENTITY_ENDPOINT?resource=https://management.core.windows.net&api-versio
> This command's output will contain an access token and SHOULD NOT BE SHARED, to avoid compromising account security.
-### Azure Kubernetes Service managed identity
-
-#### Pod Identity
-
-| Error Message |Description| Mitigation |
-|---|---|---|
-|"no azure identity found for request clientID"|The application attempted to authenticate before an identity was assigned to its pod|Verify the pod is labeled correctly. This also occurs when a correctly labeled pod authenticates before the identity is ready. To prevent initialization races, configure NMI to set the Retry-After header in its responses as described in [Pod Identity documentation](https://azure.github.io/aad-pod-identity/docs/configure/feature_flags/#set-retry-after-header-in-nmi-response).
-
## Troubleshoot AzureCLICredential authentication issues
@@ -219,7 +210,7 @@ azd auth token --output json --scope https://management.core.windows.net/.defaul
| Error Message |Description| Mitigation |
|---|---|---|
-|no client ID/tenant ID/token file specified|Incomplete configuration|In most cases these values are provided via environment variables set by Azure Workload Identity.- If your application runs on Azure Kubernetes Servide (AKS) or a cluster that has deployed the Azure Workload Identity admission webhook, check pod labels and service account configuration. See the [AKS documentation](https://learn.microsoft.com/azure/aks/workload-identity-deploy-cluster#disable-workload-identity) and [Azure Workload Identity troubleshooting guide](https://azure.github.io/azure-workload-identity/docs/troubleshooting.html) for more details.
- If your application isn't running on AKS or your cluster hasn't deployed the Workload Identity admission webhook, set these values in `WorkloadIdentityCredentialOptions`
+|no client ID/tenant ID/token file specified|Incomplete configuration|In most cases these values are provided via environment variables set by Azure Workload Identity.
- If your application runs on Azure Kubernetes Service (AKS) or a cluster that has deployed the Azure Workload Identity admission webhook, check pod labels and service account configuration. See the [AKS documentation](https://learn.microsoft.com/azure/aks/workload-identity-deploy-cluster#disable-workload-identity) and [Azure Workload Identity troubleshooting guide](https://azure.github.io/azure-workload-identity/docs/troubleshooting.html) for more details.
- If your application isn't running on AKS or your cluster hasn't deployed the Workload Identity admission webhook, set these values in `WorkloadIdentityCredentialOptions`
## Troubleshoot AzurePipelinesCredential authentication issues
diff --git a/vendor/github.com/Azure/azure-sdk-for-go/sdk/azidentity/assets.json b/vendor/github.com/Azure/azure-sdk-for-go/sdk/azidentity/assets.json
index 4118f99ef..1646ff911 100644
--- a/vendor/github.com/Azure/azure-sdk-for-go/sdk/azidentity/assets.json
+++ b/vendor/github.com/Azure/azure-sdk-for-go/sdk/azidentity/assets.json
@@ -2,5 +2,5 @@
"AssetsRepo": "Azure/azure-sdk-assets",
"AssetsRepoPrefixPath": "go",
"TagPrefix": "go/azidentity",
- "Tag": "go/azidentity_191110b0dd"
+ "Tag": "go/azidentity_530ea4279b"
}
diff --git a/vendor/github.com/Azure/azure-sdk-for-go/sdk/azidentity/azure_cli_credential.go b/vendor/github.com/Azure/azure-sdk-for-go/sdk/azidentity/azure_cli_credential.go
index 36e359a09..6944152c9 100644
--- a/vendor/github.com/Azure/azure-sdk-for-go/sdk/azidentity/azure_cli_credential.go
+++ b/vendor/github.com/Azure/azure-sdk-for-go/sdk/azidentity/azure_cli_credential.go
@@ -7,14 +7,11 @@
package azidentity
import (
- "bytes"
"context"
+ "encoding/base64"
"encoding/json"
"errors"
"fmt"
- "os"
- "os/exec"
- "runtime"
"strings"
"sync"
"time"
@@ -26,8 +23,6 @@ import (
const credNameAzureCLI = "AzureCLICredential"
-type azTokenProvider func(ctx context.Context, scopes []string, tenant, subscription string) ([]byte, error)
-
// AzureCLICredentialOptions contains optional parameters for AzureCLICredential.
type AzureCLICredentialOptions struct {
// AdditionallyAllowedTenants specifies tenants to which the credential may authenticate, in addition to
@@ -45,15 +40,8 @@ type AzureCLICredentialOptions struct {
// inDefaultChain is true when the credential is part of DefaultAzureCredential
inDefaultChain bool
- // tokenProvider is used by tests to fake invoking az
- tokenProvider azTokenProvider
-}
-
-// init returns an instance of AzureCLICredentialOptions initialized with default values.
-func (o *AzureCLICredentialOptions) init() {
- if o.tokenProvider == nil {
- o.tokenProvider = defaultAzTokenProvider
- }
+ // exec is used by tests to fake invoking az
+ exec executor
}
// AzureCLICredential authenticates as the identity logged in to the Azure CLI.
@@ -80,7 +68,9 @@ func NewAzureCLICredential(options *AzureCLICredentialOptions) (*AzureCLICredent
if cp.TenantID != "" && !validTenantID(cp.TenantID) {
return nil, errInvalidTenantID
}
- cp.init()
+ if cp.exec == nil {
+ cp.exec = shellExec
+ }
cp.AdditionallyAllowedTenants = resolveAdditionalTenants(cp.AdditionallyAllowedTenants)
return &AzureCLICredential{mu: &sync.Mutex{}, opts: cp}, nil
}
@@ -99,14 +89,37 @@ func (c *AzureCLICredential) GetToken(ctx context.Context, opts policy.TokenRequ
if err != nil {
return at, err
}
+ // pass the CLI a Microsoft Entra ID v1 resource because we don't know which CLI version is installed and older ones don't support v2 scopes
+ resource := strings.TrimSuffix(opts.Scopes[0], defaultSuffix)
+ command := "az account get-access-token -o json --resource " + resource
+ tenantArg := ""
+ if tenant != "" {
+ tenantArg = " --tenant " + tenant
+ command += tenantArg
+ }
+ if c.opts.Subscription != "" {
+ // subscription needs quotes because it may contain spaces
+ command += ` --subscription "` + c.opts.Subscription + `"`
+ }
+ if opts.Claims != "" {
+ encoded := base64.StdEncoding.EncodeToString([]byte(opts.Claims))
+ return at, fmt.Errorf(
+ "%s.GetToken(): Azure CLI requires multifactor authentication or additional claims. Run this command then retry the operation: az login%s --claims-challenge %s",
+ credNameAzureCLI,
+ tenantArg,
+ encoded,
+ )
+ }
+
c.mu.Lock()
defer c.mu.Unlock()
- b, err := c.opts.tokenProvider(ctx, opts.Scopes, tenant, c.opts.Subscription)
+
+ b, err := c.opts.exec(ctx, credNameAzureCLI, command)
if err == nil {
at, err = c.createAccessToken(b)
}
if err != nil {
- err = unavailableIfInChain(err, c.opts.inDefaultChain)
+ err = unavailableIfInDAC(err, c.opts.inDefaultChain)
return at, err
}
msg := fmt.Sprintf("%s.GetToken() acquired a token for scope %q", credNameAzureCLI, strings.Join(opts.Scopes, ", "))
@@ -114,57 +127,6 @@ func (c *AzureCLICredential) GetToken(ctx context.Context, opts policy.TokenRequ
return at, nil
}
-// defaultAzTokenProvider invokes the Azure CLI to acquire a token. It assumes
-// callers have verified that all string arguments are safe to pass to the CLI.
-var defaultAzTokenProvider azTokenProvider = func(ctx context.Context, scopes []string, tenantID, subscription string) ([]byte, error) {
- // pass the CLI a Microsoft Entra ID v1 resource because we don't know which CLI version is installed and older ones don't support v2 scopes
- resource := strings.TrimSuffix(scopes[0], defaultSuffix)
- // set a default timeout for this authentication iff the application hasn't done so already
- var cancel context.CancelFunc
- if _, hasDeadline := ctx.Deadline(); !hasDeadline {
- ctx, cancel = context.WithTimeout(ctx, cliTimeout)
- defer cancel()
- }
- commandLine := "az account get-access-token -o json --resource " + resource
- if tenantID != "" {
- commandLine += " --tenant " + tenantID
- }
- if subscription != "" {
- // subscription needs quotes because it may contain spaces
- commandLine += ` --subscription "` + subscription + `"`
- }
- var cliCmd *exec.Cmd
- if runtime.GOOS == "windows" {
- dir := os.Getenv("SYSTEMROOT")
- if dir == "" {
- return nil, newCredentialUnavailableError(credNameAzureCLI, "environment variable 'SYSTEMROOT' has no value")
- }
- cliCmd = exec.CommandContext(ctx, "cmd.exe", "/c", commandLine)
- cliCmd.Dir = dir
- } else {
- cliCmd = exec.CommandContext(ctx, "/bin/sh", "-c", commandLine)
- cliCmd.Dir = "/bin"
- }
- cliCmd.Env = os.Environ()
- var stderr bytes.Buffer
- cliCmd.Stderr = &stderr
-
- output, err := cliCmd.Output()
- if err != nil {
- msg := stderr.String()
- var exErr *exec.ExitError
- if errors.As(err, &exErr) && exErr.ExitCode() == 127 || strings.HasPrefix(msg, "'az' is not recognized") {
- msg = "Azure CLI not found on path"
- }
- if msg == "" {
- msg = err.Error()
- }
- return nil, newCredentialUnavailableError(credNameAzureCLI, msg)
- }
-
- return output, nil
-}
-
func (c *AzureCLICredential) createAccessToken(tk []byte) (azcore.AccessToken, error) {
t := struct {
AccessToken string `json:"accessToken"`
diff --git a/vendor/github.com/Azure/azure-sdk-for-go/sdk/azidentity/azure_developer_cli_credential.go b/vendor/github.com/Azure/azure-sdk-for-go/sdk/azidentity/azure_developer_cli_credential.go
index 46d0b5519..f97bf95df 100644
--- a/vendor/github.com/Azure/azure-sdk-for-go/sdk/azidentity/azure_developer_cli_credential.go
+++ b/vendor/github.com/Azure/azure-sdk-for-go/sdk/azidentity/azure_developer_cli_credential.go
@@ -7,14 +7,11 @@
package azidentity
import (
- "bytes"
"context"
+ "encoding/base64"
"encoding/json"
"errors"
"fmt"
- "os"
- "os/exec"
- "runtime"
"strings"
"sync"
"time"
@@ -24,9 +21,10 @@ import (
"github.com/Azure/azure-sdk-for-go/sdk/internal/log"
)
-const credNameAzureDeveloperCLI = "AzureDeveloperCLICredential"
-
-type azdTokenProvider func(ctx context.Context, scopes []string, tenant string) ([]byte, error)
+const (
+ credNameAzureDeveloperCLI = "AzureDeveloperCLICredential"
+ mfaRequired = "Azure Developer CLI requires multifactor authentication or additional claims"
+)
// AzureDeveloperCLICredentialOptions contains optional parameters for AzureDeveloperCLICredential.
type AzureDeveloperCLICredentialOptions struct {
@@ -41,8 +39,8 @@ type AzureDeveloperCLICredentialOptions struct {
// inDefaultChain is true when the credential is part of DefaultAzureCredential
inDefaultChain bool
- // tokenProvider is used by tests to fake invoking azd
- tokenProvider azdTokenProvider
+ // exec is used by tests to fake invoking azd
+ exec executor
}
// AzureDeveloperCLICredential authenticates as the identity logged in to the [Azure Developer CLI].
@@ -62,8 +60,8 @@ func NewAzureDeveloperCLICredential(options *AzureDeveloperCLICredentialOptions)
if cp.TenantID != "" && !validTenantID(cp.TenantID) {
return nil, errInvalidTenantID
}
- if cp.tokenProvider == nil {
- cp.tokenProvider = defaultAzdTokenProvider
+ if cp.exec == nil {
+ cp.exec = shellExec
}
return &AzureDeveloperCLICredential{mu: &sync.Mutex{}, opts: cp}, nil
}
@@ -75,23 +73,52 @@ func (c *AzureDeveloperCLICredential) GetToken(ctx context.Context, opts policy.
if len(opts.Scopes) == 0 {
return at, errors.New(credNameAzureDeveloperCLI + ": GetToken() requires at least one scope")
}
+ command := "azd auth token -o json --no-prompt"
for _, scope := range opts.Scopes {
if !validScope(scope) {
return at, fmt.Errorf("%s.GetToken(): invalid scope %q", credNameAzureDeveloperCLI, scope)
}
+ command += " --scope " + scope
}
tenant, err := resolveTenant(c.opts.TenantID, opts.TenantID, credNameAzureDeveloperCLI, c.opts.AdditionallyAllowedTenants)
if err != nil {
return at, err
}
+ if tenant != "" {
+ command += " --tenant-id " + tenant
+ }
+ commandNoClaims := command
+ if opts.Claims != "" {
+ encoded := base64.StdEncoding.EncodeToString([]byte(opts.Claims))
+ command += " --claims " + encoded
+ }
+
c.mu.Lock()
defer c.mu.Unlock()
- b, err := c.opts.tokenProvider(ctx, opts.Scopes, tenant)
+
+ b, err := c.opts.exec(ctx, credNameAzureDeveloperCLI, command)
if err == nil {
at, err = c.createAccessToken(b)
}
if err != nil {
- err = unavailableIfInChain(err, c.opts.inDefaultChain)
+ msg := err.Error()
+ switch {
+ case strings.Contains(msg, "unknown flag: --claims"):
+ err = newAuthenticationFailedError(
+ credNameAzureDeveloperCLI,
+ mfaRequired+", however the installed version doesn't support this. Upgrade to version 1.18.1 or later",
+ nil,
+ )
+ case opts.Claims != "":
+ err = newAuthenticationFailedError(
+ credNameAzureDeveloperCLI,
+ mfaRequired+". Run this command then retry the operation: "+commandNoClaims,
+ nil,
+ )
+ case strings.Contains(msg, "azd auth login"):
+ err = newCredentialUnavailableError(credNameAzureDeveloperCLI, `please run "azd auth login" from a command prompt to authenticate before using this credential`)
+ }
+ err = unavailableIfInDAC(err, c.opts.inDefaultChain)
return at, err
}
msg := fmt.Sprintf("%s.GetToken() acquired a token for scope %q", credNameAzureDeveloperCLI, strings.Join(opts.Scopes, ", "))
@@ -99,54 +126,6 @@ func (c *AzureDeveloperCLICredential) GetToken(ctx context.Context, opts policy.
return at, nil
}
-// defaultAzTokenProvider invokes the Azure Developer CLI to acquire a token. It assumes
-// callers have verified that all string arguments are safe to pass to the CLI.
-var defaultAzdTokenProvider azdTokenProvider = func(ctx context.Context, scopes []string, tenant string) ([]byte, error) {
- // set a default timeout for this authentication iff the application hasn't done so already
- var cancel context.CancelFunc
- if _, hasDeadline := ctx.Deadline(); !hasDeadline {
- ctx, cancel = context.WithTimeout(ctx, cliTimeout)
- defer cancel()
- }
- commandLine := "azd auth token -o json"
- if tenant != "" {
- commandLine += " --tenant-id " + tenant
- }
- for _, scope := range scopes {
- commandLine += " --scope " + scope
- }
- var cliCmd *exec.Cmd
- if runtime.GOOS == "windows" {
- dir := os.Getenv("SYSTEMROOT")
- if dir == "" {
- return nil, newCredentialUnavailableError(credNameAzureDeveloperCLI, "environment variable 'SYSTEMROOT' has no value")
- }
- cliCmd = exec.CommandContext(ctx, "cmd.exe", "/c", commandLine)
- cliCmd.Dir = dir
- } else {
- cliCmd = exec.CommandContext(ctx, "/bin/sh", "-c", commandLine)
- cliCmd.Dir = "/bin"
- }
- cliCmd.Env = os.Environ()
- var stderr bytes.Buffer
- cliCmd.Stderr = &stderr
- output, err := cliCmd.Output()
- if err != nil {
- msg := stderr.String()
- var exErr *exec.ExitError
- if errors.As(err, &exErr) && exErr.ExitCode() == 127 || strings.HasPrefix(msg, "'azd' is not recognized") {
- msg = "Azure Developer CLI not found on path"
- } else if strings.Contains(msg, "azd auth login") {
- msg = `please run "azd auth login" from a command prompt to authenticate before using this credential`
- }
- if msg == "" {
- msg = err.Error()
- }
- return nil, newCredentialUnavailableError(credNameAzureDeveloperCLI, msg)
- }
- return output, nil
-}
-
func (c *AzureDeveloperCLICredential) createAccessToken(tk []byte) (azcore.AccessToken, error) {
t := struct {
AccessToken string `json:"token"`
diff --git a/vendor/github.com/Azure/azure-sdk-for-go/sdk/azidentity/ci.yml b/vendor/github.com/Azure/azure-sdk-for-go/sdk/azidentity/ci.yml
index c3af0cdc2..51dd97939 100644
--- a/vendor/github.com/Azure/azure-sdk-for-go/sdk/azidentity/ci.yml
+++ b/vendor/github.com/Azure/azure-sdk-for-go/sdk/azidentity/ci.yml
@@ -41,6 +41,3 @@ extends:
GenerateVMJobs: true
Path: sdk/azidentity/managed-identity-matrix.json
Selection: sparse
- MatrixReplace:
- - Pool=.*LINUXPOOL.*/azsdk-pool-mms-ubuntu-2204-identitymsi
- - OSVmImage=.*LINUXNEXTVMIMAGE.*/azsdk-pool-mms-ubuntu-2204-1espt
diff --git a/vendor/github.com/Azure/azure-sdk-for-go/sdk/azidentity/default_azure_credential.go b/vendor/github.com/Azure/azure-sdk-for-go/sdk/azidentity/default_azure_credential.go
index f2a31ee6a..c041a52db 100644
--- a/vendor/github.com/Azure/azure-sdk-for-go/sdk/azidentity/default_azure_credential.go
+++ b/vendor/github.com/Azure/azure-sdk-for-go/sdk/azidentity/default_azure_credential.go
@@ -19,6 +19,15 @@ import (
const azureTokenCredentials = "AZURE_TOKEN_CREDENTIALS"
+// bit flags NewDefaultAzureCredential uses to parse AZURE_TOKEN_CREDENTIALS
+const (
+ env = uint8(1) << iota
+ workloadIdentity
+ managedIdentity
+ az
+ azd
+)
+
// DefaultAzureCredentialOptions contains optional parameters for DefaultAzureCredential.
// These options may not apply to all credentials in the chain.
type DefaultAzureCredentialOptions struct {
@@ -39,6 +48,10 @@ type DefaultAzureCredentialOptions struct {
// the application responsible for ensuring the configured authority is valid and trustworthy.
DisableInstanceDiscovery bool
+ // RequireAzureTokenCredentials determines whether NewDefaultAzureCredential returns an error when the environment
+ // variable AZURE_TOKEN_CREDENTIALS has no value.
+ RequireAzureTokenCredentials bool
+
// TenantID sets the default tenant for authentication via the Azure CLI, Azure Developer CLI, and workload identity.
TenantID string
}
@@ -63,6 +76,20 @@ type DefaultAzureCredentialOptions struct {
// Once a credential has successfully authenticated, DefaultAzureCredential will use that credential for
// every subsequent authentication.
//
+// # Selecting credentials
+//
+// Set environment variable AZURE_TOKEN_CREDENTIALS to select a subset of the credential chain described above.
+// DefaultAzureCredential will try only the specified credential(s), but its other behavior remains the same.
+// Valid values for AZURE_TOKEN_CREDENTIALS are the name of any single type in the above chain, for example
+// "EnvironmentCredential" or "AzureCLICredential", and these special values:
+//
+// - "dev": try [AzureCLICredential] and [AzureDeveloperCLICredential], in that order
+// - "prod": try [EnvironmentCredential], [WorkloadIdentityCredential], and [ManagedIdentityCredential], in that order
+//
+// [DefaultAzureCredentialOptions].RequireAzureTokenCredentials controls whether AZURE_TOKEN_CREDENTIALS must be set.
+// NewDefaultAzureCredential returns an error when RequireAzureTokenCredentials is true and AZURE_TOKEN_CREDENTIALS
+// has no value.
+//
// [DefaultAzureCredential overview]: https://aka.ms/azsdk/go/identity/credential-chains#defaultazurecredential-overview
type DefaultAzureCredential struct {
chain *ChainedTokenCredential
@@ -70,34 +97,46 @@ type DefaultAzureCredential struct {
// NewDefaultAzureCredential creates a DefaultAzureCredential. Pass nil for options to accept defaults.
func NewDefaultAzureCredential(options *DefaultAzureCredentialOptions) (*DefaultAzureCredential, error) {
+ if options == nil {
+ options = &DefaultAzureCredentialOptions{}
+ }
+
var (
- creds []azcore.TokenCredential
- errorMessages []string
- includeDev, includeProd = true, true
+ creds []azcore.TokenCredential
+ errorMessages []string
+ selected = env | workloadIdentity | managedIdentity | az | azd
)
- if c, ok := os.LookupEnv(azureTokenCredentials); ok {
- switch c {
- case "dev":
- includeProd = false
- case "prod":
- includeDev = false
+ if atc, ok := os.LookupEnv(azureTokenCredentials); ok {
+ switch {
+ case atc == "dev":
+ selected = az | azd
+ case atc == "prod":
+ selected = env | workloadIdentity | managedIdentity
+ case strings.EqualFold(atc, credNameEnvironment):
+ selected = env
+ case strings.EqualFold(atc, credNameWorkloadIdentity):
+ selected = workloadIdentity
+ case strings.EqualFold(atc, credNameManagedIdentity):
+ selected = managedIdentity
+ case strings.EqualFold(atc, credNameAzureCLI):
+ selected = az
+ case strings.EqualFold(atc, credNameAzureDeveloperCLI):
+ selected = azd
default:
- return nil, fmt.Errorf(`invalid %s value %q. Valid values are "dev" and "prod"`, azureTokenCredentials, c)
+ return nil, fmt.Errorf(`invalid %s value %q. Valid values are "dev", "prod", or the name of any credential type in the default chain. See https://aka.ms/azsdk/go/identity/docs#DefaultAzureCredential for more information`, azureTokenCredentials, atc)
}
+ } else if options.RequireAzureTokenCredentials {
+ return nil, fmt.Errorf("%s must be set when RequireAzureTokenCredentials is true. See https://aka.ms/azsdk/go/identity/docs#DefaultAzureCredential for more information", azureTokenCredentials)
}
- if options == nil {
- options = &DefaultAzureCredentialOptions{}
- }
additionalTenants := options.AdditionallyAllowedTenants
if len(additionalTenants) == 0 {
if tenants := os.Getenv(azureAdditionallyAllowedTenants); tenants != "" {
additionalTenants = strings.Split(tenants, ";")
}
}
-
- if includeProd {
+ if selected&env != 0 {
envCred, err := NewEnvironmentCredential(&EnvironmentCredentialOptions{
ClientOptions: options.ClientOptions,
DisableInstanceDiscovery: options.DisableInstanceDiscovery,
@@ -107,9 +146,10 @@ func NewDefaultAzureCredential(options *DefaultAzureCredentialOptions) (*Default
creds = append(creds, envCred)
} else {
errorMessages = append(errorMessages, "EnvironmentCredential: "+err.Error())
- creds = append(creds, &defaultCredentialErrorReporter{credType: "EnvironmentCredential", err: err})
+ creds = append(creds, &defaultCredentialErrorReporter{credType: credNameEnvironment, err: err})
}
-
+ }
+ if selected&workloadIdentity != 0 {
wic, err := NewWorkloadIdentityCredential(&WorkloadIdentityCredentialOptions{
AdditionallyAllowedTenants: additionalTenants,
ClientOptions: options.ClientOptions,
@@ -122,7 +162,8 @@ func NewDefaultAzureCredential(options *DefaultAzureCredentialOptions) (*Default
errorMessages = append(errorMessages, credNameWorkloadIdentity+": "+err.Error())
creds = append(creds, &defaultCredentialErrorReporter{credType: credNameWorkloadIdentity, err: err})
}
-
+ }
+ if selected&managedIdentity != 0 {
o := &ManagedIdentityCredentialOptions{ClientOptions: options.ClientOptions, dac: true}
if ID, ok := os.LookupEnv(azureClientID); ok {
o.ID = ClientID(ID)
@@ -135,18 +176,24 @@ func NewDefaultAzureCredential(options *DefaultAzureCredentialOptions) (*Default
creds = append(creds, &defaultCredentialErrorReporter{credType: credNameManagedIdentity, err: err})
}
}
- if includeDev {
- azCred, err := NewAzureCLICredential(&AzureCLICredentialOptions{AdditionallyAllowedTenants: additionalTenants, TenantID: options.TenantID})
+ if selected&az != 0 {
+ azCred, err := NewAzureCLICredential(&AzureCLICredentialOptions{
+ AdditionallyAllowedTenants: additionalTenants,
+ TenantID: options.TenantID,
+ inDefaultChain: true,
+ })
if err == nil {
creds = append(creds, azCred)
} else {
errorMessages = append(errorMessages, credNameAzureCLI+": "+err.Error())
creds = append(creds, &defaultCredentialErrorReporter{credType: credNameAzureCLI, err: err})
}
-
+ }
+ if selected&azd != 0 {
azdCred, err := NewAzureDeveloperCLICredential(&AzureDeveloperCLICredentialOptions{
AdditionallyAllowedTenants: additionalTenants,
TenantID: options.TenantID,
+ inDefaultChain: true,
})
if err == nil {
creds = append(creds, azdCred)
diff --git a/vendor/github.com/Azure/azure-sdk-for-go/sdk/azidentity/developer_credential_util.go b/vendor/github.com/Azure/azure-sdk-for-go/sdk/azidentity/developer_credential_util.go
index be963d3a2..14f8a0312 100644
--- a/vendor/github.com/Azure/azure-sdk-for-go/sdk/azidentity/developer_credential_util.go
+++ b/vendor/github.com/Azure/azure-sdk-for-go/sdk/azidentity/developer_credential_util.go
@@ -7,22 +7,73 @@
package azidentity
import (
+ "bytes"
+ "context"
"errors"
+ "os"
+ "os/exec"
+ "runtime"
+ "strings"
"time"
)
// cliTimeout is the default timeout for authentication attempts via CLI tools
const cliTimeout = 10 * time.Second
-// unavailableIfInChain returns err or, if the credential was invoked by DefaultAzureCredential, a
+// executor runs a command and returns its output or an error
+type executor func(ctx context.Context, credName, command string) ([]byte, error)
+
+var shellExec = func(ctx context.Context, credName, command string) ([]byte, error) {
+ // set a default timeout for this authentication iff the caller hasn't done so already
+ var cancel context.CancelFunc
+ if _, hasDeadline := ctx.Deadline(); !hasDeadline {
+ ctx, cancel = context.WithTimeout(ctx, cliTimeout)
+ defer cancel()
+ }
+ var cmd *exec.Cmd
+ if runtime.GOOS == "windows" {
+ dir := os.Getenv("SYSTEMROOT")
+ if dir == "" {
+ return nil, newCredentialUnavailableError(credName, `environment variable "SYSTEMROOT" has no value`)
+ }
+ cmd = exec.CommandContext(ctx, "cmd.exe", "/c", command)
+ cmd.Dir = dir
+ } else {
+ cmd = exec.CommandContext(ctx, "/bin/sh", "-c", command)
+ cmd.Dir = "/bin"
+ }
+ cmd.Env = os.Environ()
+ stderr := bytes.Buffer{}
+ cmd.Stderr = &stderr
+ cmd.WaitDelay = 100 * time.Millisecond
+
+ stdout, err := cmd.Output()
+ if errors.Is(err, exec.ErrWaitDelay) && len(stdout) > 0 {
+ // The child process wrote to stdout and exited without closing it.
+ // Swallow this error and return stdout because it may contain a token.
+ return stdout, nil
+ }
+ if err != nil {
+ msg := stderr.String()
+ var exErr *exec.ExitError
+ if errors.As(err, &exErr) && exErr.ExitCode() == 127 || strings.Contains(msg, "' is not recognized") {
+ return nil, newCredentialUnavailableError(credName, "CLI executable not found on path")
+ }
+ if msg == "" {
+ msg = err.Error()
+ }
+ return nil, newAuthenticationFailedError(credName, msg, nil)
+ }
+
+ return stdout, nil
+}
+
+// unavailableIfInDAC returns err or, if the credential was invoked by DefaultAzureCredential, a
// credentialUnavailableError having the same message. This ensures DefaultAzureCredential will try
// the next credential in its chain (another developer credential).
-func unavailableIfInChain(err error, inDefaultChain bool) error {
- if err != nil && inDefaultChain {
- var unavailableErr credentialUnavailable
- if !errors.As(err, &unavailableErr) {
- err = newCredentialUnavailableError(credNameAzureDeveloperCLI, err.Error())
- }
+func unavailableIfInDAC(err error, inDefaultChain bool) error {
+ if err != nil && inDefaultChain && !errors.As(err, new(credentialUnavailable)) {
+ err = NewCredentialUnavailableError(err.Error())
}
return err
}
diff --git a/vendor/github.com/Azure/azure-sdk-for-go/sdk/azidentity/environment_credential.go b/vendor/github.com/Azure/azure-sdk-for-go/sdk/azidentity/environment_credential.go
index 9b5e17dcd..f04d40ea4 100644
--- a/vendor/github.com/Azure/azure-sdk-for-go/sdk/azidentity/environment_credential.go
+++ b/vendor/github.com/Azure/azure-sdk-for-go/sdk/azidentity/environment_credential.go
@@ -18,7 +18,10 @@ import (
"github.com/Azure/azure-sdk-for-go/sdk/internal/log"
)
-const envVarSendCertChain = "AZURE_CLIENT_SEND_CERTIFICATE_CHAIN"
+const (
+ credNameEnvironment = "EnvironmentCredential"
+ envVarSendCertChain = "AZURE_CLIENT_SEND_CERTIFICATE_CHAIN"
+)
// EnvironmentCredentialOptions contains optional parameters for EnvironmentCredential
type EnvironmentCredentialOptions struct {
diff --git a/vendor/github.com/Azure/azure-sdk-for-go/sdk/azidentity/managed-identity-matrix.json b/vendor/github.com/Azure/azure-sdk-for-go/sdk/azidentity/managed-identity-matrix.json
index edd56f9d5..063325c69 100644
--- a/vendor/github.com/Azure/azure-sdk-for-go/sdk/azidentity/managed-identity-matrix.json
+++ b/vendor/github.com/Azure/azure-sdk-for-go/sdk/azidentity/managed-identity-matrix.json
@@ -4,14 +4,13 @@
"Agent": {
"msi_image": {
"ArmTemplateParameters": "@{deployResources = $true}",
- "OSVmImage": "env:LINUXNEXTVMIMAGE",
+ "OSVmImage": "env:LINUXVMIMAGE",
"Pool": "env:LINUXPOOL"
}
},
"GoVersion": [
"env:GO_VERSION_PREVIOUS"
- ],
- "IDENTITY_IMDS_AVAILABLE": "1"
+ ]
}
]
-}
+}
\ No newline at end of file
diff --git a/vendor/github.com/Azure/azure-sdk-for-go/sdk/azidentity/managed_identity_client.go b/vendor/github.com/Azure/azure-sdk-for-go/sdk/azidentity/managed_identity_client.go
index b3a0f8588..0735d1fcb 100644
--- a/vendor/github.com/Azure/azure-sdk-for-go/sdk/azidentity/managed_identity_client.go
+++ b/vendor/github.com/Azure/azure-sdk-for-go/sdk/azidentity/managed_identity_client.go
@@ -54,10 +54,10 @@ type managedIdentityClient struct {
// setIMDSRetryOptionDefaults sets zero-valued fields to default values appropriate for IMDS
func setIMDSRetryOptionDefaults(o *policy.RetryOptions) {
if o.MaxRetries == 0 {
- o.MaxRetries = 5
+ o.MaxRetries = 6
}
if o.MaxRetryDelay == 0 {
- o.MaxRetryDelay = 1 * time.Minute
+ o.MaxRetryDelay = 25 * time.Second
}
if o.RetryDelay == 0 {
o.RetryDelay = 2 * time.Second
diff --git a/vendor/github.com/Azure/azure-sdk-for-go/sdk/azidentity/test-resources-post.ps1 b/vendor/github.com/Azure/azure-sdk-for-go/sdk/azidentity/test-resources-post.ps1
index 67f97fbb2..c5634cd21 100644
--- a/vendor/github.com/Azure/azure-sdk-for-go/sdk/azidentity/test-resources-post.ps1
+++ b/vendor/github.com/Azure/azure-sdk-for-go/sdk/azidentity/test-resources-post.ps1
@@ -41,7 +41,7 @@ if ($CI) {
az account set --subscription $SubscriptionId
}
-Write-Host "Building container"
+Write-Host "##[group]Building container"
$image = "$($DeploymentOutputs['AZIDENTITY_ACR_LOGIN_SERVER'])/azidentity-managed-id-test"
Set-Content -Path "$PSScriptRoot/Dockerfile" -Value @"
FROM mcr.microsoft.com/oss/go/microsoft/golang:latest AS builder
@@ -62,11 +62,34 @@ CMD ["./managed-id-test"]
docker build -t $image "$PSScriptRoot"
az acr login -n $DeploymentOutputs['AZIDENTITY_ACR_NAME']
docker push $image
+Write-Host "##[endgroup]"
$rg = $DeploymentOutputs['AZIDENTITY_RESOURCE_GROUP']
+Write-Host "##[group]Deploying to VM"
+# az will return 0 when the script fails on the VM, so the script prints a UUID to indicate all commands succeeded
+$uuid = [guid]::NewGuid().ToString()
+$vmScript = @"
+az acr login -n $($DeploymentOutputs['AZIDENTITY_ACR_NAME']) && \
+sudo docker run \
+-e AZIDENTITY_STORAGE_NAME=$($DeploymentOutputs['AZIDENTITY_STORAGE_NAME']) \
+-e AZIDENTITY_STORAGE_NAME_USER_ASSIGNED=$($DeploymentOutputs['AZIDENTITY_STORAGE_NAME_USER_ASSIGNED']) \
+-e AZIDENTITY_USER_ASSIGNED_IDENTITY=$($DeploymentOutputs['AZIDENTITY_USER_ASSIGNED_IDENTITY']) \
+-e AZIDENTITY_USER_ASSIGNED_IDENTITY_CLIENT_ID=$($DeploymentOutputs['AZIDENTITY_USER_ASSIGNED_IDENTITY_CLIENT_ID']) \
+-e AZIDENTITY_USER_ASSIGNED_IDENTITY_OBJECT_ID=$($DeploymentOutputs['AZIDENTITY_USER_ASSIGNED_IDENTITY_OBJECT_ID']) \
+-p 80:8080 -d \
+$image && \
+/usr/bin/echo $uuid
+"@
+$output = az vm run-command invoke -g $rg -n $DeploymentOutputs['AZIDENTITY_VM_NAME'] --command-id RunShellScript --scripts "$vmScript" | Out-String
+Write-Host $output
+if (-not $output.Contains($uuid)) {
+ throw "couldn't start container on VM"
+}
+Write-Host "##[endgroup]"
+
# ACI is easier to provision here than in the bicep file because the image isn't available before now
-Write-Host "Deploying Azure Container Instance"
+Write-Host "##[group]Deploying Azure Container Instance"
$aciName = "azidentity-test"
az container create -g $rg -n $aciName --image $image `
--acr-identity $($DeploymentOutputs['AZIDENTITY_USER_ASSIGNED_IDENTITY']) `
@@ -85,23 +108,27 @@ az container create -g $rg -n $aciName --image $image `
FUNCTIONS_CUSTOMHANDLER_PORT=80
$aciIP = az container show -g $rg -n $aciName --query ipAddress.ip --output tsv
Write-Host "##vso[task.setvariable variable=AZIDENTITY_ACI_IP;]$aciIP"
+Write-Host "##[endgroup]"
# Azure Functions deployment: copy the Windows binary from the Docker image, deploy it in a zip
-Write-Host "Deploying to Azure Functions"
+Write-Host "##[group]Deploying to Azure Functions"
$container = docker create $image
docker cp ${container}:managed-id-test.exe "$PSScriptRoot/testdata/managed-id-test/"
docker rm -v $container
Compress-Archive -Path "$PSScriptRoot/testdata/managed-id-test/*" -DestinationPath func.zip -Force
az functionapp deploy -g $rg -n $DeploymentOutputs['AZIDENTITY_FUNCTION_NAME'] --src-path func.zip --type zip
+Write-Host "##[endgroup]"
-Write-Host "Creating federated identity"
+Write-Host "##[group]Creating federated identity"
$aksName = $DeploymentOutputs['AZIDENTITY_AKS_NAME']
$idName = $DeploymentOutputs['AZIDENTITY_USER_ASSIGNED_IDENTITY_NAME']
$issuer = az aks show -g $rg -n $aksName --query "oidcIssuerProfile.issuerUrl" -otsv
$podName = "azidentity-test"
$serviceAccountName = "workload-identity-sa"
-az identity federated-credential create -g $rg --identity-name $idName --issuer $issuer --name $idName --subject system:serviceaccount:default:$serviceAccountName
-Write-Host "Deploying to AKS"
+az identity federated-credential create -g $rg --identity-name $idName --issuer $issuer --name $idName --subject system:serviceaccount:default:$serviceAccountName --audiences api://AzureADTokenExchange
+Write-Host "##[endgroup]"
+
+Write-Host "##[group]Deploying to AKS"
az aks get-credentials -g $rg -n $aksName
az aks update --attach-acr $DeploymentOutputs['AZIDENTITY_ACR_NAME'] -g $rg -n $aksName
Set-Content -Path "$PSScriptRoot/k8s.yaml" -Value @"
@@ -138,3 +165,4 @@ spec:
"@
kubectl apply -f "$PSScriptRoot/k8s.yaml"
Write-Host "##vso[task.setvariable variable=AZIDENTITY_POD_NAME;]$podName"
+Write-Host "##[endgroup]"
diff --git a/vendor/github.com/Azure/azure-sdk-for-go/sdk/azidentity/test-resources.bicep b/vendor/github.com/Azure/azure-sdk-for-go/sdk/azidentity/test-resources.bicep
index 135feb017..cb3b5f4df 100644
--- a/vendor/github.com/Azure/azure-sdk-for-go/sdk/azidentity/test-resources.bicep
+++ b/vendor/github.com/Azure/azure-sdk-for-go/sdk/azidentity/test-resources.bicep
@@ -19,7 +19,10 @@ param location string = resourceGroup().location
// https://learn.microsoft.com/azure/role-based-access-control/built-in-roles
var acrPull = subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '7f951dda-4ed3-4680-a7ca-43fe172d538d')
-var blobReader = subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '2a2b9908-6ea1-4ae2-8e65-a410df84e7d1')
+var blobReader = subscriptionResourceId(
+ 'Microsoft.Authorization/roleDefinitions',
+ '2a2b9908-6ea1-4ae2-8e65-a410df84e7d1'
+)
resource sa 'Microsoft.Storage/storageAccounts@2021-08-01' = if (deployResources) {
kind: 'StorageV2'
@@ -60,6 +63,16 @@ resource acrPullContainerInstance 'Microsoft.Authorization/roleAssignments@2022-
scope: containerRegistry
}
+resource acrPullVM 'Microsoft.Authorization/roleAssignments@2022-04-01' = if (deployResources) {
+ name: guid(resourceGroup().id, acrPull, 'vm')
+ properties: {
+ principalId: deployResources ? vm.identity.principalId : ''
+ principalType: 'ServicePrincipal'
+ roleDefinitionId: acrPull
+ }
+ scope: containerRegistry
+}
+
resource blobRoleUserAssigned 'Microsoft.Authorization/roleAssignments@2022-04-01' = if (deployResources) {
scope: saUserAssigned
name: guid(resourceGroup().id, blobReader, usermgdid.id)
@@ -80,6 +93,16 @@ resource blobRoleFunc 'Microsoft.Authorization/roleAssignments@2022-04-01' = if
scope: sa
}
+resource blobRoleVM 'Microsoft.Authorization/roleAssignments@2022-04-01' = if (deployResources) {
+ scope: sa
+ name: guid(resourceGroup().id, blobReader, 'vm')
+ properties: {
+ principalId: deployResources ? vm.identity.principalId : ''
+ roleDefinitionId: blobReader
+ principalType: 'ServicePrincipal'
+ }
+}
+
resource containerRegistry 'Microsoft.ContainerRegistry/registries@2023-01-01-preview' = if (deployResources) {
location: location
name: uniqueString(resourceGroup().id)
@@ -215,6 +238,143 @@ resource aks 'Microsoft.ContainerService/managedClusters@2023-06-01' = if (deplo
}
}
+resource publicIP 'Microsoft.Network/publicIPAddresses@2023-05-01' = if (deployResources) {
+ name: '${baseName}PublicIP'
+ location: location
+ sku: {
+ name: 'Standard'
+ }
+ properties: {
+ publicIPAllocationMethod: 'Static'
+ }
+}
+
+resource nsg 'Microsoft.Network/networkSecurityGroups@2024-07-01' = if (deployResources) {
+ name: '${baseName}NSG'
+ location: location
+ properties: {
+ securityRules: [
+ {
+ name: 'AllowHTTP'
+ properties: {
+ description: 'Allow HTTP traffic on port 80'
+ protocol: 'Tcp'
+ sourcePortRange: '*'
+ destinationPortRange: '80'
+ sourceAddressPrefix: '*'
+ destinationAddressPrefix: '*'
+ access: 'Allow'
+ priority: 1000
+ direction: 'Inbound'
+ }
+ }
+ ]
+ }
+}
+
+resource vnet 'Microsoft.Network/virtualNetworks@2024-07-01' = if (deployResources) {
+ name: '${baseName}vnet'
+ location: location
+ properties: {
+ addressSpace: {
+ addressPrefixes: [
+ '10.0.0.0/16'
+ ]
+ }
+ subnets: [
+ {
+ name: '${baseName}subnet'
+ properties: {
+ addressPrefix: '10.0.0.0/24'
+ defaultOutboundAccess: false
+ networkSecurityGroup: {
+ id: deployResources ? nsg.id : ''
+ }
+ }
+ }
+ ]
+ }
+}
+
+resource nic 'Microsoft.Network/networkInterfaces@2024-07-01' = if (deployResources) {
+ name: '${baseName}NIC'
+ location: location
+ properties: {
+ ipConfigurations: [
+ {
+ name: 'myIPConfig'
+ properties: {
+ privateIPAllocationMethod: 'Dynamic'
+ publicIPAddress: {
+ id: deployResources ? publicIP.id : ''
+ }
+ subnet: {
+ id: deployResources ? vnet.properties.subnets[0].id : ''
+ }
+ }
+ }
+ ]
+ }
+}
+
+resource vm 'Microsoft.Compute/virtualMachines@2024-07-01' = if (deployResources) {
+ name: '${baseName}vm'
+ location: location
+ identity: {
+ type: 'SystemAssigned, UserAssigned'
+ userAssignedIdentities: {
+ '${deployResources ? usermgdid.id: ''}': {}
+ }
+ }
+ properties: {
+ hardwareProfile: {
+ vmSize: 'Standard_DS1_v2'
+ }
+ osProfile: {
+ adminUsername: adminUser
+ computerName: '${baseName}vm'
+ customData: base64('''
+#cloud-config
+package_update: true
+packages:
+ - docker.io
+runcmd:
+ - curl -sL https://aka.ms/InstallAzureCLIDeb | sudo bash
+ - az login --identity --allow-no-subscriptions
+''')
+ linuxConfiguration: {
+ disablePasswordAuthentication: true
+ ssh: {
+ publicKeys: [
+ {
+ path: '/home/${adminUser}/.ssh/authorized_keys'
+ keyData: sshPubKey
+ }
+ ]
+ }
+ }
+ }
+ networkProfile: {
+ networkInterfaces: [
+ {
+ id: deployResources ? nic.id : ''
+ }
+ ]
+ }
+ storageProfile: {
+ imageReference: {
+ publisher: 'Canonical'
+ offer: 'ubuntu-24_04-lts'
+ sku: 'server'
+ version: 'latest'
+ }
+ osDisk: {
+ createOption: 'FromImage'
+ }
+ }
+ }
+}
+
output AZIDENTITY_ACR_LOGIN_SERVER string = deployResources ? containerRegistry.properties.loginServer : ''
output AZIDENTITY_ACR_NAME string = deployResources ? containerRegistry.name : ''
output AZIDENTITY_AKS_NAME string = deployResources ? aks.name : ''
@@ -226,3 +386,5 @@ output AZIDENTITY_USER_ASSIGNED_IDENTITY string = deployResources ? usermgdid.id
output AZIDENTITY_USER_ASSIGNED_IDENTITY_CLIENT_ID string = deployResources ? usermgdid.properties.clientId : ''
output AZIDENTITY_USER_ASSIGNED_IDENTITY_NAME string = deployResources ? usermgdid.name : ''
output AZIDENTITY_USER_ASSIGNED_IDENTITY_OBJECT_ID string = deployResources ? usermgdid.properties.principalId : ''
+output AZIDENTITY_VM_NAME string = deployResources ? vm.name : ''
+output AZIDENTITY_VM_IP string = deployResources ? publicIP.properties.ipAddress : ''
diff --git a/vendor/github.com/Azure/azure-sdk-for-go/sdk/azidentity/version.go b/vendor/github.com/Azure/azure-sdk-for-go/sdk/azidentity/version.go
index e859fba3a..4c8860536 100644
--- a/vendor/github.com/Azure/azure-sdk-for-go/sdk/azidentity/version.go
+++ b/vendor/github.com/Azure/azure-sdk-for-go/sdk/azidentity/version.go
@@ -14,5 +14,5 @@ const (
module = "github.com/Azure/azure-sdk-for-go/sdk/" + component
// Version is the semantic version (see http://semver.org) of this module.
- version = "v1.10.0"
+ version = "v1.12.0"
)
diff --git a/vendor/github.com/Azure/azure-sdk-for-go/sdk/internal/errorinfo/errorinfo.go b/vendor/github.com/Azure/azure-sdk-for-go/sdk/internal/errorinfo/errorinfo.go
index 8ee66b526..779657b23 100644
--- a/vendor/github.com/Azure/azure-sdk-for-go/sdk/internal/errorinfo/errorinfo.go
+++ b/vendor/github.com/Azure/azure-sdk-for-go/sdk/internal/errorinfo/errorinfo.go
@@ -6,6 +6,8 @@
package errorinfo
+import "errors"
+
// NonRetriable represents a non-transient error. This works in
// conjunction with the retry policy, indicating that the error condition
// is idempotent, so no retries will be attempted.
@@ -15,10 +17,14 @@ type NonRetriable interface {
NonRetriable()
}
-// NonRetriableError marks the specified error as non-retriable.
-// This function takes an error as input and returns a new error that is marked as non-retriable.
+// NonRetriableError ensures the specified error is [NonRetriable]. If
+// the error is already [NonRetriable], it returns that error unchanged.
+// Otherwise, it returns a new, [NonRetriable] error.
func NonRetriableError(err error) error {
- return &nonRetriableError{err}
+ if !errors.As(err, new(NonRetriable)) {
+ err = &nonRetriableError{err}
+ }
+ return err
}
// nonRetriableError is a struct that embeds the error interface.
diff --git a/vendor/github.com/AzureAD/microsoft-authentication-library-for-go/apps/internal/local/server.go b/vendor/github.com/AzureAD/microsoft-authentication-library-for-go/apps/internal/local/server.go
index cda678e33..c6baf2094 100644
--- a/vendor/github.com/AzureAD/microsoft-authentication-library-for-go/apps/internal/local/server.go
+++ b/vendor/github.com/AzureAD/microsoft-authentication-library-for-go/apps/internal/local/server.go
@@ -143,9 +143,10 @@ func (s *Server) handler(w http.ResponseWriter, r *http.Request) {
headerErr := q.Get("error")
if headerErr != "" {
desc := html.EscapeString(q.Get("error_description"))
+ escapedHeaderErr := html.EscapeString(headerErr)
// Note: It is a little weird we handle some errors by not going to the failPage. If they all should,
// change this to s.error() and make s.error() write the failPage instead of an error code.
- _, _ = w.Write([]byte(fmt.Sprintf(failPage, headerErr, desc)))
+ _, _ = w.Write([]byte(fmt.Sprintf(failPage, escapedHeaderErr, desc)))
s.putResult(Result{Err: fmt.Errorf("%s", desc)})
return
diff --git a/vendor/github.com/AzureAD/microsoft-authentication-library-for-go/apps/internal/oauth/ops/authority/authority.go b/vendor/github.com/AzureAD/microsoft-authentication-library-for-go/apps/internal/oauth/ops/authority/authority.go
index c3c4a96fc..3f4037464 100644
--- a/vendor/github.com/AzureAD/microsoft-authentication-library-for-go/apps/internal/oauth/ops/authority/authority.go
+++ b/vendor/github.com/AzureAD/microsoft-authentication-library-for-go/apps/internal/oauth/ops/authority/authority.go
@@ -46,9 +46,11 @@ type jsonCaller interface {
JSONCall(ctx context.Context, endpoint string, headers http.Header, qv url.Values, body, resp interface{}) error
}
+// For backward compatibility, accept both old and new China endpoints for a transition period.
var aadTrustedHostList = map[string]bool{
"login.windows.net": true, // Microsoft Azure Worldwide - Used in validation scenarios where host is not this list
- "login.partner.microsoftonline.cn": true, // Microsoft Azure China
+ "login.partner.microsoftonline.cn": true, // Microsoft Azure China (new)
+ "login.chinacloudapi.cn": true, // Microsoft Azure China (legacy, backward compatibility)
"login.microsoftonline.de": true, // Microsoft Azure Blackforest
"login-us.microsoftonline.com": true, // Microsoft Azure US Government - Legacy
"login.microsoftonline.us": true, // Microsoft Azure US Government
@@ -98,6 +100,41 @@ func (r *TenantDiscoveryResponse) Validate() error {
return nil
}
+// ValidateIssuerMatchesAuthority validates that the issuer in the TenantDiscoveryResponse matches the authority.
+// This is used to identity security or configuration issues in authorities and the OIDC endpoint
+func (r *TenantDiscoveryResponse) ValidateIssuerMatchesAuthority(authorityURI string, aliases map[string]bool) error {
+
+ if authorityURI == "" {
+ return errors.New("TenantDiscoveryResponse: empty authorityURI provided for validation")
+ }
+
+ // Parse the issuer URL
+ issuerURL, err := url.Parse(r.Issuer)
+ if err != nil {
+ return fmt.Errorf("TenantDiscoveryResponse: failed to parse issuer URL: %w", err)
+ }
+
+ // Even if it doesn't match the authority, issuers from known and trusted hosts are valid
+ if aliases != nil && aliases[issuerURL.Host] {
+ return nil
+ }
+
+ // Parse the authority URL for comparison
+ authorityURL, err := url.Parse(authorityURI)
+ if err != nil {
+ return fmt.Errorf("TenantDiscoveryResponse: failed to parse authority URL: %w", err)
+ }
+
+ // Check if the scheme and host match (paths can be ignored when validating the issuer)
+ if issuerURL.Scheme == authorityURL.Scheme && issuerURL.Host == authorityURL.Host {
+ return nil
+ }
+
+ // If we get here, validation failed
+ return fmt.Errorf("TenantDiscoveryResponse: issuer from OIDC discovery '%s' does not match authority '%s' or a known pattern",
+ r.Issuer, authorityURI)
+}
+
type InstanceDiscoveryMetadata struct {
PreferredNetwork string `json:"preferred_network"`
PreferredCache string `json:"preferred_cache"`
@@ -354,6 +391,8 @@ type Info struct {
Tenant string
Region string
InstanceDiscoveryDisabled bool
+ // InstanceDiscoveryMetadata stores the metadata from AAD instance discovery
+ InstanceDiscoveryMetadata []InstanceDiscoveryMetadata
}
// NewInfoFromAuthorityURI creates an AuthorityInfo instance from the authority URL provided.
diff --git a/vendor/github.com/AzureAD/microsoft-authentication-library-for-go/apps/internal/oauth/resolvers.go b/vendor/github.com/AzureAD/microsoft-authentication-library-for-go/apps/internal/oauth/resolvers.go
index 4030ec8d8..d220a9946 100644
--- a/vendor/github.com/AzureAD/microsoft-authentication-library-for-go/apps/internal/oauth/resolvers.go
+++ b/vendor/github.com/AzureAD/microsoft-authentication-library-for-go/apps/internal/oauth/resolvers.go
@@ -21,10 +21,12 @@ import (
type cacheEntry struct {
Endpoints authority.Endpoints
ValidForDomainsInList map[string]bool
+ // Aliases stores host aliases from instance discovery for quick lookup
+ Aliases map[string]bool
}
func createcacheEntry(endpoints authority.Endpoints) cacheEntry {
- return cacheEntry{endpoints, map[string]bool{}}
+ return cacheEntry{endpoints, map[string]bool{}, map[string]bool{}}
}
// AuthorityEndpoint retrieves endpoints from an authority for auth and token acquisition.
@@ -71,10 +73,15 @@ func (m *authorityEndpoint) ResolveEndpoints(ctx context.Context, authorityInfo
m.addCachedEndpoints(authorityInfo, userPrincipalName, endpoints)
+ if err := resp.ValidateIssuerMatchesAuthority(authorityInfo.CanonicalAuthorityURI,
+ m.cache[authorityInfo.CanonicalAuthorityURI].Aliases); err != nil {
+ return authority.Endpoints{}, fmt.Errorf("ResolveEndpoints(): %w", err)
+ }
+
return endpoints, nil
}
-// cachedEndpoints returns a the cached endpoints if they exists. If not, we return false.
+// cachedEndpoints returns the cached endpoints if they exist. If not, we return false.
func (m *authorityEndpoint) cachedEndpoints(authorityInfo authority.Info, userPrincipalName string) (authority.Endpoints, bool) {
m.mu.Lock()
defer m.mu.Unlock()
@@ -113,6 +120,13 @@ func (m *authorityEndpoint) addCachedEndpoints(authorityInfo authority.Info, use
}
}
+ // Extract aliases from instance discovery metadata and add to cache
+ for _, metadata := range authorityInfo.InstanceDiscoveryMetadata {
+ for _, alias := range metadata.Aliases {
+ updatedCacheEntry.Aliases[alias] = true
+ }
+ }
+
m.cache[authorityInfo.CanonicalAuthorityURI] = updatedCacheEntry
}
@@ -127,12 +141,14 @@ func (m *authorityEndpoint) openIDConfigurationEndpoint(ctx context.Context, aut
if err != nil {
return "", err
}
+ authorityInfo.InstanceDiscoveryMetadata = resp.Metadata
return resp.TenantDiscoveryEndpoint, nil
} else if authorityInfo.Region != "" {
resp, err := m.rest.Authority().AADInstanceDiscovery(ctx, authorityInfo)
if err != nil {
return "", err
}
+ authorityInfo.InstanceDiscoveryMetadata = resp.Metadata
return resp.TenantDiscoveryEndpoint, nil
}
diff --git a/vendor/github.com/golang-jwt/jwt/v5/MIGRATION_GUIDE.md b/vendor/github.com/golang-jwt/jwt/v5/MIGRATION_GUIDE.md
index ff9c57e1d..b3178e751 100644
--- a/vendor/github.com/golang-jwt/jwt/v5/MIGRATION_GUIDE.md
+++ b/vendor/github.com/golang-jwt/jwt/v5/MIGRATION_GUIDE.md
@@ -155,7 +155,7 @@ stored in base64 encoded form, which was redundant with the information in the
type Token struct {
Raw string // Raw contains the raw token
Method SigningMethod // Method is the signing method used or to be used
- Header map[string]interface{} // Header is the first segment of the token in decoded form
+ Header map[string]any // Header is the first segment of the token in decoded form
Claims Claims // Claims is the second segment of the token in decoded form
Signature []byte // Signature is the third segment of the token in decoded form
Valid bool // Valid specifies if the token is valid
diff --git a/vendor/github.com/golang-jwt/jwt/v5/ecdsa.go b/vendor/github.com/golang-jwt/jwt/v5/ecdsa.go
index c929e4a02..06cd94d23 100644
--- a/vendor/github.com/golang-jwt/jwt/v5/ecdsa.go
+++ b/vendor/github.com/golang-jwt/jwt/v5/ecdsa.go
@@ -55,7 +55,7 @@ func (m *SigningMethodECDSA) Alg() string {
// Verify implements token verification for the SigningMethod.
// For this verify method, key must be an ecdsa.PublicKey struct
-func (m *SigningMethodECDSA) Verify(signingString string, sig []byte, key interface{}) error {
+func (m *SigningMethodECDSA) Verify(signingString string, sig []byte, key any) error {
// Get the key
var ecdsaKey *ecdsa.PublicKey
switch k := key.(type) {
@@ -89,7 +89,7 @@ func (m *SigningMethodECDSA) Verify(signingString string, sig []byte, key interf
// Sign implements token signing for the SigningMethod.
// For this signing method, key must be an ecdsa.PrivateKey struct
-func (m *SigningMethodECDSA) Sign(signingString string, key interface{}) ([]byte, error) {
+func (m *SigningMethodECDSA) Sign(signingString string, key any) ([]byte, error) {
// Get the key
var ecdsaKey *ecdsa.PrivateKey
switch k := key.(type) {
diff --git a/vendor/github.com/golang-jwt/jwt/v5/ecdsa_utils.go b/vendor/github.com/golang-jwt/jwt/v5/ecdsa_utils.go
index 5700636d3..44a3b7a1c 100644
--- a/vendor/github.com/golang-jwt/jwt/v5/ecdsa_utils.go
+++ b/vendor/github.com/golang-jwt/jwt/v5/ecdsa_utils.go
@@ -23,7 +23,7 @@ func ParseECPrivateKeyFromPEM(key []byte) (*ecdsa.PrivateKey, error) {
}
// Parse the key
- var parsedKey interface{}
+ var parsedKey any
if parsedKey, err = x509.ParseECPrivateKey(block.Bytes); err != nil {
if parsedKey, err = x509.ParsePKCS8PrivateKey(block.Bytes); err != nil {
return nil, err
@@ -50,7 +50,7 @@ func ParseECPublicKeyFromPEM(key []byte) (*ecdsa.PublicKey, error) {
}
// Parse the key
- var parsedKey interface{}
+ var parsedKey any
if parsedKey, err = x509.ParsePKIXPublicKey(block.Bytes); err != nil {
if cert, err := x509.ParseCertificate(block.Bytes); err == nil {
parsedKey = cert.PublicKey
diff --git a/vendor/github.com/golang-jwt/jwt/v5/ed25519.go b/vendor/github.com/golang-jwt/jwt/v5/ed25519.go
index c2138119e..4159e57bf 100644
--- a/vendor/github.com/golang-jwt/jwt/v5/ed25519.go
+++ b/vendor/github.com/golang-jwt/jwt/v5/ed25519.go
@@ -33,7 +33,7 @@ func (m *SigningMethodEd25519) Alg() string {
// Verify implements token verification for the SigningMethod.
// For this verify method, key must be an ed25519.PublicKey
-func (m *SigningMethodEd25519) Verify(signingString string, sig []byte, key interface{}) error {
+func (m *SigningMethodEd25519) Verify(signingString string, sig []byte, key any) error {
var ed25519Key ed25519.PublicKey
var ok bool
@@ -55,7 +55,7 @@ func (m *SigningMethodEd25519) Verify(signingString string, sig []byte, key inte
// Sign implements token signing for the SigningMethod.
// For this signing method, key must be an ed25519.PrivateKey
-func (m *SigningMethodEd25519) Sign(signingString string, key interface{}) ([]byte, error) {
+func (m *SigningMethodEd25519) Sign(signingString string, key any) ([]byte, error) {
var ed25519Key crypto.Signer
var ok bool
diff --git a/vendor/github.com/golang-jwt/jwt/v5/ed25519_utils.go b/vendor/github.com/golang-jwt/jwt/v5/ed25519_utils.go
index cdb5e68e8..6f46e8860 100644
--- a/vendor/github.com/golang-jwt/jwt/v5/ed25519_utils.go
+++ b/vendor/github.com/golang-jwt/jwt/v5/ed25519_utils.go
@@ -24,7 +24,7 @@ func ParseEdPrivateKeyFromPEM(key []byte) (crypto.PrivateKey, error) {
}
// Parse the key
- var parsedKey interface{}
+ var parsedKey any
if parsedKey, err = x509.ParsePKCS8PrivateKey(block.Bytes); err != nil {
return nil, err
}
@@ -49,7 +49,7 @@ func ParseEdPublicKeyFromPEM(key []byte) (crypto.PublicKey, error) {
}
// Parse the key
- var parsedKey interface{}
+ var parsedKey any
if parsedKey, err = x509.ParsePKIXPublicKey(block.Bytes); err != nil {
return nil, err
}
diff --git a/vendor/github.com/golang-jwt/jwt/v5/errors.go b/vendor/github.com/golang-jwt/jwt/v5/errors.go
index 23bb616dd..14e007516 100644
--- a/vendor/github.com/golang-jwt/jwt/v5/errors.go
+++ b/vendor/github.com/golang-jwt/jwt/v5/errors.go
@@ -2,6 +2,7 @@ package jwt
import (
"errors"
+ "fmt"
"strings"
)
@@ -47,3 +48,42 @@ func joinErrors(errs ...error) error {
errs: errs,
}
}
+
+// Unwrap implements the multiple error unwrapping for this error type, which is
+// possible in Go 1.20.
+func (je joinedError) Unwrap() []error {
+ return je.errs
+}
+
+// newError creates a new error message with a detailed error message. The
+// message will be prefixed with the contents of the supplied error type.
+// Additionally, more errors, that provide more context can be supplied which
+// will be appended to the message. This makes use of Go 1.20's possibility to
+// include more than one %w formatting directive in [fmt.Errorf].
+//
+// For example,
+//
+// newError("no keyfunc was provided", ErrTokenUnverifiable)
+//
+// will produce the error string
+//
+// "token is unverifiable: no keyfunc was provided"
+func newError(message string, err error, more ...error) error {
+ var format string
+ var args []any
+ if message != "" {
+ format = "%w: %s"
+ args = []any{err, message}
+ } else {
+ format = "%w"
+ args = []any{err}
+ }
+
+ for _, e := range more {
+ format += ": %w"
+ args = append(args, e)
+ }
+
+ err = fmt.Errorf(format, args...)
+ return err
+}
diff --git a/vendor/github.com/golang-jwt/jwt/v5/errors_go1_20.go b/vendor/github.com/golang-jwt/jwt/v5/errors_go1_20.go
deleted file mode 100644
index a893d355e..000000000
--- a/vendor/github.com/golang-jwt/jwt/v5/errors_go1_20.go
+++ /dev/null
@@ -1,47 +0,0 @@
-//go:build go1.20
-// +build go1.20
-
-package jwt
-
-import (
- "fmt"
-)
-
-// Unwrap implements the multiple error unwrapping for this error type, which is
-// possible in Go 1.20.
-func (je joinedError) Unwrap() []error {
- return je.errs
-}
-
-// newError creates a new error message with a detailed error message. The
-// message will be prefixed with the contents of the supplied error type.
-// Additionally, more errors, that provide more context can be supplied which
-// will be appended to the message. This makes use of Go 1.20's possibility to
-// include more than one %w formatting directive in [fmt.Errorf].
-//
-// For example,
-//
-// newError("no keyfunc was provided", ErrTokenUnverifiable)
-//
-// will produce the error string
-//
-// "token is unverifiable: no keyfunc was provided"
-func newError(message string, err error, more ...error) error {
- var format string
- var args []any
- if message != "" {
- format = "%w: %s"
- args = []any{err, message}
- } else {
- format = "%w"
- args = []any{err}
- }
-
- for _, e := range more {
- format += ": %w"
- args = append(args, e)
- }
-
- err = fmt.Errorf(format, args...)
- return err
-}
diff --git a/vendor/github.com/golang-jwt/jwt/v5/errors_go_other.go b/vendor/github.com/golang-jwt/jwt/v5/errors_go_other.go
deleted file mode 100644
index 2ad542f00..000000000
--- a/vendor/github.com/golang-jwt/jwt/v5/errors_go_other.go
+++ /dev/null
@@ -1,78 +0,0 @@
-//go:build !go1.20
-// +build !go1.20
-
-package jwt
-
-import (
- "errors"
- "fmt"
-)
-
-// Is implements checking for multiple errors using [errors.Is], since multiple
-// error unwrapping is not possible in versions less than Go 1.20.
-func (je joinedError) Is(err error) bool {
- for _, e := range je.errs {
- if errors.Is(e, err) {
- return true
- }
- }
-
- return false
-}
-
-// wrappedErrors is a workaround for wrapping multiple errors in environments
-// where Go 1.20 is not available. It basically uses the already implemented
-// functionality of joinedError to handle multiple errors with supplies a
-// custom error message that is identical to the one we produce in Go 1.20 using
-// multiple %w directives.
-type wrappedErrors struct {
- msg string
- joinedError
-}
-
-// Error returns the stored error string
-func (we wrappedErrors) Error() string {
- return we.msg
-}
-
-// newError creates a new error message with a detailed error message. The
-// message will be prefixed with the contents of the supplied error type.
-// Additionally, more errors, that provide more context can be supplied which
-// will be appended to the message. Since we cannot use of Go 1.20's possibility
-// to include more than one %w formatting directive in [fmt.Errorf], we have to
-// emulate that.
-//
-// For example,
-//
-// newError("no keyfunc was provided", ErrTokenUnverifiable)
-//
-// will produce the error string
-//
-// "token is unverifiable: no keyfunc was provided"
-func newError(message string, err error, more ...error) error {
- // We cannot wrap multiple errors here with %w, so we have to be a little
- // bit creative. Basically, we are using %s instead of %w to produce the
- // same error message and then throw the result into a custom error struct.
- var format string
- var args []any
- if message != "" {
- format = "%s: %s"
- args = []any{err, message}
- } else {
- format = "%s"
- args = []any{err}
- }
- errs := []error{err}
-
- for _, e := range more {
- format += ": %s"
- args = append(args, e)
- errs = append(errs, e)
- }
-
- err = &wrappedErrors{
- msg: fmt.Sprintf(format, args...),
- joinedError: joinedError{errs: errs},
- }
- return err
-}
diff --git a/vendor/github.com/golang-jwt/jwt/v5/hmac.go b/vendor/github.com/golang-jwt/jwt/v5/hmac.go
index aca600ce1..1bef138c3 100644
--- a/vendor/github.com/golang-jwt/jwt/v5/hmac.go
+++ b/vendor/github.com/golang-jwt/jwt/v5/hmac.go
@@ -55,7 +55,7 @@ func (m *SigningMethodHMAC) Alg() string {
// about this, and why we intentionally are not supporting string as a key can
// be found on our usage guide
// https://golang-jwt.github.io/jwt/usage/signing_methods/#signing-methods-and-key-types.
-func (m *SigningMethodHMAC) Verify(signingString string, sig []byte, key interface{}) error {
+func (m *SigningMethodHMAC) Verify(signingString string, sig []byte, key any) error {
// Verify the key is the right type
keyBytes, ok := key.([]byte)
if !ok {
@@ -88,7 +88,7 @@ func (m *SigningMethodHMAC) Verify(signingString string, sig []byte, key interfa
// cryptographically random source, e.g. crypto/rand. Additional information
// about this, and why we intentionally are not supporting string as a key can
// be found on our usage guide https://golang-jwt.github.io/jwt/usage/signing_methods/.
-func (m *SigningMethodHMAC) Sign(signingString string, key interface{}) ([]byte, error) {
+func (m *SigningMethodHMAC) Sign(signingString string, key any) ([]byte, error) {
if keyBytes, ok := key.([]byte); ok {
if !m.Hash.Available() {
return nil, ErrHashUnavailable
diff --git a/vendor/github.com/golang-jwt/jwt/v5/map_claims.go b/vendor/github.com/golang-jwt/jwt/v5/map_claims.go
index b2b51a1f8..3b9205272 100644
--- a/vendor/github.com/golang-jwt/jwt/v5/map_claims.go
+++ b/vendor/github.com/golang-jwt/jwt/v5/map_claims.go
@@ -5,9 +5,9 @@ import (
"fmt"
)
-// MapClaims is a claims type that uses the map[string]interface{} for JSON
+// MapClaims is a claims type that uses the map[string]any for JSON
// decoding. This is the default claims type if you don't supply one
-type MapClaims map[string]interface{}
+type MapClaims map[string]any
// GetExpirationTime implements the Claims interface.
func (m MapClaims) GetExpirationTime() (*NumericDate, error) {
@@ -73,7 +73,7 @@ func (m MapClaims) parseClaimsString(key string) (ClaimStrings, error) {
cs = append(cs, v)
case []string:
cs = v
- case []interface{}:
+ case []any:
for _, a := range v {
vs, ok := a.(string)
if !ok {
@@ -92,7 +92,7 @@ func (m MapClaims) parseClaimsString(key string) (ClaimStrings, error) {
func (m MapClaims) parseString(key string) (string, error) {
var (
ok bool
- raw interface{}
+ raw any
iss string
)
raw, ok = m[key]
diff --git a/vendor/github.com/golang-jwt/jwt/v5/none.go b/vendor/github.com/golang-jwt/jwt/v5/none.go
index 685c2ea30..624ad55e8 100644
--- a/vendor/github.com/golang-jwt/jwt/v5/none.go
+++ b/vendor/github.com/golang-jwt/jwt/v5/none.go
@@ -25,7 +25,7 @@ func (m *signingMethodNone) Alg() string {
}
// Only allow 'none' alg type if UnsafeAllowNoneSignatureType is specified as the key
-func (m *signingMethodNone) Verify(signingString string, sig []byte, key interface{}) (err error) {
+func (m *signingMethodNone) Verify(signingString string, sig []byte, key any) (err error) {
// Key must be UnsafeAllowNoneSignatureType to prevent accidentally
// accepting 'none' signing method
if _, ok := key.(unsafeNoneMagicConstant); !ok {
@@ -41,7 +41,7 @@ func (m *signingMethodNone) Verify(signingString string, sig []byte, key interfa
}
// Only allow 'none' signing if UnsafeAllowNoneSignatureType is specified as the key
-func (m *signingMethodNone) Sign(signingString string, key interface{}) ([]byte, error) {
+func (m *signingMethodNone) Sign(signingString string, key any) ([]byte, error) {
if _, ok := key.(unsafeNoneMagicConstant); ok {
return []byte{}, nil
}
diff --git a/vendor/github.com/golang-jwt/jwt/v5/parser_option.go b/vendor/github.com/golang-jwt/jwt/v5/parser_option.go
index 88a780fbd..431573557 100644
--- a/vendor/github.com/golang-jwt/jwt/v5/parser_option.go
+++ b/vendor/github.com/golang-jwt/jwt/v5/parser_option.go
@@ -66,20 +66,37 @@ func WithExpirationRequired() ParserOption {
}
}
-// WithAudience configures the validator to require the specified audience in
-// the `aud` claim. Validation will fail if the audience is not listed in the
-// token or the `aud` claim is missing.
+// WithAudience configures the validator to require any of the specified
+// audiences in the `aud` claim. Validation will fail if the audience is not
+// listed in the token or the `aud` claim is missing.
//
// NOTE: While the `aud` claim is OPTIONAL in a JWT, the handling of it is
// application-specific. Since this validation API is helping developers in
// writing secure application, we decided to REQUIRE the existence of the claim,
// if an audience is expected.
-func WithAudience(aud string) ParserOption {
+func WithAudience(aud ...string) ParserOption {
return func(p *Parser) {
p.validator.expectedAud = aud
}
}
+// WithAllAudiences configures the validator to require all the specified
+// audiences in the `aud` claim. Validation will fail if the specified audiences
+// are not listed in the token or the `aud` claim is missing. Duplicates within
+// the list are de-duplicated since internally, we use a map to look up the
+// audiences.
+//
+// NOTE: While the `aud` claim is OPTIONAL in a JWT, the handling of it is
+// application-specific. Since this validation API is helping developers in
+// writing secure application, we decided to REQUIRE the existence of the claim,
+// if an audience is expected.
+func WithAllAudiences(aud ...string) ParserOption {
+ return func(p *Parser) {
+ p.validator.expectedAud = aud
+ p.validator.expectAllAud = true
+ }
+}
+
// WithIssuer configures the validator to require the specified issuer in the
// `iss` claim. Validation will fail if a different issuer is specified in the
// token or the `iss` claim is missing.
diff --git a/vendor/github.com/golang-jwt/jwt/v5/rsa.go b/vendor/github.com/golang-jwt/jwt/v5/rsa.go
index 83cbee6ae..98b960a78 100644
--- a/vendor/github.com/golang-jwt/jwt/v5/rsa.go
+++ b/vendor/github.com/golang-jwt/jwt/v5/rsa.go
@@ -46,7 +46,7 @@ func (m *SigningMethodRSA) Alg() string {
// Verify implements token verification for the SigningMethod
// For this signing method, must be an *rsa.PublicKey structure.
-func (m *SigningMethodRSA) Verify(signingString string, sig []byte, key interface{}) error {
+func (m *SigningMethodRSA) Verify(signingString string, sig []byte, key any) error {
var rsaKey *rsa.PublicKey
var ok bool
@@ -67,7 +67,7 @@ func (m *SigningMethodRSA) Verify(signingString string, sig []byte, key interfac
// Sign implements token signing for the SigningMethod
// For this signing method, must be an *rsa.PrivateKey structure.
-func (m *SigningMethodRSA) Sign(signingString string, key interface{}) ([]byte, error) {
+func (m *SigningMethodRSA) Sign(signingString string, key any) ([]byte, error) {
var rsaKey *rsa.PrivateKey
var ok bool
diff --git a/vendor/github.com/golang-jwt/jwt/v5/rsa_pss.go b/vendor/github.com/golang-jwt/jwt/v5/rsa_pss.go
index 28c386ec4..f17590cc4 100644
--- a/vendor/github.com/golang-jwt/jwt/v5/rsa_pss.go
+++ b/vendor/github.com/golang-jwt/jwt/v5/rsa_pss.go
@@ -1,6 +1,3 @@
-//go:build go1.4
-// +build go1.4
-
package jwt
import (
@@ -82,7 +79,7 @@ func init() {
// Verify implements token verification for the SigningMethod.
// For this verify method, key must be an rsa.PublicKey struct
-func (m *SigningMethodRSAPSS) Verify(signingString string, sig []byte, key interface{}) error {
+func (m *SigningMethodRSAPSS) Verify(signingString string, sig []byte, key any) error {
var rsaKey *rsa.PublicKey
switch k := key.(type) {
case *rsa.PublicKey:
@@ -108,7 +105,7 @@ func (m *SigningMethodRSAPSS) Verify(signingString string, sig []byte, key inter
// Sign implements token signing for the SigningMethod.
// For this signing method, key must be an rsa.PrivateKey struct
-func (m *SigningMethodRSAPSS) Sign(signingString string, key interface{}) ([]byte, error) {
+func (m *SigningMethodRSAPSS) Sign(signingString string, key any) ([]byte, error) {
var rsaKey *rsa.PrivateKey
switch k := key.(type) {
diff --git a/vendor/github.com/golang-jwt/jwt/v5/rsa_utils.go b/vendor/github.com/golang-jwt/jwt/v5/rsa_utils.go
index b3aeebbe1..f22c3d068 100644
--- a/vendor/github.com/golang-jwt/jwt/v5/rsa_utils.go
+++ b/vendor/github.com/golang-jwt/jwt/v5/rsa_utils.go
@@ -23,7 +23,7 @@ func ParseRSAPrivateKeyFromPEM(key []byte) (*rsa.PrivateKey, error) {
return nil, ErrKeyMustBePEMEncoded
}
- var parsedKey interface{}
+ var parsedKey any
if parsedKey, err = x509.ParsePKCS1PrivateKey(block.Bytes); err != nil {
if parsedKey, err = x509.ParsePKCS8PrivateKey(block.Bytes); err != nil {
return nil, err
@@ -53,7 +53,7 @@ func ParseRSAPrivateKeyFromPEMWithPassword(key []byte, password string) (*rsa.Pr
return nil, ErrKeyMustBePEMEncoded
}
- var parsedKey interface{}
+ var parsedKey any
var blockDecrypted []byte
if blockDecrypted, err = x509.DecryptPEMBlock(block, []byte(password)); err != nil {
@@ -86,7 +86,7 @@ func ParseRSAPublicKeyFromPEM(key []byte) (*rsa.PublicKey, error) {
}
// Parse the key
- var parsedKey interface{}
+ var parsedKey any
if parsedKey, err = x509.ParsePKIXPublicKey(block.Bytes); err != nil {
if cert, err := x509.ParseCertificate(block.Bytes); err == nil {
parsedKey = cert.PublicKey
diff --git a/vendor/github.com/golang-jwt/jwt/v5/signing_method.go b/vendor/github.com/golang-jwt/jwt/v5/signing_method.go
index 0d73631c1..096d0ed4c 100644
--- a/vendor/github.com/golang-jwt/jwt/v5/signing_method.go
+++ b/vendor/github.com/golang-jwt/jwt/v5/signing_method.go
@@ -12,9 +12,9 @@ var signingMethodLock = new(sync.RWMutex)
// signature in Sign. The signature is then usually base64 encoded as part of a
// JWT.
type SigningMethod interface {
- Verify(signingString string, sig []byte, key interface{}) error // Returns nil if signature is valid
- Sign(signingString string, key interface{}) ([]byte, error) // Returns signature or error
- Alg() string // returns the alg identifier for this method (example: 'HS256')
+ Verify(signingString string, sig []byte, key any) error // Returns nil if signature is valid
+ Sign(signingString string, key any) ([]byte, error) // Returns signature or error
+ Alg() string // returns the alg identifier for this method (example: 'HS256')
}
// RegisterSigningMethod registers the "alg" name and a factory function for signing method.
diff --git a/vendor/github.com/golang-jwt/jwt/v5/token.go b/vendor/github.com/golang-jwt/jwt/v5/token.go
index 9c7f4ab01..3f7155888 100644
--- a/vendor/github.com/golang-jwt/jwt/v5/token.go
+++ b/vendor/github.com/golang-jwt/jwt/v5/token.go
@@ -11,9 +11,9 @@ import (
// Token. This allows you to use properties in the Header of the token (such as
// `kid`) to identify which key to use.
//
-// The returned interface{} may be a single key or a VerificationKeySet containing
+// The returned any may be a single key or a VerificationKeySet containing
// multiple keys.
-type Keyfunc func(*Token) (interface{}, error)
+type Keyfunc func(*Token) (any, error)
// VerificationKey represents a public or secret key for verifying a token's signature.
type VerificationKey interface {
@@ -28,12 +28,12 @@ type VerificationKeySet struct {
// Token represents a JWT Token. Different fields will be used depending on
// whether you're creating or parsing/verifying a token.
type Token struct {
- Raw string // Raw contains the raw token. Populated when you [Parse] a token
- Method SigningMethod // Method is the signing method used or to be used
- Header map[string]interface{} // Header is the first segment of the token in decoded form
- Claims Claims // Claims is the second segment of the token in decoded form
- Signature []byte // Signature is the third segment of the token in decoded form. Populated when you Parse a token
- Valid bool // Valid specifies if the token is valid. Populated when you Parse/Verify a token
+ Raw string // Raw contains the raw token. Populated when you [Parse] a token
+ Method SigningMethod // Method is the signing method used or to be used
+ Header map[string]any // Header is the first segment of the token in decoded form
+ Claims Claims // Claims is the second segment of the token in decoded form
+ Signature []byte // Signature is the third segment of the token in decoded form. Populated when you Parse a token
+ Valid bool // Valid specifies if the token is valid. Populated when you Parse/Verify a token
}
// New creates a new [Token] with the specified signing method and an empty map
@@ -46,7 +46,7 @@ func New(method SigningMethod, opts ...TokenOption) *Token {
// claims. Additional options can be specified, but are currently unused.
func NewWithClaims(method SigningMethod, claims Claims, opts ...TokenOption) *Token {
return &Token{
- Header: map[string]interface{}{
+ Header: map[string]any{
"typ": "JWT",
"alg": method.Alg(),
},
@@ -60,7 +60,7 @@ func NewWithClaims(method SigningMethod, claims Claims, opts ...TokenOption) *To
// https://golang-jwt.github.io/jwt/usage/signing_methods/#signing-methods-and-key-types
// for an overview of the different signing methods and their respective key
// types.
-func (t *Token) SignedString(key interface{}) (string, error) {
+func (t *Token) SignedString(key any) (string, error) {
sstr, err := t.SigningString()
if err != nil {
return "", err
diff --git a/vendor/github.com/golang-jwt/jwt/v5/types.go b/vendor/github.com/golang-jwt/jwt/v5/types.go
index b2655a9e6..a3e0ef121 100644
--- a/vendor/github.com/golang-jwt/jwt/v5/types.go
+++ b/vendor/github.com/golang-jwt/jwt/v5/types.go
@@ -103,7 +103,7 @@ func (date *NumericDate) UnmarshalJSON(b []byte) (err error) {
type ClaimStrings []string
func (s *ClaimStrings) UnmarshalJSON(data []byte) (err error) {
- var value interface{}
+ var value any
if err = json.Unmarshal(data, &value); err != nil {
return err
@@ -116,7 +116,7 @@ func (s *ClaimStrings) UnmarshalJSON(data []byte) (err error) {
aud = append(aud, v)
case []string:
aud = ClaimStrings(v)
- case []interface{}:
+ case []any:
for _, vv := range v {
vs, ok := vv.(string)
if !ok {
diff --git a/vendor/github.com/golang-jwt/jwt/v5/validator.go b/vendor/github.com/golang-jwt/jwt/v5/validator.go
index 008ecd871..92b5c057c 100644
--- a/vendor/github.com/golang-jwt/jwt/v5/validator.go
+++ b/vendor/github.com/golang-jwt/jwt/v5/validator.go
@@ -1,8 +1,8 @@
package jwt
import (
- "crypto/subtle"
"fmt"
+ "slices"
"time"
)
@@ -52,8 +52,12 @@ type Validator struct {
verifyIat bool
// expectedAud contains the audience this token expects. Supplying an empty
- // string will disable aud checking.
- expectedAud string
+ // slice will disable aud checking.
+ expectedAud []string
+
+ // expectAllAud specifies whether all expected audiences must be present in
+ // the token. If false, only one of the expected audiences must be present.
+ expectAllAud bool
// expectedIss contains the issuer this token expects. Supplying an empty
// string will disable iss checking.
@@ -88,7 +92,7 @@ func NewValidator(opts ...ParserOption) *Validator {
func (v *Validator) Validate(claims Claims) error {
var (
now time.Time
- errs []error = make([]error, 0, 6)
+ errs = make([]error, 0, 6)
err error
)
@@ -120,8 +124,8 @@ func (v *Validator) Validate(claims Claims) error {
}
// If we have an expected audience, we also require the audience claim
- if v.expectedAud != "" {
- if err = v.verifyAudience(claims, v.expectedAud, true); err != nil {
+ if len(v.expectedAud) > 0 {
+ if err = v.verifyAudience(claims, v.expectedAud, v.expectAllAud); err != nil {
errs = append(errs, err)
}
}
@@ -226,33 +230,39 @@ func (v *Validator) verifyNotBefore(claims Claims, cmp time.Time, required bool)
//
// Additionally, if any error occurs while retrieving the claim, e.g., when its
// the wrong type, an ErrTokenUnverifiable error will be returned.
-func (v *Validator) verifyAudience(claims Claims, cmp string, required bool) error {
+func (v *Validator) verifyAudience(claims Claims, cmp []string, expectAllAud bool) error {
aud, err := claims.GetAudience()
if err != nil {
return err
}
- if len(aud) == 0 {
+ // Check that aud exists and is not empty. We only require the aud claim
+ // if we expect at least one audience to be present.
+ if len(aud) == 0 || len(aud) == 1 && aud[0] == "" {
+ required := len(v.expectedAud) > 0
return errorIfRequired(required, "aud")
}
- // use a var here to keep constant time compare when looping over a number of claims
- result := false
-
- var stringClaims string
- for _, a := range aud {
- if subtle.ConstantTimeCompare([]byte(a), []byte(cmp)) != 0 {
- result = true
+ if !expectAllAud {
+ for _, a := range aud {
+ // If we only expect one match, we can stop early if we find a match
+ if slices.Contains(cmp, a) {
+ return nil
+ }
}
- stringClaims = stringClaims + a
+
+ return ErrTokenInvalidAudience
}
- // case where "" is sent in one or many aud claims
- if stringClaims == "" {
- return errorIfRequired(required, "aud")
+ // Note that we are looping cmp here to ensure that all expected audiences
+ // are present in the aud claim.
+ for _, a := range cmp {
+ if !slices.Contains(aud, a) {
+ return ErrTokenInvalidAudience
+ }
}
- return errorIfFalse(result, ErrTokenInvalidAudience)
+ return nil
}
// verifyIssuer compares the iss claim in claims against cmp.
diff --git a/vendor/modules.txt b/vendor/modules.txt
index 6e8815d2d..9bebc0458 100644
--- a/vendor/modules.txt
+++ b/vendor/modules.txt
@@ -10,7 +10,7 @@ dario.cat/mergo
# github.com/42wim/httpsig v1.2.3
## explicit; go 1.23.0
github.com/42wim/httpsig
-# github.com/Azure/azure-sdk-for-go/sdk/azcore v1.18.0
+# github.com/Azure/azure-sdk-for-go/sdk/azcore v1.19.1
## explicit; go 1.23.0
github.com/Azure/azure-sdk-for-go/sdk/azcore
github.com/Azure/azure-sdk-for-go/sdk/azcore/arm/internal/resource
@@ -31,11 +31,11 @@ github.com/Azure/azure-sdk-for-go/sdk/azcore/policy
github.com/Azure/azure-sdk-for-go/sdk/azcore/runtime
github.com/Azure/azure-sdk-for-go/sdk/azcore/streaming
github.com/Azure/azure-sdk-for-go/sdk/azcore/tracing
-# github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.10.0
+# github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.12.0
## explicit; go 1.23.0
github.com/Azure/azure-sdk-for-go/sdk/azidentity
github.com/Azure/azure-sdk-for-go/sdk/azidentity/internal
-# github.com/Azure/azure-sdk-for-go/sdk/internal v1.11.1
+# github.com/Azure/azure-sdk-for-go/sdk/internal v1.11.2
## explicit; go 1.23.0
github.com/Azure/azure-sdk-for-go/sdk/internal/diag
github.com/Azure/azure-sdk-for-go/sdk/internal/errorinfo
@@ -48,7 +48,7 @@ github.com/Azure/azure-sdk-for-go/sdk/internal/uuid
## explicit; go 1.16
github.com/Azure/go-ansiterm
github.com/Azure/go-ansiterm/winterm
-# github.com/AzureAD/microsoft-authentication-library-for-go v1.4.2
+# github.com/AzureAD/microsoft-authentication-library-for-go v1.5.0
## explicit; go 1.18
github.com/AzureAD/microsoft-authentication-library-for-go/apps/cache
github.com/AzureAD/microsoft-authentication-library-for-go/apps/confidential
@@ -395,8 +395,8 @@ github.com/gogo/protobuf/sortkeys
# github.com/golang-jwt/jwt/v4 v4.5.2
## explicit; go 1.16
github.com/golang-jwt/jwt/v4
-# github.com/golang-jwt/jwt/v5 v5.2.2
-## explicit; go 1.18
+# github.com/golang-jwt/jwt/v5 v5.3.0
+## explicit; go 1.21
github.com/golang-jwt/jwt/v5
# github.com/golang/groupcache v0.0.0-20241129210726-2c02b8208cf8
## explicit; go 1.20