From cb4a6bc67fd95952042f034b829e8a9ea0f97793 Mon Sep 17 00:00:00 2001 From: Joseph Stevens Date: Sat, 12 Oct 2024 16:45:18 -0700 Subject: [PATCH] enable standard forms of GCP auth for oci sources Signed-off-by: Joseph Stevens --- oci/auth/gcp/auth.go | 54 +++++++++++------------------------- oci/go.mod | 3 +- oci/go.sum | 6 ++-- oci/tests/integration/go.mod | 3 +- oci/tests/integration/go.sum | 6 ++-- 5 files changed, 28 insertions(+), 44 deletions(-) diff --git a/oci/auth/gcp/auth.go b/oci/auth/gcp/auth.go index 584f0b25..4e017a53 100644 --- a/oci/auth/gcp/auth.go +++ b/oci/auth/gcp/auth.go @@ -18,10 +18,7 @@ package gcp import ( "context" - "encoding/json" "fmt" - "io" - "net/http" "net/url" "strings" "time" @@ -31,6 +28,7 @@ import ( "github.com/google/go-containerregistry/pkg/name" "github.com/fluxcd/pkg/oci" + "golang.org/x/oauth2/google" ) type gceToken struct { @@ -79,54 +77,34 @@ func (c *Client) WithTokenURL(url string) *Client { return c } -// getLoginAuth obtains authentication by getting a token from the metadata API -// on GCP. This assumes that the pod has right to pull the image which would be -// the case if it is hosted on GCP. It works with both service account and -// workload identity enabled clusters. +// getLoginAuth obtains authentication using the default GCP credential chain. +// This supports various authentication methods including service account JSON, +// external account JSON, user credentials, and GCE metadata service. func (c *Client) getLoginAuth(ctx context.Context) (authn.AuthConfig, time.Time, error) { var authConfig authn.AuthConfig - request, err := http.NewRequestWithContext(ctx, http.MethodGet, c.tokenURL, nil) - if err != nil { - return authConfig, time.Time{}, err - } - - request.Header.Add("Metadata-Flavor", "Google") - - var transport http.RoundTripper - if c.proxyURL != nil { - t := http.DefaultTransport.(*http.Transport).Clone() - t.Proxy = http.ProxyURL(c.proxyURL) - transport = t - } + // Define the required scopes for accessing GCR. + scopes := []string{"https://www.googleapis.com/auth/cloud-platform"} - client := &http.Client{Transport: transport} - response, err := client.Do(request) + // Obtain the default token source. + tokenSource, err := google.DefaultTokenSource(ctx, scopes...) if err != nil { - return authConfig, time.Time{}, err + return authConfig, time.Time{}, fmt.Errorf("failed to get default token source: %w", err) } - defer response.Body.Close() - defer io.Copy(io.Discard, response.Body) - if response.StatusCode != http.StatusOK { - return authConfig, time.Time{}, fmt.Errorf("unexpected status from metadata service: %s", response.Status) - } - - var accessToken gceToken - decoder := json.NewDecoder(response.Body) - if err := decoder.Decode(&accessToken); err != nil { - return authConfig, time.Time{}, err + // Retrieve the token. + token, err := tokenSource.Token() + if err != nil { + return authConfig, time.Time{}, fmt.Errorf("failed to obtain token: %w", err) } + // Set up the authentication configuration. authConfig = authn.AuthConfig{ Username: "oauth2accesstoken", - Password: accessToken.AccessToken, + Password: token.AccessToken, } - // add expiresIn seconds to the current time to get the expiry time - expiresAt := time.Now().Add(time.Duration(accessToken.ExpiresIn) * time.Second) - - return authConfig, expiresAt, nil + return authConfig, token.Expiry, nil } // Login attempts to get the authentication material for GCR. diff --git a/oci/go.mod b/oci/go.mod index 8cc1706f..68c2da10 100644 --- a/oci/go.mod +++ b/oci/go.mod @@ -26,9 +26,11 @@ require ( github.com/google/go-containerregistry v0.20.2 github.com/onsi/gomega v1.34.2 github.com/sirupsen/logrus v1.9.3 + golang.org/x/oauth2 v0.23.0 ) require ( + cloud.google.com/go/compute/metadata v0.3.0 // indirect github.com/Azure/azure-sdk-for-go/sdk/internal v1.10.0 // indirect github.com/AzureAD/microsoft-authentication-library-for-go v1.2.2 // indirect github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.16.13 // indirect @@ -136,7 +138,6 @@ require ( go.starlark.net v0.0.0-20230525235612-a134d8f9ddca // indirect golang.org/x/crypto v0.27.0 // indirect golang.org/x/net v0.29.0 // indirect - golang.org/x/oauth2 v0.22.0 // indirect golang.org/x/sync v0.8.0 // indirect golang.org/x/sys v0.25.0 // indirect golang.org/x/term v0.24.0 // indirect diff --git a/oci/go.sum b/oci/go.sum index 7ac23d2f..79bf0a28 100644 --- a/oci/go.sum +++ b/oci/go.sum @@ -1,4 +1,6 @@ cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= +cloud.google.com/go/compute/metadata v0.3.0 h1:Tz+eQXMEqDIKRsmY3cHTL6FVaynIjX2QxYC4trgAKZc= +cloud.google.com/go/compute/metadata v0.3.0/go.mod h1:zFmK7XCadkQkj6TtorcaGlCW1hT1fIilQDwofLpJ20k= github.com/Azure/azure-sdk-for-go/sdk/azcore v1.14.0 h1:nyQWyZvwGTvunIMxi1Y9uXkcyr+I7TeNrr/foo4Kpk8= github.com/Azure/azure-sdk-for-go/sdk/azcore v1.14.0/go.mod h1:l38EPgmsp71HHLq9j7De57JcKOWPyhrsW1Awm1JS6K0= github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.7.0 h1:tfLQ34V6F7tVSwoTf/4lH5sE0o6eCJuNDTmH09nDpbc= @@ -406,8 +408,8 @@ golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwY golang.org/x/net v0.29.0 h1:5ORfpBpCs4HzDYoodCDBbwHzdR5UrLBZ3sOnUJmFoHo= golang.org/x/net v0.29.0/go.mod h1:gLkgy8jTGERgjzMic6DS9+SP0ajcu6Xu3Orq/SpETg0= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= -golang.org/x/oauth2 v0.22.0 h1:BzDx2FehcG7jJwgWLELCdmLuxk2i+x9UDpSiss2u0ZA= -golang.org/x/oauth2 v0.22.0/go.mod h1:XYTD2NtWslqkgxebSiOHnXEap4TF09sJSc7H1sXbhtI= +golang.org/x/oauth2 v0.23.0 h1:PbgcYx2W7i4LvjJWEbf0ngHV6qJYr86PkAV3bXdLEbs= +golang.org/x/oauth2 v0.23.0/go.mod h1:XYTD2NtWslqkgxebSiOHnXEap4TF09sJSc7H1sXbhtI= golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= diff --git a/oci/tests/integration/go.mod b/oci/tests/integration/go.mod index 659ff987..84342771 100644 --- a/oci/tests/integration/go.mod +++ b/oci/tests/integration/go.mod @@ -30,6 +30,7 @@ require ( ) require ( + cloud.google.com/go/compute/metadata v0.3.0 // indirect dario.cat/mergo v1.0.1 // indirect github.com/Azure/azure-sdk-for-go/sdk/azcore v1.14.0 // indirect github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.7.0 // indirect @@ -131,7 +132,7 @@ require ( golang.org/x/exp v0.0.0-20240719175910-8a7402abbf56 // indirect golang.org/x/mod v0.21.0 // indirect golang.org/x/net v0.29.0 // indirect - golang.org/x/oauth2 v0.22.0 // indirect + golang.org/x/oauth2 v0.23.0 // indirect golang.org/x/sync v0.8.0 // indirect golang.org/x/sys v0.25.0 // indirect golang.org/x/term v0.24.0 // indirect diff --git a/oci/tests/integration/go.sum b/oci/tests/integration/go.sum index b5263679..3df784a7 100644 --- a/oci/tests/integration/go.sum +++ b/oci/tests/integration/go.sum @@ -1,4 +1,6 @@ cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= +cloud.google.com/go/compute/metadata v0.3.0 h1:Tz+eQXMEqDIKRsmY3cHTL6FVaynIjX2QxYC4trgAKZc= +cloud.google.com/go/compute/metadata v0.3.0/go.mod h1:zFmK7XCadkQkj6TtorcaGlCW1hT1fIilQDwofLpJ20k= dario.cat/mergo v1.0.1 h1:Ra4+bf83h2ztPIQYNP99R6m+Y7KfnARDfID+a+vLl4s= dario.cat/mergo v1.0.1/go.mod h1:uNxQE+84aUszobStD9th8a29P2fMDhsBdgRYvZOxGmk= github.com/Azure/azure-sdk-for-go/sdk/azcore v1.14.0 h1:nyQWyZvwGTvunIMxi1Y9uXkcyr+I7TeNrr/foo4Kpk8= @@ -368,8 +370,8 @@ golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qx golang.org/x/net v0.29.0 h1:5ORfpBpCs4HzDYoodCDBbwHzdR5UrLBZ3sOnUJmFoHo= golang.org/x/net v0.29.0/go.mod h1:gLkgy8jTGERgjzMic6DS9+SP0ajcu6Xu3Orq/SpETg0= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= -golang.org/x/oauth2 v0.22.0 h1:BzDx2FehcG7jJwgWLELCdmLuxk2i+x9UDpSiss2u0ZA= -golang.org/x/oauth2 v0.22.0/go.mod h1:XYTD2NtWslqkgxebSiOHnXEap4TF09sJSc7H1sXbhtI= +golang.org/x/oauth2 v0.23.0 h1:PbgcYx2W7i4LvjJWEbf0ngHV6qJYr86PkAV3bXdLEbs= +golang.org/x/oauth2 v0.23.0/go.mod h1:XYTD2NtWslqkgxebSiOHnXEap4TF09sJSc7H1sXbhtI= golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=