Skip to content

Commit

Permalink
🧹 Unify az auth methods (#3698)
Browse files Browse the repository at this point in the history
* 🧹 Move the az auth helpers to cnquery.

Signed-off-by: Preslav <[email protected]>

* 🧹 Unify azure/ms365 token auth into one module.

Signed-off-by: Preslav <[email protected]>

* Reword functions.

---------

Signed-off-by: Preslav <[email protected]>
  • Loading branch information
preslavgerchev authored Apr 4, 2024
1 parent 403df5b commit 25745b6
Show file tree
Hide file tree
Showing 12 changed files with 153 additions and 107 deletions.
12 changes: 10 additions & 2 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -338,7 +338,7 @@ require (
github.com/oklog/run v1.1.0 // indirect
github.com/opencontainers/go-digest v1.0.0 // indirect
github.com/pelletier/go-toml/v2 v2.2.0 // indirect
github.com/pkg/errors v0.9.1 // indirect
github.com/pkg/errors v0.9.1
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect
github.com/polyfloyd/go-errorlint v1.4.8 // indirect
github.com/prometheus/client_golang v1.19.0 // indirect
Expand Down Expand Up @@ -418,14 +418,22 @@ require (
sigs.k8s.io/structured-merge-diff/v4 v4.4.1 // indirect
)

require github.com/patrickmn/go-cache v2.1.0+incompatible
require (
github.com/Azure/azure-sdk-for-go/sdk/azcore v1.11.1
github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.5.1
github.com/patrickmn/go-cache v2.1.0+incompatible
)

require (
github.com/Azure/azure-sdk-for-go/sdk/internal v1.5.2 // indirect
github.com/Azure/go-ansiterm v0.0.0-20230124172434-306776ec8161 // indirect
github.com/AzureAD/microsoft-authentication-library-for-go v1.2.1 // indirect
github.com/ckaznocha/intrange v0.1.1 // indirect
github.com/golangci/plugin-module-register v0.1.1 // indirect
github.com/karamaru-alpha/copyloopvar v1.0.9 // indirect
github.com/kylelemons/godebug v1.1.0 // indirect
github.com/moby/docker-image-spec v1.3.1 // indirect
github.com/pkg/browser v0.0.0-20240102092130-5ac0b6a4141c // indirect
github.com/santhosh-tekuri/jsonschema/v5 v5.3.1 // indirect
go.uber.org/automaxprocs v1.5.3 // indirect
)
12 changes: 12 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -84,10 +84,18 @@ github.com/Antonboom/nilnil v0.1.7 h1:ofgL+BA7vlA1K2wNQOsHzLJ2Pw5B5DpWRLdDAVvvTo
github.com/Antonboom/nilnil v0.1.7/go.mod h1:TP+ScQWVEq0eSIxqU8CbdT5DFWoHp0MbP+KMUO1BKYQ=
github.com/Antonboom/testifylint v1.2.0 h1:015bxD8zc5iY8QwTp4+RG9I4kIbqwvGX9TrBbb7jGdM=
github.com/Antonboom/testifylint v1.2.0/go.mod h1:rkmEqjqVnHDRNsinyN6fPSLnoajzFwsCcguJgwADBkw=
github.com/Azure/azure-sdk-for-go/sdk/azcore v1.11.1 h1:E+OJmp2tPvt1W+amx48v1eqbjDYsgN+RzP4q16yV5eM=
github.com/Azure/azure-sdk-for-go/sdk/azcore v1.11.1/go.mod h1:a6xsAQUZg+VsS3TJ05SRp524Hs4pZ/AeFSr5ENf0Yjo=
github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.5.1 h1:sO0/P7g68FrryJzljemN+6GTssUXdANk6aJ7T1ZxnsQ=
github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.5.1/go.mod h1:h8hyGFDsU5HMivxiS2iYFZsgDbU9OnnJ163x5UGVKYo=
github.com/Azure/azure-sdk-for-go/sdk/internal v1.5.2 h1:LqbJ/WzJUwBf8UiaSzgX7aMclParm9/5Vgp+TY51uBQ=
github.com/Azure/azure-sdk-for-go/sdk/internal v1.5.2/go.mod h1:yInRyqWXAuaPrgI7p70+lDDgh3mlBohis29jGMISnmc=
github.com/Azure/go-ansiterm v0.0.0-20230124172434-306776ec8161 h1:L/gRVlceqvL25UVaW/CKtUDjefjrs0SPonmDGUVOYP0=
github.com/Azure/go-ansiterm v0.0.0-20230124172434-306776ec8161/go.mod h1:xomTg63KZ2rFqZQzSB4Vz2SUXa1BpHTVz9L5PTmPC4E=
github.com/Azure/go-ntlmssp v0.0.0-20221128193559-754e69321358 h1:mFRzDkZVAjdal+s7s0MwaRv9igoPqLRdzOLzw/8Xvq8=
github.com/Azure/go-ntlmssp v0.0.0-20221128193559-754e69321358/go.mod h1:chxPXzSsl7ZWRAuOIE23GDNzjWuZquvFlgA8xmpunjU=
github.com/AzureAD/microsoft-authentication-library-for-go v1.2.1 h1:DzHpqpoJVaCgOUdVHxE8QB52S6NiVdDQvGlny1qvPqA=
github.com/AzureAD/microsoft-authentication-library-for-go v1.2.1/go.mod h1:wP83P5OoQ5p6ip3ScPr0BAq0BvuPAvacpEuSzyouqAI=
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
github.com/BurntSushi/toml v0.4.1/go.mod h1:CxXYINrC8qIiEnFrOxCa7Jy5BFHlXnUU2pbicEuybxQ=
github.com/BurntSushi/toml v1.3.2 h1:o7IhLm0Msx3BaB+n3Ag7L8EVlByGnpq14C4YWiu/gL8=
Expand Down Expand Up @@ -321,6 +329,8 @@ github.com/denis-tingaikin/go-header v0.5.0/go.mod h1:mMenU5bWrok6Wl2UsZjy+1okeg
github.com/dgrijalva/jwt-go/v4 v4.0.0-preview1/go.mod h1:+hnT3ywWDTAFrW5aE+u2Sa/wT555ZqwoCS+pk3p6ry4=
github.com/distribution/reference v0.5.0 h1:/FUIFXtfc/x2gpa5/VGfiGLuOIdYa1t65IKK2OFGvA0=
github.com/distribution/reference v0.5.0/go.mod h1:BbU0aIcezP1/5jX/8MP0YiH4SdvB5Y4f/wlDRiLyi3E=
github.com/dnaeon/go-vcr v1.2.0 h1:zHCHvJYTMh1N7xnV7zf1m1GPBF9Ad0Jk/whtQ1663qI=
github.com/dnaeon/go-vcr v1.2.0/go.mod h1:R4UdLID7HZT3taECzJs4YgbbH6PIGXB6W/sc5OLb6RQ=
github.com/docker/cli v26.0.0+incompatible h1:90BKrx1a1HKYpSnnBFR6AgDq/FqkHxwlUyzJVPxD30I=
github.com/docker/cli v26.0.0+incompatible/go.mod h1:JLrzqnKDaYBop7H2jaqPtU4hHvMKP+vjCwu2uszcLI8=
github.com/docker/distribution v2.8.3+incompatible h1:AtKxIZ36LoNK51+Z6RpzLpddBirtxJnzDrHLEKxTAYk=
Expand Down Expand Up @@ -909,6 +919,8 @@ github.com/pingcap/errors v0.11.4 h1:lFuQV/oaUMGcD2tqt+01ROSmJs75VG1ToEOkZIZ4nE4
github.com/pingcap/errors v0.11.4/go.mod h1:Oi8TUi2kEtXXLMJk9l1cGmz20kV3TaQ0usTwv5KuLY8=
github.com/pjbgf/sha1cd v0.3.0 h1:4D5XXmUUBUl/xQ6IjCkEAbqXskkq/4O7LmGn0AqMDs4=
github.com/pjbgf/sha1cd v0.3.0/go.mod h1:nZ1rrWOcGJ5uZgEEVL1VUM9iRQiZvWdbZjkKyFzPPsI=
github.com/pkg/browser v0.0.0-20240102092130-5ac0b6a4141c h1:+mdjkGKdHQG3305AYmdv1U2eRNDiU2ErMBj1gwrq8eQ=
github.com/pkg/browser v0.0.0-20240102092130-5ac0b6a4141c/go.mod h1:7rwL4CYBLnjLxUqIJNnCWiEdr3bn6IUYi15bNlnbCCU=
github.com/pkg/diff v0.0.0-20210226163009-20ebb0f2a09e/go.mod h1:pJLUxLENpZxwdsKMEsNbx1VGcRFpLqf3715MtcvvzbA=
github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
Expand Down
116 changes: 116 additions & 0 deletions providers-sdk/v1/util/azauth/token.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,116 @@
// Copyright (c) Mondoo, Inc.
// SPDX-License-Identifier: BUSL-1.1

package azauth

import (
"context"
"fmt"
"strings"
"time"

"github.com/Azure/azure-sdk-for-go/sdk/azcore"
"github.com/Azure/azure-sdk-for-go/sdk/azcore/policy"
"github.com/Azure/azure-sdk-for-go/sdk/azidentity"
"github.com/pkg/errors"
"github.com/rs/zerolog/log"
"go.mondoo.com/cnquery/v10/providers-sdk/v1/vault"
)

// sometimes we run into a 'managed identity timed out' error when using a managed identity.
// according to https://github.com/Azure/azure-sdk-for-go/blob/main/sdk/azidentity/TROUBLESHOOTING.md#troubleshoot-defaultazurecredential-authentication-issues
// we should instead use the NewManagedIdentityCredential directly.
// This function mimics the behavior of the DefaultAzureCredential, but with a higher timeout on the managed identity
func GetChainedToken(options *azidentity.DefaultAzureCredentialOptions) (*azidentity.ChainedTokenCredential, error) {
if options == nil {
options = &azidentity.DefaultAzureCredentialOptions{}
}

chain := []azcore.TokenCredential{}

cli, err := azidentity.NewAzureCLICredential(&azidentity.AzureCLICredentialOptions{})
if err == nil {
chain = append(chain, cli)
}
envCred, err := azidentity.NewEnvironmentCredential(&azidentity.EnvironmentCredentialOptions{ClientOptions: options.ClientOptions})
if err == nil {
chain = append(chain, envCred)
}
mic, err := azidentity.NewManagedIdentityCredential(&azidentity.ManagedIdentityCredentialOptions{ClientOptions: options.ClientOptions})
if err == nil {
timedMic := &timedManagedIdentityCredential{mic: *mic, timeout: 5 * time.Second}
chain = append(chain, timedMic)
}
wic, err := azidentity.NewWorkloadIdentityCredential(&azidentity.WorkloadIdentityCredentialOptions{
ClientOptions: options.ClientOptions,
DisableInstanceDiscovery: options.DisableInstanceDiscovery,
TenantID: options.TenantID,
})
if err == nil {
chain = append(chain, wic)
}

return azidentity.NewChainedTokenCredential(chain, nil)
}

type timedManagedIdentityCredential struct {
mic azidentity.ManagedIdentityCredential
timeout time.Duration
}

func (t *timedManagedIdentityCredential) GetToken(ctx context.Context, opts policy.TokenRequestOptions) (azcore.AccessToken, error) {
ctx, cancel := context.WithTimeout(ctx, t.timeout)
defer cancel()
var tk azcore.AccessToken
var err error
if t.timeout > 0 {
c, cancel := context.WithTimeout(ctx, t.timeout)
defer cancel()
tk, err = t.mic.GetToken(c, opts)
if err != nil {
var authFailedErr *azidentity.AuthenticationFailedError
if errors.As(err, &authFailedErr) && strings.Contains(err.Error(), "context deadline exceeded") {
err = azidentity.NewCredentialUnavailableError("managed identity request timed out")
}
} else {
// some managed identity implementation is available, so don't apply the timeout to future calls
t.timeout = 0
}
} else {
tk, err = t.mic.GetToken(ctx, opts)
}
return tk, err
}

func GetTokenFromCredential(credential *vault.Credential, tenantId, clientId string) (azcore.TokenCredential, error) {
var azCred azcore.TokenCredential
var err error
// fallback to default authorizer if no credentials are specified
if credential == nil {
log.Debug().Msg("using default azure token chain resolver")
azCred, err = GetChainedToken(&azidentity.DefaultAzureCredentialOptions{})
if err != nil {
return nil, errors.Wrap(err, "error creating CLI credentials")
}
} else {
switch credential.Type {
case vault.CredentialType_pkcs12:
certs, privateKey, err := azidentity.ParseCertificates(credential.Secret, []byte(credential.Password))
if err != nil {
return nil, errors.Wrap(err, fmt.Sprintf("could not parse provided certificate at %s", credential.PrivateKeyPath))
}
azCred, err = azidentity.NewClientCertificateCredential(tenantId, clientId, certs, privateKey, &azidentity.ClientCertificateCredentialOptions{})
if err != nil {
return nil, errors.Wrap(err, "error creating credentials from a certificate")
}
case vault.CredentialType_password:
azCred, err = azidentity.NewClientSecretCredential(tenantId, clientId, string(credential.Secret), &azidentity.ClientSecretCredentialOptions{})
if err != nil {
return nil, errors.Wrap(err, "error creating credentials from a secret")
}
default:
return nil, errors.New("invalid secret configuration for microsoft transport: " + credential.Type.String())
}
}
return azCred, nil
}
47 changes: 0 additions & 47 deletions providers/azure/connection/auth/auth.go

This file was deleted.

4 changes: 2 additions & 2 deletions providers/azure/connection/azureinstancesnapshot/provider.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,8 @@ import (
"go.mondoo.com/cnquery/v10/mrn"
"go.mondoo.com/cnquery/v10/providers-sdk/v1/inventory"
"go.mondoo.com/cnquery/v10/providers-sdk/v1/plugin"
"go.mondoo.com/cnquery/v10/providers-sdk/v1/util/azauth"
"go.mondoo.com/cnquery/v10/providers-sdk/v1/vault"
"go.mondoo.com/cnquery/v10/providers/azure/connection/auth"
"go.mondoo.com/cnquery/v10/providers/azure/connection/shared"
"go.mondoo.com/cnquery/v10/providers/os/connection/fs"
"go.mondoo.com/cnquery/v10/providers/os/connection/local"
Expand Down Expand Up @@ -133,7 +133,7 @@ func NewAzureSnapshotConnection(id uint32, conf *inventory.Config, asset *invent
if len(conf.Credentials) > 0 {
cred = conf.Credentials[0]
}
token, err := auth.GetTokenCredential(cred, conf.Options["tenant-id"], conf.Options["client-id"])
token, err := azauth.GetTokenFromCredential(cred, conf.Options["tenant-id"], conf.Options["client-id"])
if err != nil {
return nil, err
}
Expand Down
4 changes: 2 additions & 2 deletions providers/azure/connection/connection.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,8 @@ import (
"github.com/pkg/errors"
"go.mondoo.com/cnquery/v10/providers-sdk/v1/inventory"
"go.mondoo.com/cnquery/v10/providers-sdk/v1/plugin"
"go.mondoo.com/cnquery/v10/providers-sdk/v1/util/azauth"
"go.mondoo.com/cnquery/v10/providers-sdk/v1/vault"
"go.mondoo.com/cnquery/v10/providers/azure/connection/auth"
"go.mondoo.com/cnquery/v10/providers/azure/connection/shared"
)

Expand Down Expand Up @@ -42,7 +42,7 @@ func NewAzureConnection(id uint32, asset *inventory.Asset, conf *inventory.Confi
cred = conf.Credentials[0]
}

token, err := auth.GetTokenCredential(cred, tenantId, clientId)
token, err := azauth.GetTokenFromCredential(cred, tenantId, clientId)
if err != nil {
return nil, errors.Wrap(err, "cannot fetch credentials for microsoft provider")
}
Expand Down
4 changes: 2 additions & 2 deletions providers/azure/go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,7 @@ go 1.22
toolchain go1.22.0

require (
github.com/Azure/azure-sdk-for-go/sdk/azcore v1.10.0
github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.5.1
github.com/Azure/azure-sdk-for-go/sdk/azcore v1.11.1
github.com/Azure/azure-sdk-for-go/sdk/data/aztables v1.2.0
github.com/Azure/azure-sdk-for-go/sdk/keyvault/azcertificates v0.9.0
github.com/Azure/azure-sdk-for-go/sdk/keyvault/azkeys v0.10.0
Expand Down Expand Up @@ -56,6 +55,7 @@ require (
github.com/Antonboom/errname v0.1.12 // indirect
github.com/Antonboom/nilnil v0.1.7 // indirect
github.com/Antonboom/testifylint v1.2.0 // indirect
github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.5.1 // indirect
github.com/Azure/azure-sdk-for-go/sdk/internal v1.5.2 // indirect
github.com/Azure/azure-sdk-for-go/sdk/keyvault/internal v0.7.1 // indirect
github.com/AzureAD/microsoft-authentication-library-for-go v1.2.2 // indirect
Expand Down
4 changes: 2 additions & 2 deletions providers/azure/go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -63,8 +63,8 @@ github.com/Antonboom/nilnil v0.1.7 h1:ofgL+BA7vlA1K2wNQOsHzLJ2Pw5B5DpWRLdDAVvvTo
github.com/Antonboom/nilnil v0.1.7/go.mod h1:TP+ScQWVEq0eSIxqU8CbdT5DFWoHp0MbP+KMUO1BKYQ=
github.com/Antonboom/testifylint v1.2.0 h1:015bxD8zc5iY8QwTp4+RG9I4kIbqwvGX9TrBbb7jGdM=
github.com/Antonboom/testifylint v1.2.0/go.mod h1:rkmEqjqVnHDRNsinyN6fPSLnoajzFwsCcguJgwADBkw=
github.com/Azure/azure-sdk-for-go/sdk/azcore v1.10.0 h1:n1DH8TPV4qqPTje2RcUBYwtrTWlabVp4n46+74X2pn4=
github.com/Azure/azure-sdk-for-go/sdk/azcore v1.10.0/go.mod h1:HDcZnuGbiyppErN6lB+idp4CKhjbc8gwjto6OPpyggM=
github.com/Azure/azure-sdk-for-go/sdk/azcore v1.11.1 h1:E+OJmp2tPvt1W+amx48v1eqbjDYsgN+RzP4q16yV5eM=
github.com/Azure/azure-sdk-for-go/sdk/azcore v1.11.1/go.mod h1:a6xsAQUZg+VsS3TJ05SRp524Hs4pZ/AeFSr5ENf0Yjo=
github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.5.1 h1:sO0/P7g68FrryJzljemN+6GTssUXdANk6aJ7T1ZxnsQ=
github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.5.1/go.mod h1:h8hyGFDsU5HMivxiS2iYFZsgDbU9OnnJ163x5UGVKYo=
github.com/Azure/azure-sdk-for-go/sdk/data/aztables v1.2.0 h1:aJG+Jxd9/rrLwf8R1Ko0RlOBTJASs/lGQJ8b9AdlKTc=
Expand Down
44 changes: 0 additions & 44 deletions providers/ms365/connection/auth.go

This file was deleted.

3 changes: 2 additions & 1 deletion providers/ms365/connection/connection.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import (
msgrapgh_org "github.com/microsoftgraph/msgraph-sdk-go/organization"
"go.mondoo.com/cnquery/v10/providers-sdk/v1/inventory"
"go.mondoo.com/cnquery/v10/providers-sdk/v1/plugin"
"go.mondoo.com/cnquery/v10/providers-sdk/v1/util/azauth"
"go.mondoo.com/cnquery/v10/providers-sdk/v1/vault"
"go.mondoo.com/cnquery/v10/providers/os/connection/local"
"go.mondoo.com/cnquery/v10/providers/os/connection/shared"
Expand Down Expand Up @@ -50,7 +51,7 @@ func NewMs365Connection(id uint32, asset *inventory.Asset, conf *inventory.Confi
if len(tenantId) == 0 {
return nil, errors.New("ms365 backend requires a tenant-id")
}
token, err := getTokenCredential(cred, tenantId, clientId)
token, err := azauth.GetTokenFromCredential(cred, tenantId, clientId)
if err != nil {
return nil, errors.Wrap(err, "cannot fetch credentials for microsoft provider")
}
Expand Down
6 changes: 3 additions & 3 deletions providers/ms365/go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -7,14 +7,12 @@ go 1.22
toolchain go1.22.0

require (
github.com/Azure/azure-sdk-for-go/sdk/azcore v1.10.0
github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.5.1
github.com/Azure/azure-sdk-for-go/sdk/azcore v1.11.1
github.com/cockroachdb/errors v1.11.1
github.com/microsoft/kiota-abstractions-go v1.6.0
github.com/microsoft/kiota-authentication-azure-go v1.0.2
github.com/microsoftgraph/msgraph-sdk-go v1.37.0
github.com/microsoftgraph/msgraph-sdk-go-core v1.1.0
github.com/pkg/errors v0.9.1
github.com/rs/zerolog v1.32.0
github.com/stretchr/testify v1.9.0
go.mondoo.com/cnquery/v10 v10.9.1
Expand All @@ -37,6 +35,7 @@ require (
github.com/Antonboom/errname v0.1.12 // indirect
github.com/Antonboom/nilnil v0.1.7 // indirect
github.com/Antonboom/testifylint v1.2.0 // indirect
github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.5.1 // indirect
github.com/Azure/azure-sdk-for-go/sdk/internal v1.5.2 // indirect
github.com/AzureAD/microsoft-authentication-library-for-go v1.2.2 // indirect
github.com/BurntSushi/toml v1.3.2 // indirect
Expand Down Expand Up @@ -206,6 +205,7 @@ require (
github.com/olekukonko/tablewriter v0.0.5 // indirect
github.com/pelletier/go-toml/v2 v2.2.0 // indirect
github.com/pkg/browser v0.0.0-20240102092130-5ac0b6a4141c // indirect
github.com/pkg/errors v0.9.1 // indirect
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect
github.com/polyfloyd/go-errorlint v1.4.8 // indirect
github.com/prometheus/client_golang v1.19.0 // indirect
Expand Down
Loading

0 comments on commit 25745b6

Please sign in to comment.