Skip to content

Commit d2095c4

Browse files
author
Troels Liebe Bentsen
authored
Merge pull request #9 from connectedcars/gcloud-auth-support
Gcloud auth support
2 parents 56e6ca3 + 1793eee commit d2095c4

File tree

5 files changed

+203
-21
lines changed

5 files changed

+203
-21
lines changed

README.md

Lines changed: 86 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -142,11 +142,95 @@ ssh-keygen -f build.key
142142
ssh-keygen -f build.key -m 'PEM' -e > build.pem
143143
```
144144

145-
# Release new version
145+
# Development
146+
147+
## Release new version
146148

147149
``` bash
148150
export GITHUB_TOKEN="YOUR_GH_TOKEN"
149151
git tag -a v2.0.2 -m "Release 2.0.2"
150152
git push origin v2.0.2
151153
goreleaser release --rm-dist
152-
```
154+
```
155+
156+
## VSCode setup
157+
158+
settings.json
159+
``` json5
160+
{
161+
// Golang
162+
"go.useCodeSnippetsOnFunctionSuggest": true,
163+
"go.useLanguageServer": true,
164+
"go.alternateTools": {
165+
"go-languageserver": "gopls"
166+
},
167+
"go.buildOnSave": "off",
168+
"go.vetOnSave": "off",
169+
"go.useCodeSnippetsOnFunctionSuggestWithoutType": true,
170+
"go.docsTool": "gogetdoc",
171+
"editor.codeActionsOnSave": {
172+
"source.organizeImports": true
173+
}
174+
}
175+
```
176+
177+
launch.json
178+
``` json5
179+
{
180+
// Use IntelliSense to learn about possible attributes.
181+
// Hover to view descriptions of existing attributes.
182+
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
183+
"version": "0.2.0",
184+
"configurations": [
185+
{
186+
"name": "Launch",
187+
"type": "go",
188+
"request": "launch",
189+
"mode": "debug",
190+
"program": "${workspaceFolder}/cmd/authwrapper",
191+
"env": {
192+
"SSH_KEY_PATH": "kms://projects/yourprojectname/locations/global/keyRings/yourkeyring/cryptoKeys/ssh-key/cryptoKeyVersions/1",
193+
"SSH_SIGNING_SERVER_URL": "http://localhost:3080",
194+
//"SSH_PRINCIPALS": "tlb",
195+
196+
"SSH_SIGNING_SERVER_LISTEN_ADDRESS": ":3080",
197+
"SSH_CA_KEY_PATH": "kms://projects/yourprojectname/locations/global/keyRings/yourkeyring/cryptoKeys/ssh-key/cryptoKeyVersions/1",
198+
"SSH_CA_AUTHORIZED_KEYS_PATH": "${workspaceFolder}/authorized_keys",
199+
"SSH_SIGNING_LIFETIME": "60m",
200+
201+
//"SSH_KEY_PATH": "kms://projects/yourprojectname/locations/global/keyRings/yourkeyring/cryptoKeys/ssh-key/cryptoKeyVersions/1",
202+
"GIT_SSH_COMMAND": "ssh -vvvv",
203+
"DOCKER_BUILDKIT": "1",
204+
"PROGRESS_NO_TRUNC": "1",
205+
"SSH_AUTH_SOCK": ""
206+
},
207+
"args": [
208+
"-principals", "tlb",
209+
//"ssh-add", "-L"
210+
"ssh", "-p", "22", "-vv", "-l" ,"tlb", "1.2.4.5", "hostname"
211+
//"bash", "-c", "docker build --no-cache --progress=plain --ssh=default=$SSH_AUTH_SOCK .",
212+
//"docker", "build",
213+
//"--add-host=metadata.google.internal:192.168.65.2",
214+
//"--no-cache",
215+
//"--progress=plain",
216+
//"--ssh=default=$SSH_AUTH_SOCK",
217+
//"--build-arg=WRAP_IMAGE=gcr.io/cloud-builders/docker",
218+
//"--build-arg=WRAP_COMMAND=/usr/bin/docker",
219+
//"--build-arg=WRAP_NAME=docker",
220+
//"--build-arg=SSH_KEY_PATH=kms://projects/yourprojectname/locations/global/keyRings/yourkeyring/cryptoKeys/ssh-key/cryptoKeyVersions/1",
221+
//"."
222+
//"git", "clone", "git@github.com:connectedcars/private-module.git"
223+
],
224+
"showLog": true
225+
},
226+
{
227+
"name": "Launch test function",
228+
"type": "go",
229+
"request": "launch",
230+
"mode": "test",
231+
"program": "${workspaceFolder}/cmd/main_test.go",
232+
"args": ["-test.timeout", "999s"]
233+
},
234+
]
235+
}
236+
```

go.mod

Lines changed: 15 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,28 @@
11
module github.com/connectedcars/auth-wrapper
22

3-
go 1.13
3+
go 1.19
4+
5+
require (
6+
cloud.google.com/go/kms v1.4.0
7+
golang.org/x/crypto v0.0.0-20220829220503-c86fa9a7ed90
8+
golang.org/x/oauth2 v0.0.0-20220822191816-0ebed06d0094
9+
google.golang.org/api v0.95.0
10+
google.golang.org/genproto v0.0.0-20220908141613-51c1cc9bc6d0
11+
)
412

513
require (
614
cloud.google.com/go/compute v1.9.0 // indirect
715
cloud.google.com/go/iam v0.4.0 // indirect
8-
cloud.google.com/go/kms v1.4.0
916
github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect
17+
github.com/golang/protobuf v1.5.2 // indirect
1018
github.com/google/go-cmp v0.5.9 // indirect
19+
github.com/googleapis/enterprise-certificate-proxy v0.1.0 // indirect
1120
github.com/googleapis/gax-go/v2 v2.5.1 // indirect
12-
golang.org/x/crypto v0.0.0-20220829220503-c86fa9a7ed90
21+
go.opencensus.io v0.23.0 // indirect
1322
golang.org/x/net v0.0.0-20220907135653-1e95f45603a7 // indirect
1423
golang.org/x/sys v0.0.0-20220908164124-27713097b956 // indirect
15-
google.golang.org/api v0.95.0 // indirect
16-
google.golang.org/genproto v0.0.0-20220908141613-51c1cc9bc6d0
24+
golang.org/x/text v0.3.7 // indirect
25+
google.golang.org/appengine v1.6.7 // indirect
1726
google.golang.org/grpc v1.49.0 // indirect
27+
google.golang.org/protobuf v1.28.1 // indirect
1828
)

go.sum

