From c55a248623f8f28321cf8ae6ad0a74b02ab0cdd5 Mon Sep 17 00:00:00 2001 From: jackofallops Date: Thu, 12 Jun 2025 16:19:27 +0200 Subject: [PATCH] add configurable IDMS API version for non-standard service implementations --- sdk/auth/auth.go | 7 ++++--- sdk/auth/config.go | 5 ++++- sdk/auth/managed_identity_authorizer.go | 19 ++++++++++++++----- 3 files changed, 22 insertions(+), 9 deletions(-) diff --git a/sdk/auth/auth.go b/sdk/auth/auth.go index fc56db91c3b..a731e5e30cc 100644 --- a/sdk/auth/auth.go +++ b/sdk/auth/auth.go @@ -133,9 +133,10 @@ func NewAuthorizerFromCredentials(ctx context.Context, c Credentials, api enviro if c.EnableAuthenticatingUsingManagedIdentity { opts := ManagedIdentityAuthorizerOptions{ - Api: api, - ClientId: c.ClientID, - CustomManagedIdentityEndpoint: c.CustomManagedIdentityEndpoint, + Api: api, + ClientId: c.ClientID, + CustomManagedIdentityEndpoint: c.CustomManagedIdentityEndpoint, + CustomManagedIdentityAPIVersion: c.CustomManagedIdentityAPIVersion, } a, err := NewManagedIdentityAuthorizer(ctx, opts) if err != nil { diff --git a/sdk/auth/config.go b/sdk/auth/config.go index 12a4dffd725..1b7b71e4d65 100644 --- a/sdk/auth/config.go +++ b/sdk/auth/config.go @@ -7,7 +7,7 @@ import ( "github.com/hashicorp/go-azure-sdk/sdk/environments" ) -// Credentials sets up NewAuthorizer to return an Authorizer based on the provided credentails. +// Credentials sets up NewAuthorizer to return an Authorizer based on the provided credentials. type Credentials struct { // Specifies the national cloud environment to use Environment environments.Environment @@ -44,6 +44,9 @@ type Credentials struct { // CustomManagedIdentityEndpoint specifies a custom endpoint which should be used for Managed Identity. CustomManagedIdentityEndpoint string + // CustomManagedIdentityAPIVersion specifies the API version to use for IMDS. + CustomManagedIdentityAPIVersion string + // Enables OIDC authentication (federated client credentials). EnableAuthenticationUsingOIDC bool // OIDCAssertionToken specifies the OIDC Assertion Token to authenticate using Client Credentials. diff --git a/sdk/auth/managed_identity_authorizer.go b/sdk/auth/managed_identity_authorizer.go index 718e6693d98..740880c939e 100644 --- a/sdk/auth/managed_identity_authorizer.go +++ b/sdk/auth/managed_identity_authorizer.go @@ -28,6 +28,10 @@ type ManagedIdentityAuthorizerOptions struct { // CustomManagedIdentityEndpoint is an optional endpoint from which to obtain an access // token. When blank, the default is used. CustomManagedIdentityEndpoint string + + // CustomManagedIdentityAPIVersion is an optional API version to use when requesting a token. + // This is required when using an endpoint that does not support the default API version such as Azure Container Apps. + CustomManagedIdentityAPIVersion string } // NewManagedIdentityAuthorizer returns an authorizer using a Managed Identity for authentication. @@ -36,7 +40,7 @@ func NewManagedIdentityAuthorizer(ctx context.Context, options ManagedIdentityAu if err != nil { return nil, fmt.Errorf("determining resource for api %q: %+v", options.Api.Name(), err) } - conf, err := newManagedIdentityConfig(*resource, options.ClientId, options.CustomManagedIdentityEndpoint) + conf, err := newManagedIdentityConfig(*resource, options.ClientId, options.CustomManagedIdentityEndpoint, options.CustomManagedIdentityAPIVersion) if err != nil { return nil, err } @@ -70,9 +74,9 @@ func (a *ManagedIdentityAuthorizer) Token(ctx context.Context, _ *http.Request) query["client_id"] = []string{a.conf.ClientID} } - url := fmt.Sprintf("%s?%s", a.conf.MsiEndpoint, query.Encode()) + u := fmt.Sprintf("%s?%s", a.conf.MsiEndpoint, query.Encode()) - body, err := azureMetadata(ctx, url) + body, err := azureMetadata(ctx, u) if err != nil { return nil, fmt.Errorf("ManagedIdentityAuthorizer: failed to request token from metadata endpoint: %v", err) } @@ -135,16 +139,21 @@ type managedIdentityConfig struct { // newManagedIdentityConfig returns a new managedIdentityConfig with a configured metadata endpoint and resource. // clientId and objectId can be left blank when a single managed identity is available -func newManagedIdentityConfig(resource, clientId, customManagedIdentityEndpoint string) (*managedIdentityConfig, error) { +func newManagedIdentityConfig(resource, clientId, customManagedIdentityEndpoint string, customManagedIdentityAPIVersion string) (*managedIdentityConfig, error) { endpoint := msiDefaultEndpoint if customManagedIdentityEndpoint != "" { endpoint = customManagedIdentityEndpoint } + apiVersion := msiDefaultApiVersion + if customManagedIdentityAPIVersion != "" { + apiVersion = customManagedIdentityAPIVersion + } + return &managedIdentityConfig{ ClientID: clientId, Resource: resource, - MsiApiVersion: msiDefaultApiVersion, + MsiApiVersion: apiVersion, MsiEndpoint: endpoint, }, nil }