Skip to content

Conversation

@dimpavloff
Copy link
Contributor

@dimpavloff dimpavloff commented Aug 22, 2025

Part two for grpc/proposal#492 (A97), following #8431 .

What this PR does is:

  • update internal/xds/bootstrap with support for loading multiple PerRPCCallCredentials specifed in a new call_creds field in the boostrap file as per A97
  • adjust xds/internal/xdsclient/clientimpl.goto use the call credentials when constructing the client
  • update xds/bootstrap to register the jwtcreds call credentials and make them available if GRPC_EXPERIMENTAL_XDS_BOOTSTRAP_CALL_CREDS is enabled

I have added DialOptionsWithCallCredsForTransport because, even though current and future call credentials are likely to all expect secure transport, I thought it would be safer to check of insecure transport just in case. If you prefer, I can just update DialOptions to use all call credentials regardless of the transport.

Relates to istio/istio#53532

RELEASE NOTES:

  • xds: add support for loading a JWT from file and use it as Call Credentials (A97). To enable this feature, set the environment variable GRPC_EXPERIMENTAL_XDS_BOOTSTRAP_CALL_CREDS to true (case insensitive).

Copy link
Contributor Author

@dimpavloff dimpavloff left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the review and for the fixes @easwars ! I've addressed the latest comments.

Copy link
Contributor

@arjan-bal arjan-bal left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Mostly looks good, left some minor comments.

Comment on lines +379 to +381
if callCreds == nil {
continue
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is there a benefit to allowing the returned PerRPCCredentials to be nil?

It seems that if a credential's configuration required a no-op, the implementer could simply return a dedicated no-op implementation to achieve the same result.

My concern is that allowing nil forces every consumer of the API to add nil checks or risk a panic.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think there's any benefit to allowing them to be nil, I'm just being defensive here. It's not something that can be enforced with the current interface (Build(config json.RawMessage) (credentials.PerRPCCredentials, func(), error) ) other than through convention.

I could document it in the interface if you want

Copy link
Contributor

@arjan-bal arjan-bal Nov 3, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

gRPC Go utilizes global registries for builders in many places, and the library does not expect these builders to return nil. When a builder returns nil, it is considered an illegal state and can result in a panic. Some examples:

In my opinion, it is okay to omit the nil check here and document in the Build method's comments that it must not return nil. We could also return an error if we don't want gRPC to panic. If nil PerRPCCredentials are silently ignored, developers might begin to rely on this implicit nil check, forcing every future call site of Build to also handle nil values for consistency.

Also note that checking nil values for interfaces can be error-prone. Consider the following code:

package main

import "fmt"

type Element interface{}

type SomeImplementation struct{}

func f() Element {
	return nil
}

func g() Element {
	var result *SomeImplementation
	return result
}

func main() {
	fmt.Printf("f() != nil: %v, f(): %v\n", f() == nil, f()) // Prints: false, %!p(<nil>)
	fmt.Printf("g() != nil: %v, g(): %v\n", g() != nil, g()) // Prints: true, <nil>
}

Go playground: https://go.dev/play/p/hbc9cnbihBk
This document has an explanation: https://go.dev/doc/faq#nil_error

@arjan-bal arjan-bal assigned dimpavloff and unassigned arjan-bal Nov 3, 2025
Copy link
Contributor Author

@dimpavloff dimpavloff left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks @arjan-bal . Could you please take another look?

Comment on lines +379 to +381
if callCreds == nil {
continue
}
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think there's any benefit to allowing them to be nil, I'm just being defensive here. It's not something that can be enforced with the current interface (Build(config json.RawMessage) (credentials.PerRPCCredentials, func(), error) ) other than through convention.

I could document it in the interface if you want

@dimpavloff dimpavloff requested a review from arjan-bal November 3, 2025 08:42
@dimpavloff dimpavloff removed their assignment Nov 3, 2025
@arjan-bal arjan-bal assigned arjan-bal and dimpavloff and unassigned arjan-bal Nov 3, 2025
@arjan-bal arjan-bal modified the milestones: 1.78 Release, 1.77 Release Nov 3, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Area: xDS Includes everything xDS related, including LB policies used with xDS. Type: Feature New features or improvements in behavior

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants