mirror of
https://github.com/kubernetes/node-problem-detector.git
synced 2026-08-28 01:47:20 +00:00
Fix Grype CVEs: update logrus and prometheus/prometheus
- Update github.com/sirupsen/logrus v1.9.0 -> v1.9.3 in test/go.mod to fix GHSA-4f99-4q7p-p3gh (High) - Update github.com/prometheus/prometheus v0.35.0 -> v0.311.3 to fix GHSA-vffh-x6r8-xx99 (Medium) - Run go mod tidy and go mod vendor to update vendor directory
This commit is contained in:
+23
-2
@@ -1,3 +1,26 @@
|
||||
# Changes
|
||||
|
||||
## [0.18.2](https://github.com/googleapis/google-cloud-go/releases/tag/auth%2Fv0.18.2) (2026-02-13)
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* fixes gdch credentials logic (#13741) ([f82cda5](https://github.com/googleapis/google-cloud-go/commit/f82cda58bd9885b7b8a9d8b15126f5a1e0add0dc))
|
||||
|
||||
## [0.18.1](https://github.com/googleapis/google-cloud-go/releases/tag/auth%2Fv0.18.1) (2026-01-21)
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* add InternalOptions.TelemetryAttributes for internal client use (#13641) ([3876978](https://github.com/googleapis/google-cloud-go/commit/38769789755ed47d85e85dcd56596109de65f780))
|
||||
* remove singleton and restore normal usage of otelgrpc.clientHandler (#13522) ([673d4b0](https://github.com/googleapis/google-cloud-go/commit/673d4b05617f833aa433f7f6a350b5cb888ea20d))
|
||||
|
||||
## [0.18.0](https://github.com/googleapis/google-cloud-go/releases/tag/auth%2Fv0.18.0) (2025-12-15)
|
||||
|
||||
### Features
|
||||
|
||||
* Support scopes field from impersonated credential json (#13308) ([e3f62e1](https://github.com/googleapis/google-cloud-go/commit/e3f62e102840127a0058f5cced4c9738f2bf45f2))
|
||||
* add support for parsing EC private key (#13317) ([ea6bc62](https://github.com/googleapis/google-cloud-go/commit/ea6bc62ffe2cc0a6d607d698a181b37fa46c340d))
|
||||
* deprecate unsafe credentials JSON loading options (#13397) ([0dd2a3b](https://github.com/googleapis/google-cloud-go/commit/0dd2a3bdece9a85ee7216a737559fa9f5a869545))
|
||||
|
||||
## [0.17.0](https://github.com/googleapis/google-cloud-go/releases/tag/auth%2Fv0.17.0) (2025-10-02)
|
||||
|
||||
### Features
|
||||
@@ -5,8 +28,6 @@
|
||||
* Add trust boundary support for service accounts and impersonation (HTTP/gRPC) (#11870) ([5c2b665](https://github.com/googleapis/google-cloud-go/commit/5c2b665f392e6dd90192f107188720aa1357e7da))
|
||||
* add trust boundary support for external accounts (#12864) ([a67a146](https://github.com/googleapis/google-cloud-go/commit/a67a146a6a88a6f1ba10c409dfce8015ecd60a64))
|
||||
|
||||
# Changelog
|
||||
|
||||
## [0.16.5](https://github.com/googleapis/google-cloud-go/compare/auth/v0.16.4...auth/v0.16.5) (2025-08-14)
|
||||
|
||||
|
||||
|
||||
+151
-14
@@ -52,6 +52,44 @@ var (
|
||||
allowOnGCECheck = true
|
||||
)
|
||||
|
||||
// CredType specifies the type of JSON credentials being provided
|
||||
// to a loading function such as [NewCredentialsFromFile] or
|
||||
// [NewCredentialsFromJSON].
|
||||
type CredType string
|
||||
|
||||
const (
|
||||
// ServiceAccount represents a service account file type.
|
||||
ServiceAccount CredType = "service_account"
|
||||
// AuthorizedUser represents a user credentials file type.
|
||||
AuthorizedUser CredType = "authorized_user"
|
||||
// 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"
|
||||
// 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"
|
||||
// GDCHServiceAccount represents a GDCH service account credentials.
|
||||
GDCHServiceAccount CredType = "gdch_service_account"
|
||||
// ExternalAccountAuthorizedUser represents an external account authorized user credentials.
|
||||
ExternalAccountAuthorizedUser CredType = "external_account_authorized_user"
|
||||
)
|
||||
|
||||
// TokenBindingType specifies the type of binding used when requesting a token
|
||||
// whether to request a hard-bound token using mTLS or an instance identity
|
||||
// bound token using ALTS.
|
||||
@@ -92,6 +130,14 @@ func OnGCE() bool {
|
||||
// - On Google Compute Engine, Google App Engine standard second generation
|
||||
// runtimes, and Google App Engine flexible environment, it fetches
|
||||
// credentials from the metadata server.
|
||||
//
|
||||
// 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 DetectDefault(opts *DetectOptions) (*auth.Credentials, error) {
|
||||
if err := opts.validate(); err != nil {
|
||||
return nil, err
|
||||
@@ -189,25 +235,61 @@ type DetectOptions struct {
|
||||
// from the provided filepath. If provided, CredentialsJSON must not be.
|
||||
// Optional.
|
||||
//
|
||||
// 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 field is deprecated because of a potential security risk.
|
||||
// It 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
|
||||
// NewCredentialsFromFile method. 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 method. For
|
||||
// example, if you want to load only service accounts, you can use
|
||||
//
|
||||
// creds, err := credentials.NewCredentialsFromFile(ctx, credentials.ServiceAccount, filename, opts)
|
||||
//
|
||||
// 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 method used, it is always your responsibility to
|
||||
// validate configurations received from external sources.
|
||||
//
|
||||
// For more details see:
|
||||
// https://cloud.google.com/docs/authentication/external/externally-sourced-credentials
|
||||
CredentialsFile string
|
||||
// CredentialsJSON overrides detection logic and uses the JSON bytes as the
|
||||
// source for the credential. If provided, CredentialsFile must not be.
|
||||
// Optional.
|
||||
//
|
||||
// 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 field is deprecated because of a potential security risk.
|
||||
// It 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
|
||||
// NewCredentialsFromJSON method. 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 method. For
|
||||
// example, if you want to load only service accounts, you can use
|
||||
//
|
||||
// creds, err := credentials.NewCredentialsFromJSON(ctx, credentials.ServiceAccount, json, opts)
|
||||
//
|
||||
// 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 method used, it is always your responsibility to
|
||||
// validate configurations received from external sources.
|
||||
//
|
||||
// For more details see:
|
||||
// https://cloud.google.com/docs/authentication/external/externally-sourced-credentials
|
||||
CredentialsJSON []byte
|
||||
// UseSelfSignedJWT directs service account based credentials to create a
|
||||
// self-signed JWT with the private key found in the file, skipping any
|
||||
@@ -227,6 +309,61 @@ type DetectOptions struct {
|
||||
Logger *slog.Logger
|
||||
}
|
||||
|
||||
// NewCredentialsFromFile creates a [cloud.google.com/go/auth.Credentials] from
|
||||
// the provided file. The credType argument specifies the expected credential
|
||||
// type. If the file content does not match the expected type, an error is
|
||||
// returned.
|
||||
//
|
||||
// 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 NewCredentialsFromFile(credType CredType, filename string, opts *DetectOptions) (*auth.Credentials, error) {
|
||||
b, err := os.ReadFile(filename)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return NewCredentialsFromJSON(credType, b, opts)
|
||||
}
|
||||
|
||||
// NewCredentialsFromJSON creates a [cloud.google.com/go/auth.Credentials] from
|
||||
// the provided JSON bytes. The credType argument specifies the expected
|
||||
// credential type. If the JSON does not match the expected type, an error is
|
||||
// returned.
|
||||
//
|
||||
// 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 NewCredentialsFromJSON(credType CredType, b []byte, opts *DetectOptions) (*auth.Credentials, error) {
|
||||
if err := checkCredentialType(b, credType); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
// We can't use readCredentialsFileJSON because it does auto-detection
|
||||
// for client_credentials.json which we don't support here (no type field).
|
||||
// Instead, we call fileCredentials just as readCredentialsFileJSON does
|
||||
// when it doesn't detect client_credentials.json.
|
||||
return fileCredentials(b, opts)
|
||||
}
|
||||
|
||||
func checkCredentialType(b []byte, expected CredType) error {
|
||||
|
||||
fileType, err := credsfile.ParseFileType(b)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if CredType(fileType) != expected {
|
||||
return fmt.Errorf("credentials: expected type %q, found %q", expected, fileType)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (o *DetectOptions) validate() error {
|
||||
if o == nil {
|
||||
return errors.New("credentials: options must be provided")
|
||||
|
||||
+24
-11
@@ -28,18 +28,21 @@ import (
|
||||
"cloud.google.com/go/auth/internal/trustboundary"
|
||||
)
|
||||
|
||||
const cloudPlatformScope = "https://www.googleapis.com/auth/cloud-platform"
|
||||
|
||||
func fileCredentials(b []byte, opts *DetectOptions) (*auth.Credentials, error) {
|
||||
fileType, err := credsfile.ParseFileType(b)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if fileType == "" {
|
||||
return nil, errors.New("credentials: unsupported unidentified file type")
|
||||
}
|
||||
|
||||
var projectID, universeDomain string
|
||||
var tp auth.TokenProvider
|
||||
switch fileType {
|
||||
case credsfile.UnknownCredType:
|
||||
return nil, errors.New("credentials: unsupported unidentified file type")
|
||||
case credsfile.ServiceAccountKey:
|
||||
switch CredType(fileType) {
|
||||
case ServiceAccount:
|
||||
f, err := credsfile.ParseServiceAccount(b)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@@ -50,7 +53,7 @@ func fileCredentials(b []byte, opts *DetectOptions) (*auth.Credentials, error) {
|
||||
}
|
||||
projectID = f.ProjectID
|
||||
universeDomain = resolveUniverseDomain(opts.UniverseDomain, f.UniverseDomain)
|
||||
case credsfile.UserCredentialsKey:
|
||||
case AuthorizedUser:
|
||||
f, err := credsfile.ParseUserCredentials(b)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@@ -60,7 +63,7 @@ func fileCredentials(b []byte, opts *DetectOptions) (*auth.Credentials, error) {
|
||||
return nil, err
|
||||
}
|
||||
universeDomain = f.UniverseDomain
|
||||
case credsfile.ExternalAccountKey:
|
||||
case ExternalAccount:
|
||||
f, err := credsfile.ParseExternalAccount(b)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@@ -70,7 +73,7 @@ func fileCredentials(b []byte, opts *DetectOptions) (*auth.Credentials, error) {
|
||||
return nil, err
|
||||
}
|
||||
universeDomain = resolveUniverseDomain(opts.UniverseDomain, f.UniverseDomain)
|
||||
case credsfile.ExternalAccountAuthorizedUserKey:
|
||||
case ExternalAccountAuthorizedUser:
|
||||
f, err := credsfile.ParseExternalAccountAuthorizedUser(b)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@@ -80,7 +83,7 @@ func fileCredentials(b []byte, opts *DetectOptions) (*auth.Credentials, error) {
|
||||
return nil, err
|
||||
}
|
||||
universeDomain = f.UniverseDomain
|
||||
case credsfile.ImpersonatedServiceAccountKey:
|
||||
case ImpersonatedServiceAccount:
|
||||
f, err := credsfile.ParseImpersonatedServiceAccount(b)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@@ -90,7 +93,7 @@ func fileCredentials(b []byte, opts *DetectOptions) (*auth.Credentials, error) {
|
||||
return nil, err
|
||||
}
|
||||
universeDomain = resolveUniverseDomain(opts.UniverseDomain, f.UniverseDomain)
|
||||
case credsfile.GDCHServiceAccountKey:
|
||||
case GDCHServiceAccount:
|
||||
f, err := credsfile.ParseGDCHServiceAccount(b)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@@ -275,14 +278,24 @@ func handleImpersonatedServiceAccount(f *credsfile.ImpersonatedServiceAccountFil
|
||||
return nil, errors.New("missing 'source_credentials' field or 'service_account_impersonation_url' in credentials")
|
||||
}
|
||||
|
||||
sourceTP, err := fileCredentials(f.CredSource, opts)
|
||||
sourceOpts := *opts
|
||||
|
||||
// Source credential needs IAM or Cloud Platform scope to call the
|
||||
// iamcredentials endpoint. The scopes provided by the user are for the
|
||||
// impersonated credentials.
|
||||
sourceOpts.Scopes = []string{cloudPlatformScope}
|
||||
sourceTP, err := fileCredentials(f.CredSource, &sourceOpts)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
ud := resolveUniverseDomain(opts.UniverseDomain, f.UniverseDomain)
|
||||
scopes := opts.scopes()
|
||||
if len(scopes) == 0 {
|
||||
scopes = f.Scopes
|
||||
}
|
||||
impOpts := &impersonate.Options{
|
||||
URL: f.ServiceAccountImpersonationURL,
|
||||
Scopes: opts.scopes(),
|
||||
Scopes: scopes,
|
||||
Tp: sourceTP,
|
||||
Delegates: f.Delegates,
|
||||
Client: opts.client(),
|
||||
|
||||
+20
-13
@@ -15,6 +15,7 @@
|
||||
package gdch
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"context"
|
||||
"crypto"
|
||||
"crypto/tls"
|
||||
@@ -24,9 +25,7 @@ import (
|
||||
"fmt"
|
||||
"log/slog"
|
||||
"net/http"
|
||||
"net/url"
|
||||
"os"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"cloud.google.com/go/auth"
|
||||
@@ -121,27 +120,34 @@ func (g gdchProvider) Token(ctx context.Context) (*auth.Token, error) {
|
||||
Exp: exp.Unix(),
|
||||
}
|
||||
h := jwt.Header{
|
||||
Algorithm: jwt.HeaderAlgRSA256,
|
||||
Algorithm: jwt.HeaderAlgES256,
|
||||
Type: jwt.HeaderType,
|
||||
KeyID: string(g.pkID),
|
||||
KeyID: g.pkID,
|
||||
}
|
||||
payload, err := jwt.EncodeJWS(&h, &claims, g.signer)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
v := url.Values{}
|
||||
v.Set("grant_type", GrantType)
|
||||
v.Set("audience", g.aud)
|
||||
v.Set("requested_token_type", requestTokenType)
|
||||
v.Set("subject_token", payload)
|
||||
v.Set("subject_token_type", subjectTokenType)
|
||||
|
||||
req, err := http.NewRequestWithContext(ctx, "POST", g.tokenURL, strings.NewReader(v.Encode()))
|
||||
v := map[string]string{
|
||||
"grant_type": GrantType,
|
||||
"audience": g.aud,
|
||||
"requested_token_type": requestTokenType,
|
||||
"subject_token": payload,
|
||||
"subject_token_type": subjectTokenType,
|
||||
}
|
||||
|
||||
r, err := json.Marshal(v)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("credentials: cannot marshal token request: %w", err)
|
||||
}
|
||||
|
||||
req, err := http.NewRequestWithContext(ctx, "POST", g.tokenURL, bytes.NewReader(r))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
req.Header.Set("Content-Type", "application/x-www-form-urlencoded")
|
||||
g.logger.DebugContext(ctx, "gdch token request", "request", internallog.HTTPRequest(req, []byte(v.Encode())))
|
||||
req.Header.Set("Content-Type", "application/json")
|
||||
g.logger.DebugContext(ctx, "gdch token request", "request", internallog.HTTPRequest(req, r))
|
||||
resp, body, err := internal.DoRequest(g.client, req)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("credentials: cannot fetch token: %w", err)
|
||||
@@ -188,4 +194,5 @@ func addCertToTransport(hc *http.Client, certPool *x509.CertPool) {
|
||||
trans.TLSClientConfig = &tls.Config{
|
||||
RootCAs: certPool,
|
||||
}
|
||||
hc.Transport = trans
|
||||
}
|
||||
|
||||
+10
-24
@@ -24,7 +24,6 @@ import (
|
||||
"log/slog"
|
||||
"net/http"
|
||||
"os"
|
||||
"sync"
|
||||
|
||||
"cloud.google.com/go/auth"
|
||||
"cloud.google.com/go/auth/credentials"
|
||||
@@ -36,7 +35,6 @@ import (
|
||||
"google.golang.org/grpc"
|
||||
grpccreds "google.golang.org/grpc/credentials"
|
||||
grpcinsecure "google.golang.org/grpc/credentials/insecure"
|
||||
"google.golang.org/grpc/stats"
|
||||
)
|
||||
|
||||
const (
|
||||
@@ -54,27 +52,6 @@ var (
|
||||
timeoutDialerOption grpc.DialOption
|
||||
)
|
||||
|
||||
// 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: When this module depends on a version of otelgrpc containing the fix,
|
||||
// replace this singleton with inline usage for simplicity.
|
||||
// The fix should be in https://github.com/open-telemetry/opentelemetry-go/pull/5797.
|
||||
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
|
||||
}
|
||||
|
||||
// ClientCertProvider is a function that returns a TLS client certificate to be
|
||||
// used when opening TLS connections. It follows the same semantics as
|
||||
// [crypto/tls.Config.GetClientCertificate].
|
||||
@@ -223,6 +200,15 @@ type InternalOptions struct {
|
||||
// SkipValidation bypasses validation on Options. It should only be used
|
||||
// internally for clients that needs more control over their transport.
|
||||
SkipValidation bool
|
||||
// TelemetryAttributes specifies a map of telemetry attributes to be added
|
||||
// to all OpenTelemetry signals, such as tracing and metrics, for purposes
|
||||
// including representing the static identity of the client (e.g., service
|
||||
// name, version). These attributes are expected to be consistent across all
|
||||
// signals to enable cross-signal correlation.
|
||||
//
|
||||
// It should only be used internally by generated clients. Callers should not
|
||||
// modify the map after it is passed in.
|
||||
TelemetryAttributes map[string]string
|
||||
}
|
||||
|
||||
// Dial returns a GRPCClientConnPool that can be used to communicate with a
|
||||
@@ -444,5 +430,5 @@ func addOpenTelemetryStatsHandler(dialOpts []grpc.DialOption, opts *Options) []g
|
||||
if opts.DisableTelemetry {
|
||||
return dialOpts
|
||||
}
|
||||
return append(dialOpts, grpc.WithStatsHandler(otelGRPCStatsHandler()))
|
||||
return append(dialOpts, grpc.WithStatsHandler(otelgrpc.NewClientHandler()))
|
||||
}
|
||||
|
||||
+9
@@ -168,6 +168,15 @@ type InternalOptions struct {
|
||||
// for the credentials. It should only be used internally for clients that
|
||||
// need more control over their transport. The default is false.
|
||||
SkipUniverseDomainValidation bool
|
||||
// TelemetryAttributes specifies a map of telemetry attributes to be added
|
||||
// to all OpenTelemetry signals, such as tracing and metrics, for purposes
|
||||
// including representing the static identity of the client (e.g., service
|
||||
// name, version). These attributes are expected to be consistent across all
|
||||
// signals to enable cross-signal correlation.
|
||||
//
|
||||
// It should only be used internally by generated clients. Callers should not
|
||||
// modify the map after it is passed in.
|
||||
TelemetryAttributes map[string]string
|
||||
}
|
||||
|
||||
// AddAuthorizationMiddleware adds a middleware to the provided client's
|
||||
|
||||
-44
@@ -32,50 +32,6 @@ const (
|
||||
userCredsFilename = "application_default_credentials.json"
|
||||
)
|
||||
|
||||
// CredentialType represents different credential filetypes Google credentials
|
||||
// can be.
|
||||
type CredentialType int
|
||||
|
||||
const (
|
||||
// UnknownCredType is an unidentified file type.
|
||||
UnknownCredType CredentialType = iota
|
||||
// UserCredentialsKey represents a user creds file type.
|
||||
UserCredentialsKey
|
||||
// ServiceAccountKey represents a service account file type.
|
||||
ServiceAccountKey
|
||||
// ImpersonatedServiceAccountKey represents a impersonated service account
|
||||
// file type.
|
||||
ImpersonatedServiceAccountKey
|
||||
// ExternalAccountKey represents a external account file type.
|
||||
ExternalAccountKey
|
||||
// GDCHServiceAccountKey represents a GDCH file type.
|
||||
GDCHServiceAccountKey
|
||||
// ExternalAccountAuthorizedUserKey represents a external account authorized
|
||||
// user file type.
|
||||
ExternalAccountAuthorizedUserKey
|
||||
)
|
||||
|
||||
// parseCredentialType returns the associated filetype based on the parsed
|
||||
// typeString provided.
|
||||
func parseCredentialType(typeString string) CredentialType {
|
||||
switch typeString {
|
||||
case "service_account":
|
||||
return ServiceAccountKey
|
||||
case "authorized_user":
|
||||
return UserCredentialsKey
|
||||
case "impersonated_service_account":
|
||||
return ImpersonatedServiceAccountKey
|
||||
case "external_account":
|
||||
return ExternalAccountKey
|
||||
case "external_account_authorized_user":
|
||||
return ExternalAccountAuthorizedUserKey
|
||||
case "gdch_service_account":
|
||||
return GDCHServiceAccountKey
|
||||
default:
|
||||
return UnknownCredType
|
||||
}
|
||||
}
|
||||
|
||||
// GetFileNameFromEnv returns the override if provided or detects a filename
|
||||
// from the environment.
|
||||
func GetFileNameFromEnv(override string) string {
|
||||
|
||||
+1
@@ -140,6 +140,7 @@ type ImpersonatedServiceAccountFile struct {
|
||||
Type string `json:"type"`
|
||||
ServiceAccountImpersonationURL string `json:"service_account_impersonation_url"`
|
||||
Delegates []string `json:"delegates"`
|
||||
Scopes []string `json:"scopes"`
|
||||
CredSource json.RawMessage `json:"source_credentials"`
|
||||
UniverseDomain string `json:"universe_domain"`
|
||||
}
|
||||
|
||||
+4
-3
@@ -89,10 +89,11 @@ type fileTypeChecker struct {
|
||||
}
|
||||
|
||||
// ParseFileType determines the [CredentialType] based on bytes provided.
|
||||
func ParseFileType(b []byte) (CredentialType, error) {
|
||||
// Only returns error for json.Unmarshal.
|
||||
func ParseFileType(b []byte) (string, error) {
|
||||
var f fileTypeChecker
|
||||
if err := json.Unmarshal(b, &f); err != nil {
|
||||
return 0, err
|
||||
return "", err
|
||||
}
|
||||
return parseCredentialType(f.Type), nil
|
||||
return f.Type, nil
|
||||
}
|
||||
|
||||
+7
-6
@@ -88,12 +88,13 @@ func ParseKey(key []byte) (crypto.Signer, error) {
|
||||
key = block.Bytes
|
||||
}
|
||||
var parsedKey crypto.PrivateKey
|
||||
var err error
|
||||
parsedKey, err = x509.ParsePKCS8PrivateKey(key)
|
||||
if err != nil {
|
||||
parsedKey, err = x509.ParsePKCS1PrivateKey(key)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("private key should be a PEM or plain PKCS1 or PKCS8: %w", err)
|
||||
|
||||
var errPKCS8, errPKCS1, errEC error
|
||||
if parsedKey, errPKCS8 = x509.ParsePKCS8PrivateKey(key); errPKCS8 != nil {
|
||||
if parsedKey, errPKCS1 = x509.ParsePKCS1PrivateKey(key); errPKCS1 != nil {
|
||||
if parsedKey, errEC = x509.ParseECPrivateKey(key); errEC != nil {
|
||||
return nil, fmt.Errorf("failed to parse private key. Tried PKCS8, PKCS1, and EC formats. Errors: [PKCS8: %v], [PKCS1: %v], [EC: %v]", errPKCS8, errPKCS1, errEC)
|
||||
}
|
||||
}
|
||||
}
|
||||
parsed, ok := parsedKey.(crypto.Signer)
|
||||
|
||||
+39
-2
@@ -17,13 +17,16 @@ package jwt
|
||||
import (
|
||||
"bytes"
|
||||
"crypto"
|
||||
"crypto/ecdsa"
|
||||
"crypto/rand"
|
||||
"crypto/rsa"
|
||||
"crypto/sha256"
|
||||
"encoding/asn1"
|
||||
"encoding/base64"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
"math/big"
|
||||
"strings"
|
||||
"time"
|
||||
)
|
||||
@@ -35,6 +38,8 @@ const (
|
||||
HeaderAlgES256 = "ES256"
|
||||
// HeaderType is the standard [Header.Type].
|
||||
HeaderType = "JWT"
|
||||
// ES256 key size
|
||||
es256KeySize = 32
|
||||
)
|
||||
|
||||
// Header represents a JWT header.
|
||||
@@ -127,6 +132,22 @@ func EncodeJWS(header *Header, c *Claims, signer crypto.Signer) (string, error)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
if header.Algorithm == HeaderAlgES256 {
|
||||
var ecSig struct {
|
||||
R, S *big.Int
|
||||
}
|
||||
if _, err := asn1.Unmarshal(sig, &ecSig); err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
rawSig := make([]byte, es256KeySize*2)
|
||||
|
||||
ecSig.R.FillBytes(rawSig[:es256KeySize])
|
||||
ecSig.S.FillBytes(rawSig[es256KeySize:])
|
||||
|
||||
sig = rawSig
|
||||
}
|
||||
return fmt.Sprintf("%s.%s", ss, base64.RawURLEncoding.EncodeToString(sig)), nil
|
||||
}
|
||||
|
||||
@@ -153,7 +174,7 @@ func DecodeJWS(payload string) (*Claims, error) {
|
||||
|
||||
// VerifyJWS tests whether the provided JWT token's signature was produced by
|
||||
// the private key associated with the provided public key.
|
||||
func VerifyJWS(token string, key *rsa.PublicKey) error {
|
||||
func VerifyJWS(token string, key crypto.PublicKey) error {
|
||||
parts := strings.Split(token, ".")
|
||||
if len(parts) != 3 {
|
||||
return errors.New("jwt: invalid token received, token must have 3 parts")
|
||||
@@ -167,5 +188,21 @@ func VerifyJWS(token string, key *rsa.PublicKey) error {
|
||||
|
||||
h := sha256.New()
|
||||
h.Write([]byte(signedContent))
|
||||
return rsa.VerifyPKCS1v15(key, crypto.SHA256, h.Sum(nil), signatureString)
|
||||
hashed := h.Sum(nil)
|
||||
|
||||
switch pub := key.(type) {
|
||||
case *rsa.PublicKey:
|
||||
return rsa.VerifyPKCS1v15(pub, crypto.SHA256, hashed, signatureString)
|
||||
case *ecdsa.PublicKey:
|
||||
if len(signatureString) != 2*32 {
|
||||
return fmt.Errorf("jwt: ecdsa signature size should be 64 bytes, got %d", len(signatureString))
|
||||
}
|
||||
r := new(big.Int).SetBytes(signatureString[:32])
|
||||
s := new(big.Int).SetBytes(signatureString[32:])
|
||||
if !ecdsa.Verify(pub, hashed, r, s) {
|
||||
return errors.New("jwt: ecdsa signature verification failed")
|
||||
}
|
||||
return nil
|
||||
}
|
||||
return fmt.Errorf("jwt: unsupported public key type: %T", key)
|
||||
}
|
||||
|
||||
+2
-2
@@ -1,4 +1,4 @@
|
||||
// Copyright 2025 Google LLC
|
||||
// Copyright 2026 Google LLC
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
@@ -17,4 +17,4 @@
|
||||
package internal
|
||||
|
||||
// Version is the current tagged release of the library.
|
||||
const Version = "0.17.0"
|
||||
const Version = "0.18.2"
|
||||
|
||||
Reference in New Issue
Block a user