-
Notifications
You must be signed in to change notification settings - Fork 4.6k
credentials: fix behavior of grpc.WithAuthority and credential handshake precedence #8488
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
Conversation
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## master #8488 +/- ##
==========================================
- Coverage 82.48% 82.43% -0.05%
==========================================
Files 413 413
Lines 40518 40534 +16
==========================================
- Hits 33422 33415 -7
- Misses 5738 5759 +21
- Partials 1358 1360 +2
🚀 New features to boost your workflow:
|
| // Deprecated: please use Peer.AuthInfo. | ||
| SecurityVersion string | ||
| // ServerName is the user-configured server name. | ||
| // ServerName is the user-configured server name. If set, this overrides |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
My first reading of this comment made me think that this is a value that the user can set. But that is not the case. This is a value returned by gRPC to the user. Would it be possible to reword this a little so that it is clear that this only conveys the creds' view of things.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think your initial understanding was correct.
This is returned by the credentials implementation and read by gRPC. The user controls how this is set by configuring the credentials directly.
| cc.authority = auth.OverrideAuthority(cc.parsedTarget) | ||
| } else if strings.HasPrefix(endpoint, ":") { | ||
| cc.authority = "localhost" + endpoint | ||
| cc.authority = "localhost" + encodeAuthority(endpoint) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is this a breaking change? Should this be release noted?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's a behavior change. Unclear if it's breaking; I would call it a bug fix. I'll mention it in the notes.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Added:
Also, properly percent-encode the port (if needed, which is very unlikely) when the target string omits the hostname and only specifies a port (grpc.NewClient(":<port-number-or-name>")).
| serverName = authority | ||
| } | ||
| cfg.ServerName = serverName | ||
|
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should we document on the NewTLS function that config.ServerName is ignored?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's not ignored, actually. It's used by the channel in the logic mentioned in the first PR comment, as long as the user didn't manually override the channel's authority.
Lines 1810 to 1813 in 9fa3267
| authorityFromCreds := "" | |
| if creds := dopts.copts.TransportCredentials; creds != nil && creds.Info().ServerName != "" { | |
| authorityFromCreds = creds.Info().ServerName | |
| } |
Line 106 in 9fa3267
| ServerName: c.config.ServerName, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This LGTM, I do worry about breakages from small behavior changes, but this is a bug so if a breakage does happen it's probably good in the end to discover it?
cc: @matthewstevenson88 for awareness
It's definitely a bug in that the credentials override is currently winning against the channel's override for handshaking, but what is used for RPCs is something else. The intent was for Thanks! |
Before this change, credentials would ignore the channel's understanding of the server name if the user configured them to do so. This is a mistake. The credentials should use the channel's setting. The channel already reads the credentials' preference and includes that in its logic.
A summary of how this worked:
creds.OverrideServerName, which can/should be implemented such that it affects the server name override. It does this by setting theProtocolInfo.ServerNamefield that is returned by itsInfomethod.grpc.WithAuthority; credentials; name resolver; channel default based on target string.creds.ClientHandshake. The creds should honor the value passed in.I also tidied up the documentation a bit and added a deprecation notice to
ProtocolInfo.ServerName.@gtcooke94 since this impacts advancedtls.
cc @ejona86 FYI
RELEASE NOTES:
grpc.WithAuthorityas the highest-priority option for setting authority, above the setting in the credentials themselves. Now that thisWithAuthorityis available, the credentials should not be used to override the authority. Also, properly percent-encode the port (if needed, which is very unlikely) when the target string omits the hostname and only specifies a port (grpc.NewClient(":<port-number-or-name>")).