Lines changed: 0 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -30,8 +30,6 @@ cloud.google.com/go v0.100.1/go.mod h1:fs4QogzfH5n2pBXBP9vRiU+eCny7lD2vmFZy79Iuw
3030
cloud.google.com/go v0.100.2/go.mod h1:4Xra9TjzAeYHrl5+oeLlzbM2k3mjVhZh4UqTZ//w99A=
3131
cloud.google.com/go v0.102.0/go.mod h1:oWcCzKlqJ5zgHQt9YsaeTY9KzIvjyy0ArmiBUgpQ+nc=
3232
cloud.google.com/go v0.102.1 h1:vpK6iQWv/2uUeFJth4/cBHsQAGjn1iIE6AAlxipRaA0=
33-
cloud.google.com/go v0.102.1/go.mod h1:XZ77E9qnTEnrgEOvr4xzfdX5TRo7fB4T2F4O6+34hIU=
34-
cloud.google.com/go/asset v1.5.0/go.mod h1:5mfs8UvcM5wHhqtSv8J1CtxxaQq3AdBxxQi2jGW/K4o=
3533
cloud.google.com/go/bigquery v1.0.1/go.mod h1:i/xbL2UlR5RvWAURpBYZTtm/cXjCha9lbfbpx4poX+o=
3634
cloud.google.com/go/bigquery v1.3.0/go.mod h1:PjpwJnslEMmckchkHFfq+HTD2DmtT67aNFKH1/VBDHE=
3735
cloud.google.com/go/bigquery v1.4.0/go.mod h1:S8dzgnTigyfTmLBfrtrhyYhwRxG72rYxvftPBK2Dvzc=
@@ -298,7 +296,6 @@ golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v
298296
golang.org/x/net v0.0.0-20210316092652-d523dce5a7f4/go.mod h1:RBQZq4jEuRlivfhVLdyRGr576XBO4/greRjx4P4O3yc=
299297
golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM=
300298
golang.org/x/net v0.0.0-20210503060351-7fd8e65b6420/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
301-
golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
302299
golang.org/x/net v0.0.0-20220127200216-cd36cc0744dd/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk=
303300
golang.org/x/net v0.0.0-20220225172249-27dd8689420f/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk=
304301
golang.org/x/net v0.0.0-20220325170049-de3da57026de/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk=
@@ -328,7 +325,6 @@ golang.org/x/oauth2 v0.0.0-20220223155221-ee480838109b/go.mod h1:DAh4E804XQdzx2j
328325
golang.org/x/oauth2 v0.0.0-20220309155454-6242fa91716a/go.mod h1:DAh4E804XQdzx2j+YRIaUnCqCV2RuMz24cGBJ5QYIrc=
329326
golang.org/x/oauth2 v0.0.0-20220411215720-9780585627b5/go.mod h1:DAh4E804XQdzx2j+YRIaUnCqCV2RuMz24cGBJ5QYIrc=
330327
golang.org/x/oauth2 v0.0.0-20220608161450-d0670ef3b1eb/go.mod h1:jaDAt6Dkxork7LmZnYtzbRWj0W47D86a3TGe0YHBvmE=
331-
golang.org/x/oauth2 v0.0.0-20220622183110-fd043fe589d2/go.mod h1:jaDAt6Dkxork7LmZnYtzbRWj0W47D86a3TGe0YHBvmE=
332328
golang.org/x/oauth2 v0.0.0-20220822191816-0ebed06d0094 h1:2o1E+E8TpNLklK9nHiPiK1uzIYrIHt+cQx3ynCwq9V8=
333329
golang.org/x/oauth2 v0.0.0-20220822191816-0ebed06d0094/go.mod h1:h4gKUeWbJ4rQPri7E0u6Gs4e9Ri2zaLxzw5DI5XGrYg=
334330
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
@@ -402,7 +398,6 @@ golang.org/x/sys v0.0.0-20220503163025-988cb79eb6c6/go.mod h1:oPkhp1MJrh7nUepCBc
402398
golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
403399
golang.org/x/sys v0.0.0-20220610221304-9f5ed59c137d/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
404400
golang.org/x/sys v0.0.0-20220624220833-87e55d714810/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
405-
golang.org/x/sys v0.0.0-20220728004956-3c1f35247d10/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
406401
golang.org/x/sys v0.0.0-20220908164124-27713097b956 h1:XeJjHH1KiLpKGb6lvMiksZ9l0fVUh+AmGcm0nOMEBOY=
407402
golang.org/x/sys v0.0.0-20220908164124-27713097b956/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
408403
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
@@ -518,9 +513,6 @@ google.golang.org/api v0.75.0/go.mod h1:pU9QmyHLnzlpar1Mjt4IbapUCy8J+6HD6GeELN69
518513
google.golang.org/api v0.78.0/go.mod h1:1Sg78yoMLOhlQTeF+ARBoytAcH1NNyyl390YMy6rKmw=
519514
google.golang.org/api v0.80.0/go.mod h1:xY3nI94gbvBrE0J6NHXhxOmW97HG7Khjkku6AFB3Hyg=
520515
google.golang.org/api v0.84.0/go.mod h1:NTsGnUFJMYROtiquksZHBWtHfeMC7iYthki7Eq3pa8o=
521-
google.golang.org/api v0.90.0/go.mod h1:+Sem1dnrKlrXMR/X0bPnMWyluQe4RsNoYfmNLhOIkzw=
522-
google.golang.org/api v0.91.0/go.mod h1:+Sem1dnrKlrXMR/X0bPnMWyluQe4RsNoYfmNLhOIkzw=
523-
google.golang.org/api v0.93.0/go.mod h1:+Sem1dnrKlrXMR/X0bPnMWyluQe4RsNoYfmNLhOIkzw=
524516
google.golang.org/api v0.95.0 h1:d1c24AAS01DYqXreBeuVV7ewY/U8Mnhh47pwtsgVtYg=
525517
google.golang.org/api v0.95.0/go.mod h1:eADj+UBuxkh5zlrSntJghuNeg8HwQ1w5lTKkuqaETEI=
526518
google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM=
@@ -609,11 +601,7 @@ google.golang.org/genproto v0.0.0-20220518221133-4f43b3371335/go.mod h1:RAyBrSAP
609601
google.golang.org/genproto v0.0.0-20220523171625-347a074981d8/go.mod h1:RAyBrSAP7Fh3Nc84ghnVLDPuV51xc9agzmm4Ph6i0Q4=
610602
google.golang.org/genproto v0.0.0-20220608133413-ed9918b62aac/go.mod h1:KEWEmljWE5zPzLBa/oHl6DaEt9LmfH6WtH1OHIvleBA=
611603
google.golang.org/genproto v0.0.0-20220616135557-88e70c0c3a90/go.mod h1:KEWEmljWE5zPzLBa/oHl6DaEt9LmfH6WtH1OHIvleBA=
612-
google.golang.org/genproto v0.0.0-20220617124728-180714bec0ad/go.mod h1:KEWEmljWE5zPzLBa/oHl6DaEt9LmfH6WtH1OHIvleBA=
613604
google.golang.org/genproto v0.0.0-20220624142145-8cd45d7dbd1f/go.mod h1:KEWEmljWE5zPzLBa/oHl6DaEt9LmfH6WtH1OHIvleBA=
614-
google.golang.org/genproto v0.0.0-20220722212130-b98a9ff5e252/go.mod h1:GkXuJDJ6aQ7lnJcRF+SJVgFdQhypqgl3LB1C9vabdRE=
615-
google.golang.org/genproto v0.0.0-20220804142021-4e6b2dfa6612/go.mod h1:iHe1svFLAZg9VWz891+QbRMwUv9O/1Ww+/mngYeThbc=
616-
google.golang.org/genproto v0.0.0-20220815135757-37a418bb8959/go.mod h1:dbqgFATTzChvnt+ujMdZwITVAJHFtfyN1qUhDqEiIlk=
617605
google.golang.org/genproto v0.0.0-20220908141613-51c1cc9bc6d0 h1:bMz0aY2wd9TwUp9M7QfjBWuQqaFD/ZaTtvDpPDCo2Ow=
618606
google.golang.org/genproto v0.0.0-20220908141613-51c1cc9bc6d0/go.mod h1:rQWNQYp1kbHR3+n5cARSTCF5rlJOttUn8yIhRklGAWQ=
619607
google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c=
@@ -647,7 +635,6 @@ google.golang.org/grpc v1.45.0/go.mod h1:lN7owxKUQEqMfSyQikvvk5tf/6zMPsrK+ONuO11
647635
google.golang.org/grpc v1.46.0/go.mod h1:vN9eftEi1UMyUsIF80+uQXhHjbXYbm0uXoFCACuMGWk=
648636
google.golang.org/grpc v1.46.2/go.mod h1:vN9eftEi1UMyUsIF80+uQXhHjbXYbm0uXoFCACuMGWk=
649637
google.golang.org/grpc v1.47.0/go.mod h1:vN9eftEi1UMyUsIF80+uQXhHjbXYbm0uXoFCACuMGWk=
650-
google.golang.org/grpc v1.48.0/go.mod h1:vN9eftEi1UMyUsIF80+uQXhHjbXYbm0uXoFCACuMGWk=
651638
google.golang.org/grpc v1.49.0 h1:WTLtQzmQori5FUH25Pq4WT22oCsv8USpQ+F6rqtsmxw=
652639
google.golang.org/grpc v1.49.0/go.mod h1:ZgQEeidpAuNRZ8iRrlBKXZQP1ghovWIVhdJRyCDK+GI=
653640
google.golang.org/grpc/cmd/protoc-gen-go-grpc v1.1.0/go.mod h1:6Kw0yEErY5E/yWrBtf03jp27GLLJujG4z/JK95pnjjw=

