...
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15 package credentials
16
17 import (
18 "context"
19 "crypto/rsa"
20 "fmt"
21 "strings"
22 "time"
23
24 "cloud.google.com/go/auth"
25 "cloud.google.com/go/auth/internal"
26 "cloud.google.com/go/auth/internal/credsfile"
27 "cloud.google.com/go/auth/internal/jwt"
28 )
29
30 var (
31
32 now func() time.Time = time.Now
33 )
34
35
36
37 func configureSelfSignedJWT(f *credsfile.ServiceAccountFile, opts *DetectOptions) (auth.TokenProvider, error) {
38 pk, err := internal.ParseKey([]byte(f.PrivateKey))
39 if err != nil {
40 return nil, fmt.Errorf("credentials: could not parse key: %w", err)
41 }
42 return &selfSignedTokenProvider{
43 email: f.ClientEmail,
44 audience: opts.Audience,
45 scopes: opts.scopes(),
46 pk: pk,
47 pkID: f.PrivateKeyID,
48 }, nil
49 }
50
51 type selfSignedTokenProvider struct {
52 email string
53 audience string
54 scopes []string
55 pk *rsa.PrivateKey
56 pkID string
57 }
58
59 func (tp *selfSignedTokenProvider) Token(context.Context) (*auth.Token, error) {
60 iat := now()
61 exp := iat.Add(time.Hour)
62 scope := strings.Join(tp.scopes, " ")
63 c := &jwt.Claims{
64 Iss: tp.email,
65 Sub: tp.email,
66 Aud: tp.audience,
67 Scope: scope,
68 Iat: iat.Unix(),
69 Exp: exp.Unix(),
70 }
71 h := &jwt.Header{
72 Algorithm: jwt.HeaderAlgRSA256,
73 Type: jwt.HeaderType,
74 KeyID: string(tp.pkID),
75 }
76 msg, err := jwt.EncodeJWS(h, c, tp.pk)
77 if err != nil {
78 return nil, fmt.Errorf("credentials: could not encode JWT: %w", err)
79 }
80 return &auth.Token{Value: msg, Type: internal.TokenTypeBearer, Expiry: exp}, nil
81 }
82
View as plain text