Skip to content

Commit ac60db1

Browse files
Add flag guarding SPIFFE Bundle provider (#8343) (#8382)
Co-authored-by: Gregory Cooke <[email protected]>
1 parent 183c148 commit ac60db1

File tree

5 files changed

+90
-5
lines changed

5 files changed

+90
-5
lines changed

credentials/tls/certprovider/pemfile/builder.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ import (
2424
"time"
2525

2626
"google.golang.org/grpc/credentials/tls/certprovider"
27+
"google.golang.org/grpc/internal/envconfig"
2728
"google.golang.org/protobuf/encoding/protojson"
2829
"google.golang.org/protobuf/types/known/durationpb"
2930
)
@@ -72,6 +73,9 @@ func pluginConfigFromJSON(jd json.RawMessage) (Options, error) {
7273
if err := json.Unmarshal(jd, cfg); err != nil {
7374
return Options{}, fmt.Errorf("pemfile: json.Unmarshal(%s) failed: %v", string(jd), err)
7475
}
76+
if !envconfig.XDSSPIFFEEnabled {
77+
cfg.SPIFFETrustBundleMapFile = ""
78+
}
7579

7680
opts := Options{
7781
CertFile: cfg.CertificateFile,

credentials/tls/certprovider/pemfile/builder_test.go

Lines changed: 36 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -21,14 +21,18 @@ package pemfile
2121
import (
2222
"encoding/json"
2323
"testing"
24+
25+
"google.golang.org/grpc/internal/envconfig"
26+
"google.golang.org/grpc/internal/testutils"
2427
)
2528

2629
func TestParseConfig(t *testing.T) {
2730
tests := []struct {
28-
desc string
29-
input any
30-
wantOutput string
31-
wantErr bool
31+
desc string
32+
input any
33+
wantOutput string
34+
wantErr bool
35+
enabledSpiffe bool
3236
}{
3337
{
3438
desc: "non JSON input",
@@ -107,10 +111,38 @@ func TestParseConfig(t *testing.T) {
107111
}`),
108112
wantOutput: "file_watcher:/a/b/cert.pem:/a/b/key.pem:/a/b/ca.pem::3m20s",
109113
},
114+
{
115+
desc: "good config with spiffe disabled",
116+
input: json.RawMessage(`
117+
{
118+
"certificate_file": "/a/b/cert.pem",
119+
"private_key_file": "/a/b/key.pem",
120+
"ca_certificate_file": "/a/b/ca.pem",
121+
"spiffe_trust_bundle_map_file": "/a/b/spiffe_bundle.json",
122+
"refresh_interval": "200s"
123+
}`),
124+
wantOutput: "file_watcher:/a/b/cert.pem:/a/b/key.pem:/a/b/ca.pem::3m20s",
125+
},
126+
{
127+
desc: "good config with spiffe enabled",
128+
input: json.RawMessage(`
129+
{
130+
"certificate_file": "/a/b/cert.pem",
131+
"private_key_file": "/a/b/key.pem",
132+
"ca_certificate_file": "/a/b/ca.pem",
133+
"spiffe_trust_bundle_map_file": "/a/b/spiffe_bundle.json",
134+
"refresh_interval": "200s"
135+
}`),
136+
wantOutput: "file_watcher:/a/b/cert.pem:/a/b/key.pem:/a/b/ca.pem:/a/b/spiffe_bundle.json:3m20s",
137+
enabledSpiffe: true,
138+
},
110139
}
111140

112141
for _, test := range tests {
113142
t.Run(test.desc, func(t *testing.T) {
143+
if test.enabledSpiffe {
144+
testutils.SetEnvConfig(t, &envconfig.XDSSPIFFEEnabled, true)
145+
}
114146
builder := &pluginBuilder{}
115147

116148
bc, err := builder.ParseConfig(test.input)

internal/envconfig/xds.go

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,4 +63,9 @@ var (
6363
// For more details, see:
6464
// https://github.com/grpc/proposal/blob/master/A82-xds-system-root-certs.md.
6565
XDSSystemRootCertsEnabled = boolFromEnv("GRPC_EXPERIMENTAL_XDS_SYSTEM_ROOT_CERTS", false)
66+
67+
// XDSSPIFFEEnabled controls if SPIFFE Bundle Maps can be used as roots of
68+
// trust. For more details, see:
69+
// https://github.com/grpc/proposal/blob/master/A87-mtls-spiffe-support.md
70+
XDSSPIFFEEnabled = boolFromEnv("GRPC_EXPERIMENTAL_XDS_MTLS_SPIFFE", false)
6671
)

internal/xds/bootstrap/tlscreds/bundle.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@ import (
3636
"google.golang.org/grpc/credentials/tls/certprovider"
3737
"google.golang.org/grpc/credentials/tls/certprovider/pemfile"
3838
"google.golang.org/grpc/internal/credentials/spiffe"
39+
"google.golang.org/grpc/internal/envconfig"
3940
)
4041

4142
// bundle is an implementation of credentials.Bundle which implements mTLS
@@ -64,6 +65,9 @@ func NewBundle(jd json.RawMessage) (credentials.Bundle, func(), error) {
6465
}
6566
} // Else the config field is absent. Treat it as an empty config.
6667

68+
if !envconfig.XDSSPIFFEEnabled {
69+
cfg.SPIFFETrustBundleMapFile = ""
70+
}
6771
if cfg.CACertificateFile == "" && cfg.CertificateFile == "" && cfg.PrivateKeyFile == "" && cfg.SPIFFETrustBundleMapFile == "" {
6872
// We cannot use (and do not need) a file_watcher provider in this case,
6973
// and can simply directly use the TLS transport credentials.

internal/xds/bootstrap/tlscreds/bundle_ext_test.go

Lines changed: 41 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ import (
3030

3131
"google.golang.org/grpc"
3232
"google.golang.org/grpc/codes"
33+
"google.golang.org/grpc/internal/envconfig"
3334
"google.golang.org/grpc/internal/grpctest"
3435
"google.golang.org/grpc/internal/stubserver"
3536
"google.golang.org/grpc/internal/testutils"
@@ -237,6 +238,7 @@ func (s) TestCaReloading(t *testing.T) {
237238
// is performed and checked for failure, ensuring that gRPC is correctly using
238239
// the changed-on-disk bundle map.
239240
func (s) Test_SPIFFE_Reloading(t *testing.T) {
241+
testutils.SetEnvConfig(t, &envconfig.XDSSPIFFEEnabled, true)
240242
clientSPIFFEBundle, err := os.ReadFile(testdata.Path("spiffe_end2end/client_spiffebundle.json"))
241243
if err != nil {
242244
t.Fatalf("Failed to read test SPIFFE bundle: %v", err)
@@ -357,6 +359,7 @@ func (s) TestMTLS(t *testing.T) {
357359
// chain that is compatible with the client's configured SPIFFE bundle map. An
358360
// MTLS connection is attempted between the two and checked for success.
359361
func (s) Test_MTLS_SPIFFE(t *testing.T) {
362+
testutils.SetEnvConfig(t, &envconfig.XDSSPIFFEEnabled, true)
360363
tests := []struct {
361364
name string
362365
serverOption grpc.ServerOption
@@ -372,7 +375,7 @@ func (s) Test_MTLS_SPIFFE(t *testing.T) {
372375
}
373376
for _, tc := range tests {
374377
t.Run(tc.name, func(t *testing.T) {
375-
s := stubserver.StartTestService(t, nil, grpc.Creds(testutils.CreateServerTLSCredentialsCompatibleWithSPIFFE(t, tls.RequireAndVerifyClientCert)))
378+
s := stubserver.StartTestService(t, nil, tc.serverOption)
376379
defer s.Stop()
377380

378381
cfg := fmt.Sprintf(`{
@@ -403,7 +406,44 @@ func (s) Test_MTLS_SPIFFE(t *testing.T) {
403406
}
404407
}
405408

409+
// Test_MTLS_SPIFFE_FlagDisabled configures a client and server. The server has
410+
// a certificate chain that is compatible with the client's configured SPIFFE
411+
// bundle map. However, the XDS flag that enabled SPIFFE usage is disabled. An
412+
// MTLS connection is attempted between the two and checked for failure.
413+
func (s) Test_MTLS_SPIFFE_FlagDisabled(t *testing.T) {
414+
testutils.SetEnvConfig(t, &envconfig.XDSSPIFFEEnabled, false)
415+
serverOption := grpc.Creds(testutils.CreateServerTLSCredentialsCompatibleWithSPIFFE(t, tls.RequireAndVerifyClientCert))
416+
s := stubserver.StartTestService(t, nil, serverOption)
417+
defer s.Stop()
418+
419+
cfg := fmt.Sprintf(`{
420+
"certificate_file": "%s",
421+
"private_key_file": "%s",
422+
"spiffe_trust_bundle_map_file": "%s"
423+
}`,
424+
testdata.Path("spiffe_end2end/client_spiffe.pem"),
425+
testdata.Path("spiffe_end2end/client.key"),
426+
testdata.Path("spiffe_end2end/client_spiffebundle.json"))
427+
tlsBundle, stop, err := tlscreds.NewBundle([]byte(cfg))
428+
if err != nil {
429+
t.Fatalf("Failed to create TLS bundle: %v", err)
430+
}
431+
defer stop()
432+
conn, err := grpc.NewClient(s.Address, grpc.WithCredentialsBundle(tlsBundle), grpc.WithAuthority("x.test.example.com"))
433+
if err != nil {
434+
t.Fatalf("Error dialing: %v", err)
435+
}
436+
defer conn.Close()
437+
client := testgrpc.NewTestServiceClient(conn)
438+
ctx, cancel := context.WithTimeout(context.Background(), defaultTestTimeout)
439+
defer cancel()
440+
if _, err = client.EmptyCall(ctx, &testpb.Empty{}); err == nil {
441+
t.Errorf("EmptyCall(): got success want failure")
442+
}
443+
}
444+
406445
func (s) Test_MTLS_SPIFFE_Failure(t *testing.T) {
446+
testutils.SetEnvConfig(t, &envconfig.XDSSPIFFEEnabled, true)
407447
tests := []struct {
408448
name string
409449
certFile string

0 commit comments

Comments
 (0)