...
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 package google
17
18 import (
19 "context"
20 "os"
21 "strings"
22
23 "google.golang.org/api/idtoken"
24 "google.golang.org/api/impersonate"
25
26 "github.com/sigstore/cosign/v2/pkg/cosign/env"
27 "github.com/sigstore/cosign/v2/pkg/providers"
28 )
29
30 func init() {
31 providers.Register("google-workload-identity", &googleWorkloadIdentity{})
32 providers.Register("google-impersonate", &googleImpersonate{})
33 }
34
35 type googleWorkloadIdentity struct{}
36
37 var _ providers.Interface = (*googleWorkloadIdentity)(nil)
38
39
40
41 var gceProductNameFile = "/sys/class/dmi/id/product_name"
42
43
44
45 func (gwi *googleWorkloadIdentity) Enabled(ctx context.Context) bool {
46 data, err := os.ReadFile(gceProductNameFile)
47 if err != nil {
48 return false
49 }
50 name := strings.TrimSpace(string(data))
51 if name == "Google" || name == "Google Compute Engine" {
52
53
54 _, err := gwi.Provide(ctx, "garbage")
55 return err == nil
56 }
57 return false
58 }
59
60
61 func (gwi *googleWorkloadIdentity) Provide(ctx context.Context, audience string) (string, error) {
62 ts, err := idtoken.NewTokenSource(ctx, audience)
63 if err != nil {
64 return "", err
65 }
66 tok, err := ts.Token()
67 if err != nil {
68 return "", err
69 }
70 return tok.AccessToken, nil
71 }
72
73 type googleImpersonate struct{}
74
75 var _ providers.Interface = (*googleImpersonate)(nil)
76
77
78 func (gi *googleImpersonate) Enabled(_ context.Context) bool {
79
80 return env.Getenv(env.VariableGoogleServiceAccountName) != ""
81 }
82
83
84 func (gi *googleImpersonate) Provide(ctx context.Context, audience string) (string, error) {
85 target := env.Getenv(env.VariableGoogleServiceAccountName)
86 ts, err := impersonate.IDTokenSource(ctx, impersonate.IDTokenConfig{
87 Audience: audience,
88 TargetPrincipal: target,
89 IncludeEmail: true,
90 })
91 if err != nil {
92 return "", err
93 }
94 tok, err := ts.Token()
95 if err != nil {
96 return "", err
97 }
98 return tok.AccessToken, nil
99 }
100
View as plain text