vendor: google.golang.org/api v0.260.0

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
This commit is contained in:
Sebastiaan van Stijn
2026-01-23 16:49:30 +01:00
parent b21163a330
commit bb43161e2f
12 changed files with 355 additions and 68 deletions

4
go.mod
View File

@@ -292,9 +292,9 @@ require (
golang.org/x/oauth2 v0.34.0 // indirect
golang.org/x/term v0.38.0 // indirect
golang.org/x/tools v0.40.0 // indirect
google.golang.org/api v0.257.0 // indirect
google.golang.org/api v0.260.0 // indirect
google.golang.org/genproto v0.0.0-20251202230838-ff82c1b0f217 // indirect
google.golang.org/genproto/googleapis/rpc v0.0.0-20251202230838-ff82c1b0f217 // indirect
google.golang.org/genproto/googleapis/rpc v0.0.0-20251222181119-0a764e51fe1b // indirect
gopkg.in/yaml.v3 v3.0.1 // indirect
sigs.k8s.io/yaml v1.6.0 // indirect
tags.cncf.io/container-device-interface/specs-go v1.1.0 // indirect

8
go.sum
View File

@@ -990,8 +990,8 @@ golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8T
gonum.org/v1/gonum v0.16.0 h1:5+ul4Swaf3ESvrOnidPp4GZbzf0mxVQpDCYUQE7OJfk=
gonum.org/v1/gonum v0.16.0/go.mod h1:fef3am4MQ93R2HHpKnLk4/Tbh/s0+wqD5nfa6Pnwy4E=
google.golang.org/api v0.0.0-20170921000349-586095a6e407/go.mod h1:4mhQ8q/RsB7i+udVvVy5NUi08OU8ZlA0gRVgrF7VFY0=
google.golang.org/api v0.257.0 h1:8Y0lzvHlZps53PEaw+G29SsQIkuKrumGWs9puiexNAA=
google.golang.org/api v0.257.0/go.mod h1:4eJrr+vbVaZSqs7vovFd1Jb/A6ml6iw2e6FBYf3GAO4=
google.golang.org/api v0.260.0 h1:XbNi5E6bOVEj/uLXQRlt6TKuEzMD7zvW/6tNwltE4P4=
google.golang.org/api v0.260.0/go.mod h1:Shj1j0Phr/9sloYrKomICzdYgsSDImpTxME8rGLaZ/o=
google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM=
google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
google.golang.org/appengine v1.6.5/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc=
@@ -1003,8 +1003,8 @@ google.golang.org/genproto v0.0.0-20251202230838-ff82c1b0f217 h1:GvESR9BIyHUahIb
google.golang.org/genproto v0.0.0-20251202230838-ff82c1b0f217/go.mod h1:yJ2HH4EHEDTd3JiLmhds6NkJ17ITVYOdV3m3VKOnws0=
google.golang.org/genproto/googleapis/api v0.0.0-20251202230838-ff82c1b0f217 h1:fCvbg86sFXwdrl5LgVcTEvNC+2txB5mgROGmRL5mrls=
google.golang.org/genproto/googleapis/api v0.0.0-20251202230838-ff82c1b0f217/go.mod h1:+rXWjjaukWZun3mLfjmVnQi18E1AsFbDN9QdJ5YXLto=
google.golang.org/genproto/googleapis/rpc v0.0.0-20251202230838-ff82c1b0f217 h1:gRkg/vSppuSQoDjxyiGfN4Upv/h/DQmIR10ZU8dh4Ww=
google.golang.org/genproto/googleapis/rpc v0.0.0-20251202230838-ff82c1b0f217/go.mod h1:7i2o+ce6H/6BluujYR+kqX3GKH+dChPTQU19wjRPiGk=
google.golang.org/genproto/googleapis/rpc v0.0.0-20251222181119-0a764e51fe1b h1:Mv8VFug0MP9e5vUxfBcE3vUkV6CImK3cMNMIDFjmzxU=
google.golang.org/genproto/googleapis/rpc v0.0.0-20251222181119-0a764e51fe1b/go.mod h1:j9x/tPzZkyxcgEFkiKEEGxfvyumM01BEtsW8xzOahRQ=
google.golang.org/grpc v1.2.1-0.20170921194603-d4b75ebd4f9f/go.mod h1:yo6s7OP7yaDglbqo1J04qKzAhqBH6lvTonzMVmEdcZw=
google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c=
google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg=

View File

@@ -333,6 +333,20 @@ func ChunkRetryDeadline(deadline time.Duration) MediaOption {
return chunkRetryDeadlineOption(deadline)
}
type enableAutoChecksumOption struct{}
func (d enableAutoChecksumOption) setOptions(o *MediaOptions) {
o.EnableAutoChecksum = true
}
// EnableAutoChecksum returns a MediaOption that enables automatic checksum
// calculation, which is only supported for resumable multi-chunk uploads.
// The computed checksum is sent on the final upload request to the server.
// Writes are rejected in the event of a checksum mismatch.
func EnableAutoChecksum() MediaOption {
return enableAutoChecksumOption{}
}
// MediaOptions stores options for customizing media upload. It is not used by developers directly.
type MediaOptions struct {
ContentType string
@@ -340,6 +354,7 @@ type MediaOptions struct {
ChunkSize int
ChunkRetryDeadline time.Duration
ChunkTransferTimeout time.Duration
EnableAutoChecksum bool
}
// ProcessMediaOptions stores options from opts in a MediaOptions.

View File

@@ -0,0 +1,113 @@
// Copyright 2024 Google LLC.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
// Package credentialstype defines the CredType used for specifying the type of JSON credentials.
package credentialstype
import (
"encoding/json"
"fmt"
"slices"
)
// CredType specifies the type of JSON credentials.
type CredType string
const (
// Unknown represents an unknown JSON file type.
Unknown CredType = ""
// ServiceAccount represents a service account file type.
ServiceAccount CredType = "service_account"
// AuthorizedUser represents an authorized user credentials file type.
AuthorizedUser CredType = "authorized_user"
// ImpersonatedServiceAccount represents an impersonated service account file type.
//
// IMPORTANT:
// This credential type does not validate the credential configuration. A security
// risk occurs when a credential configuration configured with malicious urls
// is used.
// You should validate credential configurations provided by untrusted sources.
// See [Security requirements when using credential configurations from an external
// source] https://cloud.google.com/docs/authentication/external/externally-sourced-credentials
// for more details.
ImpersonatedServiceAccount CredType = "impersonated_service_account"
// ExternalAccount represents an external account file type.
//
// IMPORTANT:
// This credential type does not validate the credential configuration. A security
// risk occurs when a credential configuration configured with malicious urls
// is used.
// You should validate credential configurations provided by untrusted sources.
// See [Security requirements when using credential configurations from an external
// source] https://cloud.google.com/docs/authentication/external/externally-sourced-credentials
// for more details.
ExternalAccount CredType = "external_account"
// GDCHServiceAccount represents a GDCH service account file type.
GDCHServiceAccount CredType = "gdc_service_account"
// ExternalAccountAuthorizedUser represents an external account authorized user file type.
ExternalAccountAuthorizedUser CredType = "external_account_authorized_user"
)
var knownTypes = map[CredType]bool{
ServiceAccount: true,
AuthorizedUser: true,
ImpersonatedServiceAccount: true,
ExternalAccount: true,
GDCHServiceAccount: true,
ExternalAccountAuthorizedUser: true,
}
// GetCredType returns the credentials type or the Unknown type,
// or an error for empty data or failure to unmarshal JSON.
func GetCredType(data []byte) (CredType, error) {
var t CredType
if len(data) == 0 {
return t, fmt.Errorf("credential provided is 0 bytes")
}
var f struct {
Type string `json:"type"`
}
if err := json.Unmarshal(data, &f); err != nil {
return t, err
}
t = parseCredType(f.Type)
return t, nil
}
// CheckCredentialType checks if the provided JSON bytes match the expected
// credential type and, if present, one of the allowed credential types.
// An error is returned if the JSON is invalid, the type field is missing,
// or the types do not match expected and (if present) allowed.
func CheckCredentialType(b []byte, expected CredType, allowed ...CredType) error {
var f struct {
Type string `json:"type"`
}
if err := json.Unmarshal(b, &f); err != nil {
return fmt.Errorf("unable to parse credential type: %w", err)
}
if f.Type == "" {
return fmt.Errorf("missing `type` field in credential")
}
credType := CredType(f.Type)
if credType != expected {
return fmt.Errorf("credential type mismatch: got %q, expected %q", credType, expected)
}
if len(allowed) == 0 {
return nil
}
if !slices.Contains(allowed, credType) {
return fmt.Errorf("credential type not allowed: %q", credType)
}
return nil
}
// parseCredType returns the matching CredType for the JSON type string if
// it is in the list of publicly exposed types, otherwise Unknown.
func parseCredType(typeString string) CredType {
ct := CredType(typeString)
if knownTypes[ct] {
return ct
}
return Unknown
}

View File

@@ -20,6 +20,7 @@ import (
"cloud.google.com/go/auth/oauth2adapt"
"golang.org/x/oauth2"
"google.golang.org/api/internal/cert"
"google.golang.org/api/internal/credentialstype"
"google.golang.org/api/internal/impersonate"
"golang.org/x/oauth2/google"
@@ -139,11 +140,13 @@ func detectDefaultFromDialSettings(settings *DialSettings) (*auth.Credentials, e
aud = settings.DefaultAudience
}
credsFile, _ := settings.GetAuthCredentialsFile()
credsJSON, _ := settings.GetAuthCredentialsJSON()
return credentials.DetectDefault(&credentials.DetectOptions{
Scopes: scopes,
Audience: aud,
CredentialsFile: settings.CredentialsFile,
CredentialsJSON: settings.CredentialsJSON,
CredentialsFile: credsFile,
CredentialsJSON: credsJSON,
UseSelfSignedJWT: useSelfSignedJWT,
Logger: settings.Logger,
})
@@ -156,15 +159,15 @@ func baseCreds(ctx context.Context, ds *DialSettings) (*google.Credentials, erro
if ds.Credentials != nil {
return ds.Credentials, nil
}
if len(ds.CredentialsJSON) > 0 {
return credentialsFromJSON(ctx, ds.CredentialsJSON, ds)
if credsJSON, checkCredType := ds.GetAuthCredentialsJSON(); len(credsJSON) > 0 {
return credentialsFromJSON(ctx, credsJSON, ds, checkCredType)
}
if ds.CredentialsFile != "" {
data, err := os.ReadFile(ds.CredentialsFile)
if credsFile, checkCredType := ds.GetAuthCredentialsFile(); credsFile != "" {
data, err := os.ReadFile(credsFile)
if err != nil {
return nil, fmt.Errorf("cannot read credentials file: %v", err)
}
return credentialsFromJSON(ctx, data, ds)
return credentialsFromJSON(ctx, data, ds, checkCredType)
}
if ds.TokenSource != nil {
return &google.Credentials{TokenSource: ds.TokenSource}, nil
@@ -174,7 +177,7 @@ func baseCreds(ctx context.Context, ds *DialSettings) (*google.Credentials, erro
return nil, err
}
if len(cred.JSON) > 0 {
return credentialsFromJSON(ctx, cred.JSON, ds)
return credentialsFromJSON(ctx, cred.JSON, ds, credentialstype.Unknown)
}
// For GAE and GCE, the JSON is empty so return the default credentials directly.
return cred, nil
@@ -197,7 +200,12 @@ const (
//
// - Otherwise, executes standard OAuth 2.0 flow
// More details: google.aip.dev/auth/4111
func credentialsFromJSON(ctx context.Context, data []byte, ds *DialSettings) (*google.Credentials, error) {
func credentialsFromJSON(ctx context.Context, data []byte, ds *DialSettings, checkCredType credentialstype.CredType) (*google.Credentials, error) {
if checkCredType != credentialstype.Unknown {
if err := credentialstype.CheckCredentialType(data, checkCredType); err != nil {
return nil, err
}
}
var params google.CredentialsParams
params.Scopes = ds.GetScopes()

View File

@@ -17,6 +17,7 @@ import (
"cloud.google.com/go/auth"
"golang.org/x/oauth2"
"golang.org/x/oauth2/google"
"google.golang.org/api/internal/credentialstype"
"google.golang.org/api/internal/impersonate"
"google.golang.org/grpc"
)
@@ -31,16 +32,18 @@ const (
// DialSettings holds information needed to establish a connection with a
// Google API service.
type DialSettings struct {
Endpoint string
DefaultEndpoint string
DefaultEndpointTemplate string
DefaultMTLSEndpoint string
Scopes []string
DefaultScopes []string
EnableJwtWithScope bool
TokenSource oauth2.TokenSource
Credentials *google.Credentials
CredentialsFile string // if set, Token Source is ignored.
Endpoint string
DefaultEndpoint string
DefaultEndpointTemplate string
DefaultMTLSEndpoint string
Scopes []string
DefaultScopes []string
EnableJwtWithScope bool
TokenSource oauth2.TokenSource
Credentials *google.Credentials
// Deprecated: Use AuthCredentialsFile instead, due to security risk.
CredentialsFile string
// Deprecated: Use AuthCredentialsJSON instead, due to security risk.
CredentialsJSON []byte
InternalCredentials *google.Credentials
UserAgent string
@@ -72,6 +75,9 @@ type DialSettings struct {
// New Auth library Options
AuthCredentials *auth.Credentials
AuthCredentialsJSON []byte
AuthCredentialsFile string
AuthCredentialsType credentialstype.CredType
EnableNewAuthLibrary bool
// TODO(b/372244283): Remove after b/358175516 has been fixed
@@ -113,22 +119,55 @@ func (ds *DialSettings) IsNewAuthLibraryEnabled() bool {
if ds.AuthCredentials != nil {
return true
}
if len(ds.AuthCredentialsJSON) > 0 {
return true
}
if ds.AuthCredentialsFile != "" {
return true
}
if b, err := strconv.ParseBool(os.Getenv(newAuthLibEnvVar)); err == nil {
return b
}
return false
}
// GetAuthCredentialsJSON returns the AuthCredentialsJSON and AuthCredentialsType, if set.
// Otherwise it falls back to the deprecated CredentialsJSON with an Unknown type.
//
// Use AuthCredentialsJSON if provided, as it is the safer, recommended option.
// CredentialsJSON is populated by the deprecated WithCredentialsJSON.
func (ds *DialSettings) GetAuthCredentialsJSON() ([]byte, credentialstype.CredType) {
if len(ds.AuthCredentialsJSON) > 0 {
return ds.AuthCredentialsJSON, ds.AuthCredentialsType
}
return ds.CredentialsJSON, credentialstype.Unknown
}
// GetAuthCredentialsFile returns the AuthCredentialsFile and AuthCredentialsType, if set.
// Otherwise it falls back to the deprecated CredentialsFile with an Unknown type.
//
// Use AuthCredentialsFile if provided, as it is the safer, recommended option.
// CredentialsFile is populated by the deprecated WithCredentialsFile.
func (ds *DialSettings) GetAuthCredentialsFile() (string, credentialstype.CredType) {
if ds.AuthCredentialsFile != "" {
return ds.AuthCredentialsFile, ds.AuthCredentialsType
}
return ds.CredentialsFile, credentialstype.Unknown
}
// Validate reports an error if ds is invalid.
func (ds *DialSettings) Validate() error {
if ds.SkipValidation {
return nil
}
hasCreds := ds.APIKey != "" || ds.TokenSource != nil || ds.CredentialsFile != "" || ds.Credentials != nil
hasCreds := ds.APIKey != "" || ds.TokenSource != nil || ds.CredentialsFile != "" || ds.Credentials != nil || ds.AuthCredentials != nil || len(ds.AuthCredentialsJSON) > 0 || ds.AuthCredentialsFile != ""
if ds.NoAuth && hasCreds {
return errors.New("options.WithoutAuthentication is incompatible with any option that provides credentials")
}
// Credentials should not appear with other options.
// AuthCredentials is a special case that may be present with
// with other options in order to facilitate automatic conversion of
// oauth2 types (old auth) to cloud.google.com/go/auth types (new auth).
// We currently allow TokenSource and CredentialsFile to coexist.
// TODO(jba): make TokenSource & CredentialsFile an error (breaking change).
nCreds := 0
@@ -138,6 +177,12 @@ func (ds *DialSettings) Validate() error {
if len(ds.CredentialsJSON) > 0 {
nCreds++
}
if len(ds.AuthCredentialsJSON) > 0 {
nCreds++
}
if ds.AuthCredentialsFile != "" {
nCreds++
}
if ds.CredentialsFile != "" {
nCreds++
}

View File

@@ -5,4 +5,4 @@
package internal
// Version is the current tagged release of the library.
const Version = "0.257.0"
const Version = "0.260.0"

View File

@@ -290,7 +290,7 @@ func GetLogger(opts []option.ClientOption) *slog.Logger {
// options, in this order:
//
// - [option.WithoutAuthentication]
// - [option.WithAuthCredentials]
// - [option.Credentials]
// - [WithCredentials] (internal use only)
// - [option.WithCredentials]
// - [option.WithTokenSource]
@@ -300,7 +300,9 @@ func GetLogger(opts []option.ClientOption) *slog.Logger {
// returns the result:
//
// - [option.WithAudiences]
// - [option.WithAuthCredentialsFile]
// - [option.WithCredentialsFile]
// - [option.WithAuthCredentialsJSON]
// - [option.WithCredentialsJSON]
// - [option.WithScopes]
// - [WithDefaultScopes] (internal use only)

View File

@@ -14,10 +14,45 @@ import (
"golang.org/x/oauth2"
"golang.org/x/oauth2/google"
"google.golang.org/api/internal"
"google.golang.org/api/internal/credentialstype"
"google.golang.org/api/internal/impersonate"
"google.golang.org/grpc"
)
// CredentialsType specifies the type of JSON credentials being provided
// to a loading function such as [WithAuthCredentialsFile] or
// [WithAuthCredentialsJSON].
type CredentialsType = credentialstype.CredType
const (
// ServiceAccount represents a service account file type.
ServiceAccount = credentialstype.ServiceAccount
// AuthorizedUser represents an authorized user credentials file type.
AuthorizedUser = credentialstype.AuthorizedUser
// ImpersonatedServiceAccount represents an impersonated service account file type.
//
// IMPORTANT:
// This credential type does not validate the credential configuration. A security
// risk occurs when a credential configuration configured with malicious urls
// is used.
// You should validate credential configurations provided by untrusted sources.
// See [Security requirements when using credential configurations from an external
// source] https://cloud.google.com/docs/authentication/external/externally-sourced-credentials
// for more details.
ImpersonatedServiceAccount = credentialstype.ImpersonatedServiceAccount
// ExternalAccount represents an external account file type.
//
// IMPORTANT:
// This credential type does not validate the credential configuration. A security
// risk occurs when a credential configuration configured with malicious urls
// is used.
// You should validate credential configurations provided by untrusted sources.
// See [Security requirements when using credential configurations from an external
// source] https://cloud.google.com/docs/authentication/external/externally-sourced-credentials
// for more details.
ExternalAccount = credentialstype.ExternalAccount
)
// A ClientOption is an option for a Google API client.
type ClientOption interface {
Apply(*internal.DialSettings)
@@ -45,6 +80,36 @@ func (w withCredFile) Apply(o *internal.DialSettings) {
// API calls with the given service account or refresh token JSON
// credentials file.
//
// Deprecated: This function is being deprecated because of a potential security risk.
//
// This function does not validate the credential configuration. The security
// risk occurs when a credential configuration is accepted from a source that
// is not under your control and used without validation on your side.
//
// If you know that you will be loading credential configurations of a
// specific type, it is recommended to use a credential-type-specific
// option function.
// This will ensure that an unexpected credential type with potential for
// malicious intent is not loaded unintentionally. You might still have to do
// validation for certain credential types. Please follow the recommendation
// for that function. For example, if you want to load only service accounts,
// you can use [WithAuthCredentialsFile] with [ServiceAccount]:
//
// option.WithAuthCredentialsFile(option.ServiceAccount, "/path/to/file.json")
//
// If you are loading your credential configuration from an untrusted source and have
// not mitigated the risks (e.g. by validating the configuration yourself), make
// these changes as soon as possible to prevent security risks to your environment.
//
// Regardless of the function used, it is always your responsibility to validate
// configurations received from external sources.
func WithCredentialsFile(filename string) ClientOption {
return withCredFile(filename)
}
// WithAuthCredentialsFile returns a ClientOption that authenticates API calls
// with the given JSON credentials file and credential type.
//
// Important: If you accept a credential configuration (credential
// JSON/File/Stream) from an external source for authentication to Google
// Cloud Platform, you must validate it before providing it to any Google
@@ -52,8 +117,21 @@ func (w withCredFile) Apply(o *internal.DialSettings) {
// Google APIs can compromise the security of your systems and data. For
// more information, refer to [Validate credential configurations from
// external sources](https://cloud.google.com/docs/authentication/external/externally-sourced-credentials).
func WithCredentialsFile(filename string) ClientOption {
return withCredFile(filename)
func WithAuthCredentialsFile(credType CredentialsType, filename string) ClientOption {
return withAuthCredentialsFile{
credsType: credType,
filename: filename,
}
}
type withAuthCredentialsFile struct {
credsType CredentialsType
filename string
}
func (w withAuthCredentialsFile) Apply(o *internal.DialSettings) {
o.AuthCredentialsFile = w.filename
o.AuthCredentialsType = w.credsType
}
// WithServiceAccountFile returns a ClientOption that uses a Google service
@@ -67,22 +145,38 @@ func WithCredentialsFile(filename string) ClientOption {
// more information, refer to [Validate credential configurations from
// external sources](https://cloud.google.com/docs/authentication/external/externally-sourced-credentials).
//
// Deprecated: Use WithCredentialsFile instead.
// Deprecated: Use WithAuthCredentialsFile instead.
func WithServiceAccountFile(filename string) ClientOption {
return WithCredentialsFile(filename)
return WithAuthCredentialsFile(ServiceAccount, filename)
}
// WithCredentialsJSON returns a ClientOption that authenticates
// API calls with the given service account or refresh token JSON
// credentials.
//
// Important: If you accept a credential configuration (credential
// JSON/File/Stream) from an external source for authentication to Google
// Cloud Platform, you must validate it before providing it to any Google
// API or library. Providing an unvalidated credential configuration to
// Google APIs can compromise the security of your systems and data. For
// more information, refer to [Validate credential configurations from
// external sources](https://cloud.google.com/docs/authentication/external/externally-sourced-credentials).
// Deprecated: This function is being deprecated because of a potential security risk.
//
// This function does not validate the credential configuration. The security
// risk occurs when a credential configuration is accepted from a source that
// is not under your control and used without validation on your side.
//
// If you know that you will be loading credential configurations of a
// specific type, it is recommended to use a credential-type-specific
// option function.
// This will ensure that an unexpected credential type with potential for
// malicious intent is not loaded unintentionally. You might still have to do
// validation for certain credential types. Please follow the recommendation
// for that function. For example, if you want to load only service accounts,
// you can use [WithAuthCredentialsJSON] with [ServiceAccount]:
//
// option.WithAuthCredentialsJSON(option.ServiceAccount, json)
//
// If you are loading your credential configuration from an untrusted source and have
// not mitigated the risks (e.g. by validating the configuration yourself), make
// these changes as soon as possible to prevent security risks to your environment.
//
// Regardless of the function used, it is always your responsibility to validate
// configurations received from external sources.
func WithCredentialsJSON(p []byte) ClientOption {
return withCredentialsJSON(p)
}
@@ -94,6 +188,33 @@ func (w withCredentialsJSON) Apply(o *internal.DialSettings) {
copy(o.CredentialsJSON, w)
}
// WithAuthCredentialsJSON returns a ClientOption that authenticates API calls
// with the given JSON credentials and credential type.
//
// Important: If you accept a credential configuration (credential
// JSON/File/Stream) from an external source for authentication to Google
// Cloud Platform, you must validate it before providing it to any Google
// API or library. Providing an unvalidated credential configuration to
// Google APIs can compromise the security of your systems and data. For
// more information, refer to [Validate credential configurations from
// external sources](https://cloud.google.com/docs/authentication/external/externally-sourced-credentials).
func WithAuthCredentialsJSON(credType CredentialsType, json []byte) ClientOption {
return withAuthCredentialsJSON{
credsType: credType,
json: json,
}
}
type withAuthCredentialsJSON struct {
credsType CredentialsType
json []byte
}
func (w withAuthCredentialsJSON) Apply(o *internal.DialSettings) {
o.AuthCredentialsJSON = w.json
o.AuthCredentialsType = w.credsType
}
// WithEndpoint returns a ClientOption that overrides the default endpoint
// to be used for a service. Please note that by default Google APIs only
// accept HTTPS traffic.

View File

@@ -14,7 +14,6 @@ import (
"net"
"os"
"strings"
"sync"
"time"
"cloud.google.com/go/auth"
@@ -31,7 +30,6 @@ import (
grpcgoogle "google.golang.org/grpc/credentials/google"
grpcinsecure "google.golang.org/grpc/credentials/insecure"
"google.golang.org/grpc/credentials/oauth"
"google.golang.org/grpc/stats"
// Install grpclb, which is required for direct path.
_ "google.golang.org/grpc/balancer/grpclb"
@@ -55,26 +53,6 @@ var dialContext = grpc.DialContext
// Assign to var for unit test replacement
var dialContextNewAuth = grpctransport.Dial
// otelStatsHandler is a singleton otelgrpc.clientHandler to be used across
// all dial connections to avoid the memory leak documented in
// https://github.com/open-telemetry/opentelemetry-go-contrib/issues/4226
//
// TODO: If 4226 has been fixed in opentelemetry-go-contrib, replace this
// singleton with inline usage for simplicity.
var (
initOtelStatsHandlerOnce sync.Once
otelStatsHandler stats.Handler
)
// otelGRPCStatsHandler returns singleton otelStatsHandler for reuse across all
// dial connections.
func otelGRPCStatsHandler() stats.Handler {
initOtelStatsHandlerOnce.Do(func() {
otelStatsHandler = otelgrpc.NewClientHandler()
})
return otelStatsHandler
}
// Dial returns a GRPC connection for use communicating with a Google cloud
// service, configured with the given ClientOptions.
func Dial(ctx context.Context, opts ...option.ClientOption) (*grpc.ClientConn, error) {
@@ -220,6 +198,8 @@ func dialPoolNewAuth(ctx context.Context, secure bool, poolSize int, ds *interna
defaultEndpointTemplate = ds.DefaultEndpoint
}
credsJSON, _ := ds.GetAuthCredentialsJSON()
credsFile, _ := ds.GetAuthCredentialsFile()
pool, err := dialContextNewAuth(ctx, secure, &grpctransport.Options{
DisableTelemetry: ds.TelemetryDisabled,
DisableAuthentication: ds.NoAuth,
@@ -233,8 +213,8 @@ func dialPoolNewAuth(ctx context.Context, secure bool, poolSize int, ds *interna
DetectOpts: &credentials.DetectOptions{
Scopes: ds.Scopes,
Audience: aud,
CredentialsFile: ds.CredentialsFile,
CredentialsJSON: ds.CredentialsJSON,
CredentialsFile: credsFile,
CredentialsJSON: credsJSON,
Logger: ds.Logger,
},
InternalOptions: &grpctransport.InternalOptions{
@@ -400,7 +380,7 @@ func addOpenTelemetryStatsHandler(opts []grpc.DialOption, settings *internal.Dia
if settings.TelemetryDisabled {
return opts
}
return append(opts, grpc.WithStatsHandler(otelGRPCStatsHandler()))
return append(opts, grpc.WithStatsHandler(otelgrpc.NewClientHandler()))
}
// grpcTokenSource supplies PerRPCCredentials from an oauth.TokenSource.

View File

@@ -108,6 +108,8 @@ func newClientNewAuth(ctx context.Context, base http.RoundTripper, ds *internal.
if ds.UserAgent != "" {
headers.Set("User-Agent", ds.UserAgent)
}
credsJSON, _ := ds.GetAuthCredentialsJSON()
credsFile, _ := ds.GetAuthCredentialsFile()
client, err := httptransport.NewClient(&httptransport.Options{
DisableTelemetry: ds.TelemetryDisabled,
DisableAuthentication: ds.NoAuth,
@@ -120,8 +122,8 @@ func newClientNewAuth(ctx context.Context, base http.RoundTripper, ds *internal.
DetectOpts: &credentials.DetectOptions{
Scopes: ds.Scopes,
Audience: aud,
CredentialsFile: ds.CredentialsFile,
CredentialsJSON: ds.CredentialsJSON,
CredentialsFile: credsFile,
CredentialsJSON: credsJSON,
Logger: ds.Logger,
},
InternalOptions: &httptransport.InternalOptions{

5
vendor/modules.txt vendored
View File

@@ -1929,12 +1929,13 @@ golang.org/x/tools/internal/stdlib
golang.org/x/tools/internal/typeparams
golang.org/x/tools/internal/typesinternal
golang.org/x/tools/internal/versions
# google.golang.org/api v0.257.0
# google.golang.org/api v0.260.0
## explicit; go 1.24.0
google.golang.org/api/googleapi
google.golang.org/api/googleapi/transport
google.golang.org/api/internal
google.golang.org/api/internal/cert
google.golang.org/api/internal/credentialstype
google.golang.org/api/internal/impersonate
google.golang.org/api/internal/third_party/uritemplates
google.golang.org/api/iterator
@@ -1955,7 +1956,7 @@ google.golang.org/genproto/googleapis/api/httpbody
google.golang.org/genproto/googleapis/api/label
google.golang.org/genproto/googleapis/api/metric
google.golang.org/genproto/googleapis/api/monitoredres
# google.golang.org/genproto/googleapis/rpc v0.0.0-20251202230838-ff82c1b0f217
# google.golang.org/genproto/googleapis/rpc v0.0.0-20251222181119-0a764e51fe1b
## explicit; go 1.24.0
google.golang.org/genproto/googleapis/rpc/code
google.golang.org/genproto/googleapis/rpc/errdetails