kms/google/auth.go

Lines changed: 94 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,94 @@
1+
package google
2+
3+
import (
4+
"bytes"
5+
"context"
6+
"encoding/json"
7+
"fmt"
8+
"log"
9+
"os/exec"
10+
"time"
11+
12+
"golang.org/x/oauth2"
13+
googleauth "golang.org/x/oauth2/google"
14+
)
15+
16+
func FindTokenSource() (oauth2.TokenSource, error) {
17+
tokenSource, errEnv := NewEnvTokenSource()
18+
if errEnv == nil && tokenSource != nil {
19+
return tokenSource, errEnv
20+
}
21+
tokenSource, errGcloud := NewGcloudTokenSource()
22+
if errGcloud == nil && tokenSource != nil {
23+
return tokenSource, errGcloud
24+
}
25+
return nil, fmt.Errorf("Failed to find credentials")
26+
}
27+
28+
func NewEnvTokenSource() (oauth2.TokenSource, error) {
29+
credentials, err := googleauth.FindDefaultCredentials(context.Background(), "https://www.googleapis.com/auth/cloud-platform")
30+
if err == nil {
31+
// Try to get a token so we know it works
32+
token, err := credentials.TokenSource.Token()
33+
if err != nil {
34+
return nil, err
35+
}
36+
return oauth2.ReuseTokenSource(token, credentials.TokenSource), nil
37+
}
38+
return nil, fmt.Errorf("Failed to find credentials in the environment")
39+
}
40+
41+
func NewGcloudTokenSource() (oauth2.TokenSource, error) {
42+
if _, err := exec.LookPath("gcloud"); err != nil {
43+
return nil, fmt.Errorf("Failed to find gcloud in path")
44+
}
45+
46+
// Try to get a token so we know it works
47+
ts := gcloudTokenSource{}
48+
49+
token, err := ts.Token()
50+
if err != nil {
51+
return nil, err
52+
}
53+
54+
return oauth2.ReuseTokenSource(token, ts), nil
55+
}
56+
57+
type gcloudTokenSource struct{}
58+
59+
type gcloudOutput struct {
60+
Credential struct {
61+
AccessToken string `json:"access_token"`
62+
TokenExpiry string `json:"token_expiry"`
63+
IdToken string `json:"id_token"`
64+
} `json:"credential"`
65+
}
66+
67+
func (gts gcloudTokenSource) Token() (*oauth2.Token, error) {
68+
gcloudCmd := exec.Command("gcloud", "config", "config-helper", "--force-auth-refresh", "--format=json(credential)")
69+
var out bytes.Buffer
70+
gcloudCmd.Stdout = &out
71+
gcloudCmd.Stderr = log.Writer()
72+
73+
if err := gcloudCmd.Run(); err != nil {
74+
return nil, fmt.Errorf("error executing `gcloud config config-helper`: %w", err)
75+
}
76+
77+
creds := gcloudOutput{}
78+
if err := json.Unmarshal(out.Bytes(), &creds); err != nil {
79+
return nil, fmt.Errorf("failed to parse `gcloud config config-helper` output: %w", err)
80+
}
81+
82+
expiry, err := time.Parse(time.RFC3339, creds.Credential.TokenExpiry)
83+
if err != nil {
84+
return nil, fmt.Errorf("failed to parse gcloud token expiry: %w", err)
85+
}
86+
87+
token := oauth2.Token{
88+
TokenType: "Bearer",
89+
AccessToken: creds.Credential.AccessToken,
90+
Expiry: expiry,
91+
}
92+
93+
return &token, nil
94+
}

kms/google/kms-signer.go

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ import (
1212
"log"
1313

1414
cloudkms "cloud.google.com/go/kms/apiv1"
15+
"google.golang.org/api/option"
1516
kmspb "google.golang.org/genproto/googleapis/cloud/kms/v1"
1617
)
1718

@@ -56,9 +57,15 @@ var CryptoHashLookup = map[crypto.Hash]string{
5657

5758
// NewKMSSigner creates a new instance
5859
func NewKMSSigner(keyName string, forceDigest bool) (signer KMSSigner, err error) {
60+
// Try to find a token source in the environment
61+
ts, err := FindTokenSource()
62+
if err != nil {
63+
log.Fatal(err)
64+
}
65+
5966
// Create the KMS client.
6067
ctx := context.Background()
61-
client, err := cloudkms.NewKeyManagementClient(ctx)
68+
client, err := cloudkms.NewKeyManagementClient(ctx, option.WithTokenSource(ts))
6269
if err != nil {
6370
log.Fatal(err)
6471
}

0 commit comments

Comments
 (0)