google-cloud-go
google-cloud-go copied to clipboard
impersonate: NewIDTokenProvider sets options which are incongruent with detect.Options.validate()
Client
Simple unit test trying to obtain an IDTokenProvider
Environment
Goland
Go Environment
$ go version
go version go1.21.0 darwin/arm64
$ go env
GO111MODULE='on'
GOARCH='arm64'
GOBIN=''
GOCACHE='/Users/esm/Library/Caches/go-build'
GOENV='/Users/esm/Library/Application Support/go/env'
GOEXE=''
GOEXPERIMENT=''
GOFLAGS=''
GOHOSTARCH='arm64'
GOHOSTOS='darwin'
GOINSECURE=''
GOMODCACHE='/Users/esm/go/pkg/mod'
GONOPROXY=''
GONOSUMDB=''
GOOS='darwin'
GOPATH='/Users/esm/go'
GOPRIVATE=''
GOPROXY='https://proxy.golang.org,direct'
GOROOT='/Users/esm/sdk/go1.21.0'
GOSUMDB='sum.golang.org'
GOTMPDIR=''
GOTOOLCHAIN='auto'
GOTOOLDIR='/Users/esm/sdk/go1.21.0/pkg/tool/darwin_arm64'
GOVCS=''
GOVERSION='go1.21.0'
GCCGO='gccgo'
AR='ar'
CC='clang'
CXX='clang++'
CGO_ENABLED='1'
GOMOD='/Users/esm/workspaces/gcp-cloudauth/go.mod'
GOWORK=''
CGO_CFLAGS='-O2 -g'
CGO_CPPFLAGS=''
CGO_CXXFLAGS='-O2 -g'
CGO_FFLAGS='-O2 -g'
CGO_LDFLAGS='-O2 -g'
PKG_CONFIG='pkg-config'
GOGCCFLAGS='-fPIC -arch arm64 -pthread -fno-caret-diagnostics -Qunused-arguments -fmessage-length=0 -ffile-prefix-map=/var/folders/wk/92k5298d011bf835s8cmt7mh0000gn/T/go-build2964035679=/tmp/go-build -gno-record-gcc-switches -fno-common'
Code
package gcpauth
import (
"cloud.google.com/go/auth/impersonate"
"context"
"github.com/stretchr/testify/require"
"testing"
)
func TestIDTokenProvider(t *testing.T) {
tp, err := impersonate.NewIDTokenProvider(&impersonate.IDTokenOptions{
Audience: "foo",
TargetPrincipal: "bar",
IncludeEmail: true,
})
require.NoError(t, err)
tok, err := tp.Token(context.Background())
require.NoError(t, err)
require.NotNil(t, tok)
}
Expected behavior
- Successfully obtain a TokenProvider
Actual behavior
Receive an error when invoking impersonate.NewIDTokenProvider(...)
:
=== RUN TestIDTokenProvider
2023/12/12 11:03:02
auth_test.go:17:
Error Trace: /Users/esm/workspaces/gcp-cloudauth/auth_test.go:17
Error: Received unexpected error:
detect: both scopes and audience were provided
Test: TestIDTokenProvider
--- FAIL: TestIDTokenProvider (0.00s)
Additional context
- cloud.google.com/go/auth v0.1.0
-
impersonate
requires a value forIDTokenOptions.Audience
, so it must be supplied.
Offending snippet within NewIDTokenProvider
that adds both audience and scope:
client, err = httptransport.NewClient(&httptransport.Options{
DetectOpts: &detect.Options{
Audience: defaultAud,
Scopes: []string{defaultScope},
},
})
httptransport.NewClient(...)
, non-nil err
is returned by newTransport
:
trans, err := newTransport(defaultBaseTransport(clientCertProvider, dialTLSContext), opts)
if err != nil {
return nil, err
}
Stack where the error is created
Stack:
detect.DefaultCredentials (detect.go:124) cloud.google.com/go/auth/detect
httptransport.newTransport (transport.go:60) cloud.google.com/go/auth/httptransport
httptransport.NewClient (httptransport.go:170) cloud.google.com/go/auth/httptransport
impersonate.NewIDTokenProvider (idtoken.go:90) cloud.google.com/go/auth/impersonate
gcpauth.TestIDTokenProvider (auth_test.go:11) gcpauth
testing.tRunner (testing.go:1595) testing
testing.(*T).Run.func1 (testing.go:1648) testing
runtime.goexit (asm_arm64.s:1197) runtime
testing.(*T).Run (testing.go:1648) testing
Hi @emetsger, thank you for reporting this issue!
Thanks for taking this on!
Generally I've been struggling to use the go SDK at google.golang.org/api to obtain ID tokens using the idtoken
package. And after assessing various challenges around integration testing I hit pause.
Then I realized that the SDK at cloud.google.com seemed to be the state of the art, and pivoted to using cloud.googlcloud.google.com/go/auth
(the packages and APIs seem much more rational than the old SDK). But I quickly hit this roadblock, so I appreciate ya'll taking a look!
In the interim, I think I will have to work around this by manually crafting a payload for invoking the https://oauth2.googleapis.com/token endpoint, and grabbing the id_token
from the response.
This still persists, as demonstrated by https://github.com/tmc/misc/blob/master/gcp-go-impersonation-issue/main.go
@emetsger could you share your workaround here?
@tmc unfortunately, my workaround was to use the original SDK's idtoken
package at google.golang.org/api
.
Sorry for the slow response here, I will get this fixed sometime this week.