Skip to content

xds: parse allowed_grpc_services from the bootstrap config (A102)#9194

Open
mbissa wants to merge 3 commits into
grpc:masterfrom
mbissa:split-pr3-allowed-services
Open

xds: parse allowed_grpc_services from the bootstrap config (A102)#9194
mbissa wants to merge 3 commits into
grpc:masterfrom
mbissa:split-pr3-allowed-services

Conversation

@mbissa

@mbissa mbissa commented Jun 23, 2026

Copy link
Copy Markdown
Contributor

Adds parsing and credential resolution for the allowed_grpc_services bootstrap field (gRFC A102), used to validate side-channel targets received from untrusted xDS servers. Channel credentials stop at the first supported type; call credentials are built only when the call-creds env var is enabled.

This is second of 4 PRs and is independent of other PRs. Can be reviewed in isolation.

RELEASE NOTES: n/a

Adds parsing and credential resolution for the allowed_grpc_services
bootstrap field (gRFC A102), used to validate side-channel targets received
from untrusted xDS servers. The channel-credential selection stops at the
first supported type; call credentials are built only when the call-creds
env var is enabled, and are otherwise retained as config without being built.

RELEASE NOTES: n/a
@mbissa mbissa added this to the 1.83 Release milestone Jun 23, 2026
@mbissa mbissa added the Type: Feature New features or improvements in behavior label Jun 23, 2026
@mbissa

mbissa commented Jun 23, 2026

Copy link
Copy Markdown
Contributor Author

/gemini review

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Code Review

This pull request introduces the AllowedGrpcService struct and integrates an allowlist of gRPC services (allowed_grpc_services) into the xDS bootstrap configuration, along with corresponding JSON marshaling, unmarshaling, equality checks, and comprehensive unit tests. The review feedback highlights two important improvements: first, implementing a cleanup helper in Config.UnmarshalJSON to prevent resource leaks of active file watchers and credentials if subsequent parsing steps fail; second, refactoring AllowedGrpcService.UnmarshalJSON to be transactionally safe by using local variables and only mutating the receiver upon successful validation.

Comment thread internal/xds/bootstrap/bootstrap.go
Comment thread internal/xds/bootstrap/bootstrap.go
@codecov

codecov Bot commented Jun 23, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 64.03509% with 41 lines in your changes missing coverage. Please review.
✅ Project coverage is 83.15%. Comparing base (8d66cfc) to head (04e365c).
⚠️ Report is 9 commits behind head on master.

Files with missing lines Patch % Lines
internal/xds/bootstrap/bootstrap.go 64.03% 29 Missing and 12 partials ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##           master    #9194      +/-   ##
==========================================
- Coverage   83.27%   83.15%   -0.12%     
==========================================
  Files         419      419              
  Lines       33863    33977     +114     
==========================================
+ Hits        28198    28253      +55     
- Misses       4252     4290      +38     
- Partials     1413     1434      +21     
Files with missing lines Coverage Δ
internal/xds/bootstrap/bootstrap.go 63.96% <64.03%> (+0.02%) ⬆️

... and 25 files with indirect coverage changes

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@mbissa

mbissa commented Jun 23, 2026

Copy link
Copy Markdown
Contributor Author

/gemini review

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Code Review

This pull request introduces the AllowedGrpcService struct to the XDS bootstrap configuration, enabling the definition of gRPC service-specific credentials. The changes include updates to the Config struct, implementation of JSON marshaling and unmarshaling, and comprehensive testing for credential iteration and cleanup logic. The reviewer identified potential resource leaks in the UnmarshalJSON method, specifically noting that Authorities are not currently cleaned up and that resources might leak if json.Unmarshal fails mid-execution, and provided a suggested fix to improve the cleanup defer block.

Comment thread internal/xds/bootstrap/bootstrap.go
@mbissa

mbissa commented Jun 23, 2026

Copy link
Copy Markdown
Contributor Author

/gemini review

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Code Review

This pull request introduces support for AllowedGrpcServices in the xDS bootstrap configuration, allowing credentials configuration for allowed gRPC services. It also improves resource management by ensuring that any eagerly built credentials are properly cleaned up and released if bootstrap parsing or validation fails. The reviewer feedback suggests idiomatic Go improvements, such as using method expressions instead of anonymous function wrappers in slice/map equality checks, and using var declarations for empty slices to avoid unnecessary allocations.

Comment thread internal/xds/bootstrap/bootstrap.go
Comment thread internal/xds/bootstrap/bootstrap.go
Comment thread internal/xds/bootstrap/bootstrap.go
@mbissa mbissa requested a review from easwars June 23, 2026 21:18
@mbissa mbissa changed the title xds: parse allowed_grpc_services from the bootstrap config xds: parse allowed_grpc_services from the bootstrap config (A102) Jun 23, 2026
@easwars easwars assigned eshitachandwani and unassigned easwars Jun 25, 2026
@eshitachandwani eshitachandwani self-requested a review June 26, 2026 10:29
callCredsConfigs []CallCredsConfig
selectedChannelCreds ChannelCreds
selectedCallCreds []credentials.PerRPCCredentials
dialOptions []grpc.DialOption

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Can we add a comment for what the fields represent , mainly for the cleanup and dialOption

return a.selectedChannelCreds
}

// DialOptions returns dial options built from these credentials.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Can we clarify what these credentials mean ?

}

// ChannelCreds returns the list of parsed channel credentials.
func (a *AllowedGrpcService) ChannelCreds() []ChannelCreds {

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Just curious, where are we going to use these functions ?

// Equal reports whether a and other are considered equal.
func (a *AllowedGrpcService) Equal(other *AllowedGrpcService) bool {
switch {
case a == nil && other == nil:

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

I think using if statements with early return is more suitable here. WDYT ?

// A map from certprovider instance names to parsed buildable configs.
certProviderConfigs map[string]*certprovider.BuildableConfig

allowedGrpcServices map[string]*AllowedGrpcService

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Can we add a comment here as to what is the key and what does the map represent ?

break
}

if credsDialOption == nil {

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Shouldn't we do this check inside the for loop just after assigning credsDialOption ? Is there a reason it is done later ?

},
allowedGrpcServices: func() map[string]*AllowedGrpcService {
var svc AllowedGrpcService
if err := json.Unmarshal([]byte(`{"channel_creds": [{"type": "insecure"}]}`), &svc); err != nil {

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Instead of doing Unmarshal and then panic , can't we do this :

svc.channelCreds = []ChannelCreds{{Type: "insecure"}}

// channel-credential selection skips unsupported types and stops at the first
// supported one, and that call credentials are only built when the call-creds
// env var is enabled.
func (s) TestBootstrap_AllowedGrpcServices_CredentialIteration(t *testing.T) {

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Can we separate this test into different test since it anyway calls different t.Run for each different test

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Type: Feature New features or improvements in behavior

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants