From 90de6a06634f326ea35b964aede9e84393fbea77 Mon Sep 17 00:00:00 2001 From: Dan Lorenc <lorenc.d@gmail.com> Date: Sun, 12 Sep 2021 08:27:22 -0500 Subject: [PATCH] Support GCP environments without workload identity (GCB). This requires the use of an environment variable called "GOOGLE_SERVICE_ACCOUNT_NAME" to direct the client on which account to impersonate. Signed-off-by: Dan Lorenc <lorenc.d@gmail.com> --- go.mod | 3 +-- go.sum | 2 -- pkg/providers/google/google.go | 31 +++++++++++++++++++++++++++++++ 3 files changed, 32 insertions(+), 4 deletions(-) diff --git a/go.mod b/go.mod index 566030f5502b..fad82a7f6d49 100644 --- a/go.mod +++ b/go.mod @@ -23,7 +23,6 @@ require ( github.com/sigstore/fulcio v0.1.2-0.20210831152525-42f7422734bb github.com/sigstore/rekor v0.3.0 github.com/sigstore/sigstore v0.0.0-20210729211320-56a91f560f44 - github.com/spf13/pflag v1.0.5 github.com/stretchr/testify v1.7.0 github.com/theupdateframework/go-tuf v0.0.0-20210722233521-90e262754396 golang.org/x/mod v0.5.0 // indirect @@ -36,7 +35,7 @@ require ( k8s.io/api v0.22.1 k8s.io/apimachinery v0.22.1 k8s.io/client-go v0.22.1 - k8s.io/klog/v2 v2.10.0 + k8s.io/klog/v2 v2.10.0 // indirect ) require ( diff --git a/go.sum b/go.sum index f141a90f22c3..d51dca65b21a 100644 --- a/go.sum +++ b/go.sum @@ -2505,8 +2505,6 @@ k8s.io/utils v0.0.0-20210707171843-4b05e18ac7d9/go.mod h1:jPW/WVKK9YHAvNhRxK0md/ k8s.io/utils v0.0.0-20210802155522-efc7438f0176 h1:Mx0aa+SUAcNRQbs5jUzV8lkDlGFU8laZsY9jrcVX5SY= k8s.io/utils v0.0.0-20210802155522-efc7438f0176/go.mod h1:jPW/WVKK9YHAvNhRxK0md/EJ228hCsBRufyofKtW8HA= knative.dev/hack v0.0.0-20210806075220-815cd312d65c/go.mod h1:PHt8x8yX5Z9pPquBEfIj0X66f8iWkWfR0S/sarACJrI= -knative.dev/pkg v0.0.0-20210907232433-26db1ba732f6 h1:nLHaEQP+SNW4E6zsgSS6wwpHNpSpag8vw8SSsH4ILw8= -knative.dev/pkg v0.0.0-20210907232433-26db1ba732f6/go.mod h1:jMSqkNMsrzuy+XR4Yr/BMy7SDVbUOl3KKB6+5MR+ZU8= knative.dev/pkg v0.0.0-20210908025933-71508fc69a57 h1:du+do3to2zboxuk0Uj8Xvf2onOxthyaBSr98+hVB7z4= knative.dev/pkg v0.0.0-20210908025933-71508fc69a57/go.mod h1:jMSqkNMsrzuy+XR4Yr/BMy7SDVbUOl3KKB6+5MR+ZU8= nhooyr.io/websocket v1.8.6/go.mod h1:B70DZP8IakI65RVQ51MsWP/8jndNma26DVA/nFSCgW0= diff --git a/pkg/providers/google/google.go b/pkg/providers/google/google.go index 1e3edb0c056e..6daa2fcdd8e8 100644 --- a/pkg/providers/google/google.go +++ b/pkg/providers/google/google.go @@ -18,15 +18,18 @@ package google import ( "context" "io/ioutil" + "os" "strings" "google.golang.org/api/idtoken" + "google.golang.org/api/impersonate" "github.com/sigstore/cosign/pkg/providers" ) func init() { providers.Register("google-workload-identity", &googleWorkloadIdentity{}) + providers.Register("google-impersonate", &googleImpersonate{}) } type googleWorkloadIdentity struct{} @@ -66,3 +69,31 @@ func (gwi *googleWorkloadIdentity) Provide(ctx context.Context, audience string) } return tok.AccessToken, nil } + +type googleImpersonate struct{} + +var _ providers.Interface = (*googleImpersonate)(nil) + +// Enabled implements providers.Interface +func (gi *googleImpersonate) Enabled(ctx context.Context) bool { + // The "impersonate" method requires a target service account to impersonate. + return os.Getenv("GOOGLE_SERVICE_ACCOUNT_NAME") != "" +} + +// Provide implements providers.Interface +func (gi *googleImpersonate) Provide(ctx context.Context, audience string) (string, error) { + target := os.Getenv("GOOGLE_SERVICE_ACCOUNT_NAME") + ts, err := impersonate.IDTokenSource(ctx, impersonate.IDTokenConfig{ + Audience: "sigstore", + TargetPrincipal: target, + IncludeEmail: true, + }) + if err != nil { + return "", err + } + tok, err := ts.Token() + if err != nil { + return "", err + } + return tok.AccessToken, nil +}