Skip to content

Commit

Permalink
Authenticate with an Azure Workload Identity (AZWI) serviceaccount to…
Browse files Browse the repository at this point in the history
…ken when client secret is absent from auth config.
  • Loading branch information
abutcher committed Dec 5, 2022
1 parent cbf9759 commit 0461800
Showing 1 changed file with 65 additions and 8 deletions.
73 changes: 65 additions & 8 deletions pkg/dns/azure/client/auth.go
Original file line number Diff line number Diff line change
@@ -1,16 +1,56 @@
package client

import (
"context"
"os"
"strings"
"time"

"github.com/Azure/azure-sdk-for-go/sdk/azcore"
"github.com/Azure/azure-sdk-for-go/sdk/azcore/cloud"
"github.com/Azure/azure-sdk-for-go/sdk/azcore/policy"
"github.com/Azure/azure-sdk-for-go/sdk/azidentity"
"github.com/Azure/go-autorest/autorest"
"github.com/Azure/go-autorest/autorest/azure"
"github.com/jongio/azidext/go/azidext"
)

type workloadIdentityCredential struct {
assertion, file string
cred *azidentity.ClientAssertionCredential
lastRead time.Time
}

type workloadIdentityCredentialOptions struct {
azcore.ClientOptions
}

func newWorkloadIdentityCredential(tenantID, clientID, file string, options *workloadIdentityCredentialOptions) (*workloadIdentityCredential, error) {
w := &workloadIdentityCredential{file: file}
cred, err := azidentity.NewClientAssertionCredential(tenantID, clientID, w.getAssertion, &azidentity.ClientAssertionCredentialOptions{ClientOptions: options.ClientOptions})
if err != nil {
return nil, err
}
w.cred = cred
return w, nil
}

func (w *workloadIdentityCredential) GetToken(ctx context.Context, opts policy.TokenRequestOptions) (azcore.AccessToken, error) {
return w.cred.GetToken(ctx, opts)
}

func (w *workloadIdentityCredential) getAssertion(context.Context) (string, error) {
if now := time.Now(); w.lastRead.Add(5 * time.Minute).Before(now) {
content, err := os.ReadFile(w.file)
if err != nil {
return "", err
}
w.assertion = string(content)
w.lastRead = now
}
return w.assertion, nil
}

func getAuthorizerForResource(config Config) (autorest.Authorizer, error) {
var cloudConfig cloud.Configuration
switch config.Environment {
Expand All @@ -35,14 +75,31 @@ func getAuthorizerForResource(config Config) (autorest.Authorizer, error) {
},
}
}
options := azidentity.ClientSecretCredentialOptions{
ClientOptions: azcore.ClientOptions{
Cloud: cloudConfig,
},
}
cred, err := azidentity.NewClientSecretCredential(config.TenantID, config.ClientID, config.ClientSecret, &options)
if err != nil {
return nil, err

var (
cred azcore.TokenCredential
err error
)
if config.ClientSecret == "" {
options := workloadIdentityCredentialOptions{
ClientOptions: azcore.ClientOptions{
Cloud: cloudConfig,
},
}
cred, err = newWorkloadIdentityCredential(config.TenantID, config.ClientID, "/var/run/secrets/openshift/serviceaccount/token", &options)
if err != nil {
return nil, err
}
} else {
options := azidentity.ClientSecretCredentialOptions{
ClientOptions: azcore.ClientOptions{
Cloud: cloudConfig,
},
}
cred, err = azidentity.NewClientSecretCredential(config.TenantID, config.ClientID, config.ClientSecret, &options)
if err != nil {
return nil, err
}
}

scope := config.Environment.TokenAudience
Expand Down

0 comments on commit 0461800

Please sign in to comment.