Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(auth): add universe domain support to mTLS #11159

Merged
merged 9 commits into from
Nov 21, 2024
5 changes: 3 additions & 2 deletions auth/grpctransport/grpctransport.go
Original file line number Diff line number Diff line change
Expand Up @@ -197,7 +197,8 @@ type InternalOptions struct {
// DefaultEndpointTemplate combined with UniverseDomain specifies
// the default endpoint.
DefaultEndpointTemplate string
// DefaultMTLSEndpoint specifies the default mTLS endpoint.
// DefaultMTLSEndpoint combined with UniverseDomain specifies the
// default mTLS endpoint.
DefaultMTLSEndpoint string
// DefaultScopes specifies the default OAuth2 scopes to be used for a
// service.
Expand Down Expand Up @@ -244,7 +245,7 @@ func dial(ctx context.Context, secure bool, opts *Options) (*grpc.ClientConn, er
}
if io := opts.InternalOptions; io != nil {
tOpts.DefaultEndpointTemplate = io.DefaultEndpointTemplate
tOpts.DefaultMTLSEndpoint = io.DefaultMTLSEndpoint
tOpts.DefaultMTLSEndpointTemplate = io.DefaultMTLSEndpoint
quartzmo marked this conversation as resolved.
Show resolved Hide resolved
tOpts.EnableDirectPath = io.EnableDirectPath
tOpts.EnableDirectPathXds = io.EnableDirectPathXds
}
Expand Down
5 changes: 3 additions & 2 deletions auth/httptransport/httptransport.go
Original file line number Diff line number Diff line change
Expand Up @@ -141,7 +141,8 @@ type InternalOptions struct {
// DefaultEndpointTemplate combined with UniverseDomain specifies the
// default endpoint.
DefaultEndpointTemplate string
// DefaultMTLSEndpoint specifies the default mTLS endpoint.
// DefaultMTLSEndpoint combined with UniverseDomain specifies the
// default mTLS endpoint.
DefaultMTLSEndpoint string
// DefaultScopes specifies the default OAuth2 scopes to be used for a
// service.
Expand Down Expand Up @@ -200,7 +201,7 @@ func NewClient(opts *Options) (*http.Client, error) {
}
if io := opts.InternalOptions; io != nil {
tOpts.DefaultEndpointTemplate = io.DefaultEndpointTemplate
tOpts.DefaultMTLSEndpoint = io.DefaultMTLSEndpoint
tOpts.DefaultMTLSEndpointTemplate = io.DefaultMTLSEndpoint
codyoss marked this conversation as resolved.
Show resolved Hide resolved
}
clientCertProvider, dialTLSContext, err := transport.GetHTTPTransportConfig(tOpts)
if err != nil {
Expand Down
52 changes: 27 additions & 25 deletions auth/internal/transport/cba.go
Original file line number Diff line number Diff line change
Expand Up @@ -51,22 +51,18 @@ const (
mtlsMDSKey = "/run/google-mds-mtls/client.key"
)

var (
errUniverseNotSupportedMTLS = errors.New("mTLS is not supported in any universe other than googleapis.com")
)

// Options is a struct that is duplicated information from the individual
// transport packages in order to avoid cyclic deps. It correlates 1:1 with
// fields on httptransport.Options and grpctransport.Options.
type Options struct {
Endpoint string
DefaultMTLSEndpoint string
DefaultEndpointTemplate string
ClientCertProvider cert.Provider
Client *http.Client
UniverseDomain string
EnableDirectPath bool
EnableDirectPathXds bool
Endpoint string
DefaultEndpointTemplate string
DefaultMTLSEndpointTemplate string
ClientCertProvider cert.Provider
Client *http.Client
UniverseDomain string
EnableDirectPath bool
EnableDirectPathXds bool
}

// getUniverseDomain returns the default service domain for a given Cloud
Expand Down Expand Up @@ -94,6 +90,16 @@ func (o *Options) defaultEndpoint() string {
return strings.Replace(o.DefaultEndpointTemplate, universeDomainPlaceholder, o.getUniverseDomain(), 1)
}

// defaultMTLSEndpoint returns the DefaultMTLSEndpointTemplate merged with the
// universe domain if the DefaultMTLSEndpointTemplate is set, otherwise returns an
// empty string.
func (o *Options) defaultMTLSEndpoint() string {
if o.DefaultMTLSEndpointTemplate == "" {
return ""
}
return strings.Replace(o.DefaultMTLSEndpointTemplate, universeDomainPlaceholder, o.getUniverseDomain(), 1)
}

// mergedEndpoint merges a user-provided Endpoint of format host[:port] with the
// default endpoint.
func (o *Options) mergedEndpoint() (string, error) {
Expand Down Expand Up @@ -256,9 +262,6 @@ func getTransportConfig(opts *Options) (*transportConfig, error) {
if !shouldUseS2A(clientCertSource, opts) {
return &defaultTransportConfig, nil
}
if !opts.isUniverseDomainGDU() {
return nil, errUniverseNotSupportedMTLS
}

s2aAddress := GetS2AAddress()
mtlsS2AAddress := GetMTLSS2AAddress()
Expand All @@ -270,7 +273,7 @@ func getTransportConfig(opts *Options) (*transportConfig, error) {
endpoint: endpoint,
s2aAddress: s2aAddress,
mtlsS2AAddress: mtlsS2AAddress,
s2aMTLSEndpoint: opts.DefaultMTLSEndpoint,
s2aMTLSEndpoint: opts.defaultMTLSEndpoint(),
}, nil
}

Expand Down Expand Up @@ -316,24 +319,23 @@ type transportConfig struct {
// getEndpoint returns the endpoint for the service, taking into account the
// user-provided endpoint override "settings.Endpoint".
//
// If no endpoint override is specified, we will either return the default endpoint or
// the default mTLS endpoint if a client certificate is available.
// If no endpoint override is specified, we will either return the default
// endpoint or the default mTLS endpoint if a client certificate is available.
//
// You can override the default endpoint choice (mtls vs. regular) by setting the
// GOOGLE_API_USE_MTLS_ENDPOINT environment variable.
// You can override the default endpoint choice (mTLS vs. regular) by setting
// the GOOGLE_API_USE_MTLS_ENDPOINT environment variable.
//
// If the endpoint override is an address (host:port) rather than full base
// URL (ex. https://...), then the user-provided address will be merged into
// the default endpoint. For example, WithEndpoint("myhost:8000") and
// DefaultEndpointTemplate("https://UNIVERSE_DOMAIN/bar/baz") will return "https://myhost:8080/bar/baz"
// DefaultEndpointTemplate("https://UNIVERSE_DOMAIN/bar/baz") will return
// "https://myhost:8080/bar/baz". Note that this does not apply to the mTLS
// endpoint.
func getEndpoint(opts *Options, clientCertSource cert.Provider) (string, error) {
if opts.Endpoint == "" {
mtlsMode := getMTLSMode()
if mtlsMode == mTLSModeAlways || (clientCertSource != nil && mtlsMode == mTLSModeAuto) {
if !opts.isUniverseDomainGDU() {
return "", errUniverseNotSupportedMTLS
}
return opts.DefaultMTLSEndpoint, nil
return opts.defaultMTLSEndpoint(), nil
}
return opts.defaultEndpoint(), nil
}
Expand Down
Loading
Loading