From 1512ea307e7824fc0e24d6eeb6e7fb3c731c3b53 Mon Sep 17 00:00:00 2001 From: Ronald Date: Thu, 29 Jun 2023 16:37:40 -0400 Subject: [PATCH] Dynamically create jwks clusters for jwt-providers (#17944) --- agent/xds/clusters.go | 94 +++++++++ agent/xds/clusters_test.go | 179 ++++++++++++++++++ agent/xds/jwt_authn.go | 15 +- agent/xds/jwt_authn_test.go | 19 +- .../jwt_authn/intention-with-path.golden | 2 +- ...ltiple-providers-and-one-permission.golden | 6 +- .../testdata/jwt_authn/remote-provider.golden | 2 +- .../top-level-provider-with-permission.golden | 4 +- ...ttp-provider-with-hostname-and-port.golden | 23 +++ ...http-provider-with-hostname-no-port.golden | 23 +++ .../http-provider-with-ip-and-port.golden | 23 +++ .../http-provider-with-ip-no-port.golden | 23 +++ ...tps-provider-with-hostname-and-port.golden | 32 ++++ ...ttps-provider-with-hostname-no-port.golden | 32 ++++ .../https-provider-with-ip-and-port.golden | 32 ++++ .../https-provider-with-ip-no-port.golden | 32 ++++ 16 files changed, 520 insertions(+), 21 deletions(-) create mode 100644 agent/xds/testdata/jwt_authn_clusters/http-provider-with-hostname-and-port.golden create mode 100644 agent/xds/testdata/jwt_authn_clusters/http-provider-with-hostname-no-port.golden create mode 100644 agent/xds/testdata/jwt_authn_clusters/http-provider-with-ip-and-port.golden create mode 100644 agent/xds/testdata/jwt_authn_clusters/http-provider-with-ip-no-port.golden create mode 100644 agent/xds/testdata/jwt_authn_clusters/https-provider-with-hostname-and-port.golden create mode 100644 agent/xds/testdata/jwt_authn_clusters/https-provider-with-hostname-no-port.golden create mode 100644 agent/xds/testdata/jwt_authn_clusters/https-provider-with-ip-and-port.golden create mode 100644 agent/xds/testdata/jwt_authn_clusters/https-provider-with-ip-no-port.golden diff --git a/agent/xds/clusters.go b/agent/xds/clusters.go index a6f58a11f2..68ae4643b4 100644 --- a/agent/xds/clusters.go +++ b/agent/xds/clusters.go @@ -6,6 +6,8 @@ package xds import ( "errors" "fmt" + "net/url" + "strconv" "strings" "time" @@ -141,6 +143,22 @@ func (s *ResourceGenerator) clustersFromSnapshotConnectProxy(cfgSnap *proxycfg.C clusters = append(clusters, upstreamCluster) } + // add clusters for jwt-providers + for _, prov := range cfgSnap.JWTProviders { + //skip cluster creation for local providers + if prov.JSONWebKeySet == nil || prov.JSONWebKeySet.Remote == nil { + continue + } + + cluster, err := makeJWTProviderCluster(prov) + if err != nil { + s.Logger.Warn("failed to make jwt-provider cluster", "provider name", prov.Name, "error", err) + continue + } + + clusters = append(clusters, cluster) + } + for _, u := range cfgSnap.Proxy.Upstreams { if u.DestinationType != structs.UpstreamDestTypePreparedQuery { continue @@ -184,6 +202,82 @@ func (s *ResourceGenerator) clustersFromSnapshotConnectProxy(cfgSnap *proxycfg.C return clusters, nil } +func makeJWTProviderCluster(p *structs.JWTProviderConfigEntry) (*envoy_cluster_v3.Cluster, error) { + if p.JSONWebKeySet == nil || p.JSONWebKeySet.Remote == nil { + return nil, fmt.Errorf("cannot create JWKS cluster for non-remote JWKS. Provider Name: %s", p.Name) + } + hostname, scheme, port, err := parseJWTRemoteURL(p.JSONWebKeySet.Remote.URI) + if err != nil { + return nil, err + } + + // TODO: expose additional fields: eg. ConnectTimeout, through + // JWTProviderConfigEntry to allow user to configure cluster + cluster := &envoy_cluster_v3.Cluster{ + Name: makeJWKSClusterName(p.Name), + ClusterDiscoveryType: &envoy_cluster_v3.Cluster_Type{ + Type: envoy_cluster_v3.Cluster_STRICT_DNS, + }, + LoadAssignment: &envoy_endpoint_v3.ClusterLoadAssignment{ + ClusterName: makeJWKSClusterName(p.Name), + Endpoints: []*envoy_endpoint_v3.LocalityLbEndpoints{ + { + LbEndpoints: []*envoy_endpoint_v3.LbEndpoint{ + makeEndpoint(hostname, port), + }, + }, + }, + }, + } + + if scheme == "https" { + // TODO: expose this configuration through JWTProviderConfigEntry to allow + // user to configure certs + jwksTLSContext, err := makeUpstreamTLSTransportSocket( + &envoy_tls_v3.UpstreamTlsContext{ + CommonTlsContext: &envoy_tls_v3.CommonTlsContext{ + ValidationContextType: &envoy_tls_v3.CommonTlsContext_ValidationContext{ + ValidationContext: &envoy_tls_v3.CertificateValidationContext{}, + }, + }, + }, + ) + if err != nil { + return nil, err + } + + cluster.TransportSocket = jwksTLSContext + } + return cluster, nil +} + +// parseJWTRemoteURL splits the URI into domain, scheme and port. +// It will default to port 80 for http and 443 for https for any +// URI that does not specify a port. +func parseJWTRemoteURL(uri string) (string, string, int, error) { + u, err := url.ParseRequestURI(uri) + if err != nil { + return "", "", 0, err + } + + var port int + if u.Port() != "" { + port, err = strconv.Atoi(u.Port()) + if err != nil { + return "", "", port, err + } + } + + if port == 0 { + port = 80 + if u.Scheme == "https" { + port = 443 + } + } + + return u.Hostname(), u.Scheme, port, nil +} + func makeExposeClusterName(destinationPort int) string { return fmt.Sprintf("exposed_cluster_%d", destinationPort) } diff --git a/agent/xds/clusters_test.go b/agent/xds/clusters_test.go index ff72bd35c8..446f0ae247 100644 --- a/agent/xds/clusters_test.go +++ b/agent/xds/clusters_test.go @@ -959,6 +959,185 @@ func TestEnvoyLBConfig_InjectToCluster(t *testing.T) { } } +func TestMakeJWTProviderCluster(t *testing.T) { + // All tests here depend on golden files located under: agent/xds/testdata/jwt_authn_cluster/* + tests := map[string]struct { + provider *structs.JWTProviderConfigEntry + expectedError string + }{ + "remote-jwks-not-configured": { + provider: &structs.JWTProviderConfigEntry{ + Kind: "jwt-provider", + Name: "okta", + JSONWebKeySet: &structs.JSONWebKeySet{}, + }, + expectedError: "cannot create JWKS cluster for non remote JWKS. Provider Name: okta", + }, + "local-jwks-configured": { + provider: &structs.JWTProviderConfigEntry{ + Kind: "jwt-provider", + Name: "okta", + JSONWebKeySet: &structs.JSONWebKeySet{ + Local: &structs.LocalJWKS{ + Filename: "filename", + }, + }, + }, + expectedError: "cannot create JWKS cluster for non remote JWKS. Provider Name: okta", + }, + "https-provider-with-hostname-no-port": { + provider: makeTestProviderWithJWKS("https://example-okta.com/.well-known/jwks.json"), + }, + "http-provider-with-hostname-no-port": { + provider: makeTestProviderWithJWKS("http://example-okta.com/.well-known/jwks.json"), + }, + "https-provider-with-hostname-and-port": { + provider: makeTestProviderWithJWKS("https://example-okta.com:90/.well-known/jwks.json"), + }, + "http-provider-with-hostname-and-port": { + provider: makeTestProviderWithJWKS("http://example-okta.com:90/.well-known/jwks.json"), + }, + "https-provider-with-ip-no-port": { + provider: makeTestProviderWithJWKS("https://127.0.0.1"), + }, + "http-provider-with-ip-no-port": { + provider: makeTestProviderWithJWKS("http://127.0.0.1"), + }, + "https-provider-with-ip-and-port": { + provider: makeTestProviderWithJWKS("https://127.0.0.1:9091"), + }, + "http-provider-with-ip-and-port": { + provider: makeTestProviderWithJWKS("http://127.0.0.1:9091"), + }, + } + + for name, tt := range tests { + tt := tt + t.Run(name, func(t *testing.T) { + cluster, err := makeJWTProviderCluster(tt.provider) + if tt.expectedError != "" { + require.Error(t, err, tt.expectedError) + } else { + require.NoError(t, err) + gotJSON := protoToJSON(t, cluster) + require.JSONEq(t, goldenSimple(t, filepath.Join("jwt_authn_clusters", name), gotJSON), gotJSON) + } + + }) + } +} + +func makeTestProviderWithJWKS(uri string) *structs.JWTProviderConfigEntry { + return &structs.JWTProviderConfigEntry{ + Kind: "jwt-provider", + Name: "okta", + Issuer: "test-issuer", + JSONWebKeySet: &structs.JSONWebKeySet{ + Remote: &structs.RemoteJWKS{ + RequestTimeoutMs: 1000, + FetchAsynchronously: true, + URI: uri, + }, + }, + } +} + +func TestParseJWTRemoteURL(t *testing.T) { + tests := map[string]struct { + uri string + expectedHost string + expectedPort int + expectedScheme string + expectError bool + }{ + "invalid-url": { + uri: ".com", + expectError: true, + }, + "https-hostname-no-port": { + uri: "https://test.test.com", + expectedHost: "test.test.com", + expectedPort: 443, + expectedScheme: "https", + }, + "https-hostname-with-port": { + uri: "https://test.test.com:4545", + expectedHost: "test.test.com", + expectedPort: 4545, + expectedScheme: "https", + }, + "https-hostname-with-port-and-path": { + uri: "https://test.test.com:4545/test", + expectedHost: "test.test.com", + expectedPort: 4545, + expectedScheme: "https", + }, + "http-hostname-no-port": { + uri: "http://test.test.com", + expectedHost: "test.test.com", + expectedPort: 80, + expectedScheme: "http", + }, + "http-hostname-with-port": { + uri: "http://test.test.com:4636", + expectedHost: "test.test.com", + expectedPort: 4636, + expectedScheme: "http", + }, + "https-ip-no-port": { + uri: "https://127.0.0.1", + expectedHost: "127.0.0.1", + expectedPort: 443, + expectedScheme: "https", + }, + "https-ip-with-port": { + uri: "https://127.0.0.1:3434", + expectedHost: "127.0.0.1", + expectedPort: 3434, + expectedScheme: "https", + }, + "http-ip-no-port": { + uri: "http://127.0.0.1", + expectedHost: "127.0.0.1", + expectedPort: 80, + expectedScheme: "http", + }, + "http-ip-with-port": { + uri: "http://127.0.0.1:9190", + expectedHost: "127.0.0.1", + expectedPort: 9190, + expectedScheme: "http", + }, + "http-ip-with-port-and-path": { + uri: "http://127.0.0.1:9190/some/where", + expectedHost: "127.0.0.1", + expectedPort: 9190, + expectedScheme: "http", + }, + "http-ip-no-port-with-path": { + uri: "http://127.0.0.1/test/path", + expectedHost: "127.0.0.1", + expectedPort: 80, + expectedScheme: "http", + }, + } + + for name, tt := range tests { + tt := tt + t.Run(name, func(t *testing.T) { + host, scheme, port, err := parseJWTRemoteURL(tt.uri) + if tt.expectError { + require.Error(t, err) + } else { + require.NoError(t, err) + require.Equal(t, host, tt.expectedHost) + require.Equal(t, scheme, tt.expectedScheme) + require.Equal(t, port, tt.expectedPort) + } + }) + } +} + // UID is just a convenience function to aid in writing tests less verbosely. func UID(input string) proxycfg.UpstreamID { return proxycfg.UpstreamIDFromString(input) diff --git a/agent/xds/jwt_authn.go b/agent/xds/jwt_authn.go index 0dc95f5eec..ba1c17bbc2 100644 --- a/agent/xds/jwt_authn.go +++ b/agent/xds/jwt_authn.go @@ -19,6 +19,7 @@ import ( const ( jwtEnvoyFilter = "envoy.filters.http.jwt_authn" jwtMetadataKeyPrefix = "jwt_payload" + jwksClusterPrefix = "jwks_cluster" ) // This is an intermediate JWTProvider form used to associate @@ -158,7 +159,7 @@ func buildJWTProviderConfig(p *structs.JWTProviderConfigEntry, metadataKeySuffix } envoyCfg.JwksSourceSpecifier = specifier } else if remote := p.JSONWebKeySet.Remote; remote != nil && remote.URI != "" { - envoyCfg.JwksSourceSpecifier = makeRemoteJWKS(remote) + envoyCfg.JwksSourceSpecifier = makeRemoteJWKS(remote, p.Name) } else { return nil, fmt.Errorf("invalid jwt provider config; missing JSONWebKeySet for provider: %s", p.Name) } @@ -210,14 +211,12 @@ func makeLocalJWKS(l *structs.LocalJWKS, pName string) (*envoy_http_jwt_authn_v3 return specifier, nil } -func makeRemoteJWKS(r *structs.RemoteJWKS) *envoy_http_jwt_authn_v3.JwtProvider_RemoteJwks { +func makeRemoteJWKS(r *structs.RemoteJWKS, providerName string) *envoy_http_jwt_authn_v3.JwtProvider_RemoteJwks { remote_specifier := envoy_http_jwt_authn_v3.JwtProvider_RemoteJwks{ RemoteJwks: &envoy_http_jwt_authn_v3.RemoteJwks{ HttpUri: &envoy_core_v3.HttpUri{ - Uri: r.URI, - // TODO(roncodingenthusiast): An explicit cluster is required. - // Need to figure out replacing `jwks_cluster` will an actual cluster - HttpUpstreamType: &envoy_core_v3.HttpUri_Cluster{Cluster: "jwks_cluster"}, + Uri: r.URI, + HttpUpstreamType: &envoy_core_v3.HttpUri_Cluster{Cluster: makeJWKSClusterName(providerName)}, }, AsyncFetch: &envoy_http_jwt_authn_v3.JwksAsyncFetch{ FastListener: r.FetchAsynchronously, @@ -239,6 +238,10 @@ func makeRemoteJWKS(r *structs.RemoteJWKS) *envoy_http_jwt_authn_v3.JwtProvider_ return &remote_specifier } +func makeJWKSClusterName(providerName string) string { + return fmt.Sprintf("%s_%s", jwksClusterPrefix, providerName) +} + func buildJWTRetryPolicy(r *structs.JWKSRetryPolicy) *envoy_core_v3.RetryPolicy { var pol envoy_core_v3.RetryPolicy if r == nil { diff --git a/agent/xds/jwt_authn_test.go b/agent/xds/jwt_authn_test.go index 589421e8c0..b2a7d7ce54 100644 --- a/agent/xds/jwt_authn_test.go +++ b/agent/xds/jwt_authn_test.go @@ -438,7 +438,7 @@ func TestBuildJWTProviderConfig(t *testing.T) { RemoteJwks: &envoy_http_jwt_authn_v3.RemoteJwks{ HttpUri: &envoy_core_v3.HttpUri{ Uri: oktaRemoteJWKS.URI, - HttpUpstreamType: &envoy_core_v3.HttpUri_Cluster{Cluster: "jwks_cluster"}, + HttpUpstreamType: &envoy_core_v3.HttpUri_Cluster{Cluster: makeJWKSClusterName(ceRemoteJWKS.Name)}, Timeout: &durationpb.Duration{Seconds: 1}, }, AsyncFetch: &envoy_http_jwt_authn_v3.JwksAsyncFetch{ @@ -520,16 +520,18 @@ func TestMakeLocalJWKS(t *testing.T) { func TestMakeRemoteJWKS(t *testing.T) { tests := map[string]struct { - jwks *structs.RemoteJWKS - expected *envoy_http_jwt_authn_v3.JwtProvider_RemoteJwks + jwks *structs.RemoteJWKS + providerName string + expected *envoy_http_jwt_authn_v3.JwtProvider_RemoteJwks }{ "with-no-cache-duration": { - jwks: oktaRemoteJWKS, + jwks: oktaRemoteJWKS, + providerName: "auth0", expected: &envoy_http_jwt_authn_v3.JwtProvider_RemoteJwks{ RemoteJwks: &envoy_http_jwt_authn_v3.RemoteJwks{ HttpUri: &envoy_core_v3.HttpUri{ Uri: oktaRemoteJWKS.URI, - HttpUpstreamType: &envoy_core_v3.HttpUri_Cluster{Cluster: "jwks_cluster"}, + HttpUpstreamType: &envoy_core_v3.HttpUri_Cluster{Cluster: makeJWKSClusterName("auth0")}, Timeout: &durationpb.Duration{Seconds: 1}, }, AsyncFetch: &envoy_http_jwt_authn_v3.JwksAsyncFetch{ @@ -539,12 +541,13 @@ func TestMakeRemoteJWKS(t *testing.T) { }, }, "with-retry-policy": { - jwks: extendedRemoteJWKS, + jwks: extendedRemoteJWKS, + providerName: "okta", expected: &envoy_http_jwt_authn_v3.JwtProvider_RemoteJwks{ RemoteJwks: &envoy_http_jwt_authn_v3.RemoteJwks{ HttpUri: &envoy_core_v3.HttpUri{ Uri: oktaRemoteJWKS.URI, - HttpUpstreamType: &envoy_core_v3.HttpUri_Cluster{Cluster: "jwks_cluster"}, + HttpUpstreamType: &envoy_core_v3.HttpUri_Cluster{Cluster: makeJWKSClusterName("okta")}, Timeout: &durationpb.Duration{Seconds: 1}, }, AsyncFetch: &envoy_http_jwt_authn_v3.JwksAsyncFetch{ @@ -560,7 +563,7 @@ func TestMakeRemoteJWKS(t *testing.T) { for name, tt := range tests { tt := tt t.Run(name, func(t *testing.T) { - res := makeRemoteJWKS(tt.jwks) + res := makeRemoteJWKS(tt.jwks, tt.providerName) require.Equal(t, res, tt.expected) }) } diff --git a/agent/xds/testdata/jwt_authn/intention-with-path.golden b/agent/xds/testdata/jwt_authn/intention-with-path.golden index 306ecad5f6..6e925758ca 100644 --- a/agent/xds/testdata/jwt_authn/intention-with-path.golden +++ b/agent/xds/testdata/jwt_authn/intention-with-path.golden @@ -9,7 +9,7 @@ "remoteJwks": { "httpUri": { "uri": "https://example-okta.com/.well-known/jwks.json", - "cluster": "jwks_cluster", + "cluster": "jwks_cluster_okta", "timeout": "1s" }, "asyncFetch": { diff --git a/agent/xds/testdata/jwt_authn/multiple-providers-and-one-permission.golden b/agent/xds/testdata/jwt_authn/multiple-providers-and-one-permission.golden index feb1d6012e..ca9a99265e 100644 --- a/agent/xds/testdata/jwt_authn/multiple-providers-and-one-permission.golden +++ b/agent/xds/testdata/jwt_authn/multiple-providers-and-one-permission.golden @@ -9,7 +9,7 @@ "remoteJwks": { "httpUri": { "uri": "https://example-okta.com/.well-known/jwks.json", - "cluster": "jwks_cluster", + "cluster": "jwks_cluster_okta", "timeout": "1s" }, "asyncFetch": { @@ -23,7 +23,7 @@ "remoteJwks": { "httpUri": { "uri": "https://example-okta.com/.well-known/jwks.json", - "cluster": "jwks_cluster", + "cluster": "jwks_cluster_okta", "timeout": "1s" }, "asyncFetch": { @@ -37,7 +37,7 @@ "remoteJwks": { "httpUri": { "uri": "https://example-auth0.com/.well-known/jwks.json", - "cluster": "jwks_cluster", + "cluster": "jwks_cluster_auth0", "timeout": "1s" }, "asyncFetch": { diff --git a/agent/xds/testdata/jwt_authn/remote-provider.golden b/agent/xds/testdata/jwt_authn/remote-provider.golden index b84e1ea102..6116a58cec 100644 --- a/agent/xds/testdata/jwt_authn/remote-provider.golden +++ b/agent/xds/testdata/jwt_authn/remote-provider.golden @@ -9,7 +9,7 @@ "remoteJwks": { "httpUri": { "uri": "https://example-okta.com/.well-known/jwks.json", - "cluster": "jwks_cluster", + "cluster": "jwks_cluster_okta", "timeout": "1s" }, "asyncFetch": { diff --git a/agent/xds/testdata/jwt_authn/top-level-provider-with-permission.golden b/agent/xds/testdata/jwt_authn/top-level-provider-with-permission.golden index 42a609470d..6eed6793df 100644 --- a/agent/xds/testdata/jwt_authn/top-level-provider-with-permission.golden +++ b/agent/xds/testdata/jwt_authn/top-level-provider-with-permission.golden @@ -9,7 +9,7 @@ "remoteJwks": { "httpUri": { "uri": "https://example-okta.com/.well-known/jwks.json", - "cluster": "jwks_cluster", + "cluster": "jwks_cluster_okta", "timeout": "1s" }, "asyncFetch": { @@ -23,7 +23,7 @@ "remoteJwks": { "httpUri": { "uri": "https://example-okta.com/.well-known/jwks.json", - "cluster": "jwks_cluster", + "cluster": "jwks_cluster_okta", "timeout": "1s" }, "asyncFetch": { diff --git a/agent/xds/testdata/jwt_authn_clusters/http-provider-with-hostname-and-port.golden b/agent/xds/testdata/jwt_authn_clusters/http-provider-with-hostname-and-port.golden new file mode 100644 index 0000000000..a8f9de349b --- /dev/null +++ b/agent/xds/testdata/jwt_authn_clusters/http-provider-with-hostname-and-port.golden @@ -0,0 +1,23 @@ +{ + "loadAssignment": { + "clusterName": "jwks_cluster_okta", + "endpoints": [ + { + "lbEndpoints": [ + { + "endpoint": { + "address": { + "socketAddress": { + "address": "example-okta.com", + "portValue": 90 + } + } + } + } + ] + } + ] + }, + "name": "jwks_cluster_okta", + "type": "STRICT_DNS" +} \ No newline at end of file diff --git a/agent/xds/testdata/jwt_authn_clusters/http-provider-with-hostname-no-port.golden b/agent/xds/testdata/jwt_authn_clusters/http-provider-with-hostname-no-port.golden new file mode 100644 index 0000000000..977b8c70f1 --- /dev/null +++ b/agent/xds/testdata/jwt_authn_clusters/http-provider-with-hostname-no-port.golden @@ -0,0 +1,23 @@ +{ + "loadAssignment": { + "clusterName": "jwks_cluster_okta", + "endpoints": [ + { + "lbEndpoints": [ + { + "endpoint": { + "address": { + "socketAddress": { + "address": "example-okta.com", + "portValue": 80 + } + } + } + } + ] + } + ] + }, + "name": "jwks_cluster_okta", + "type": "STRICT_DNS" +} \ No newline at end of file diff --git a/agent/xds/testdata/jwt_authn_clusters/http-provider-with-ip-and-port.golden b/agent/xds/testdata/jwt_authn_clusters/http-provider-with-ip-and-port.golden new file mode 100644 index 0000000000..f5dbc48409 --- /dev/null +++ b/agent/xds/testdata/jwt_authn_clusters/http-provider-with-ip-and-port.golden @@ -0,0 +1,23 @@ +{ + "loadAssignment": { + "clusterName": "jwks_cluster_okta", + "endpoints": [ + { + "lbEndpoints": [ + { + "endpoint": { + "address": { + "socketAddress": { + "address": "127.0.0.1", + "portValue": 9091 + } + } + } + } + ] + } + ] + }, + "name": "jwks_cluster_okta", + "type": "STRICT_DNS" +} \ No newline at end of file diff --git a/agent/xds/testdata/jwt_authn_clusters/http-provider-with-ip-no-port.golden b/agent/xds/testdata/jwt_authn_clusters/http-provider-with-ip-no-port.golden new file mode 100644 index 0000000000..e47f1a6fbe --- /dev/null +++ b/agent/xds/testdata/jwt_authn_clusters/http-provider-with-ip-no-port.golden @@ -0,0 +1,23 @@ +{ + "loadAssignment": { + "clusterName": "jwks_cluster_okta", + "endpoints": [ + { + "lbEndpoints": [ + { + "endpoint": { + "address": { + "socketAddress": { + "address": "127.0.0.1", + "portValue": 80 + } + } + } + } + ] + } + ] + }, + "name": "jwks_cluster_okta", + "type": "STRICT_DNS" +} \ No newline at end of file diff --git a/agent/xds/testdata/jwt_authn_clusters/https-provider-with-hostname-and-port.golden b/agent/xds/testdata/jwt_authn_clusters/https-provider-with-hostname-and-port.golden new file mode 100644 index 0000000000..54af47ef8b --- /dev/null +++ b/agent/xds/testdata/jwt_authn_clusters/https-provider-with-hostname-and-port.golden @@ -0,0 +1,32 @@ +{ + "loadAssignment": { + "clusterName": "jwks_cluster_okta", + "endpoints": [ + { + "lbEndpoints": [ + { + "endpoint": { + "address": { + "socketAddress": { + "address": "example-okta.com", + "portValue": 90 + } + } + } + } + ] + } + ] + }, + "name": "jwks_cluster_okta", + "transportSocket": { + "name": "tls", + "typedConfig": { + "@type":"type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext", + "commonTlsContext": { + "validationContext": {} + } + } + }, + "type": "STRICT_DNS" +} \ No newline at end of file diff --git a/agent/xds/testdata/jwt_authn_clusters/https-provider-with-hostname-no-port.golden b/agent/xds/testdata/jwt_authn_clusters/https-provider-with-hostname-no-port.golden new file mode 100644 index 0000000000..7b266fa484 --- /dev/null +++ b/agent/xds/testdata/jwt_authn_clusters/https-provider-with-hostname-no-port.golden @@ -0,0 +1,32 @@ +{ + "loadAssignment": { + "clusterName": "jwks_cluster_okta", + "endpoints": [ + { + "lbEndpoints": [ + { + "endpoint": { + "address": { + "socketAddress": { + "address": "example-okta.com", + "portValue": 443 + } + } + } + } + ] + } + ] + }, + "name": "jwks_cluster_okta", + "transportSocket": { + "name": "tls", + "typedConfig": { + "@type":"type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext", + "commonTlsContext": { + "validationContext": {} + } + } + }, + "type": "STRICT_DNS" +} \ No newline at end of file diff --git a/agent/xds/testdata/jwt_authn_clusters/https-provider-with-ip-and-port.golden b/agent/xds/testdata/jwt_authn_clusters/https-provider-with-ip-and-port.golden new file mode 100644 index 0000000000..bdcbe0f3dc --- /dev/null +++ b/agent/xds/testdata/jwt_authn_clusters/https-provider-with-ip-and-port.golden @@ -0,0 +1,32 @@ +{ + "loadAssignment": { + "clusterName": "jwks_cluster_okta", + "endpoints": [ + { + "lbEndpoints": [ + { + "endpoint": { + "address": { + "socketAddress": { + "address": "127.0.0.1", + "portValue": 9091 + } + } + } + } + ] + } + ] + }, + "name": "jwks_cluster_okta", + "transportSocket": { + "name": "tls", + "typedConfig": { + "@type":"type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext", + "commonTlsContext": { + "validationContext": {} + } + } + }, + "type": "STRICT_DNS" +} \ No newline at end of file diff --git a/agent/xds/testdata/jwt_authn_clusters/https-provider-with-ip-no-port.golden b/agent/xds/testdata/jwt_authn_clusters/https-provider-with-ip-no-port.golden new file mode 100644 index 0000000000..c72e0e93d9 --- /dev/null +++ b/agent/xds/testdata/jwt_authn_clusters/https-provider-with-ip-no-port.golden @@ -0,0 +1,32 @@ +{ + "loadAssignment": { + "clusterName": "jwks_cluster_okta", + "endpoints": [ + { + "lbEndpoints": [ + { + "endpoint": { + "address": { + "socketAddress": { + "address": "127.0.0.1", + "portValue": 443 + } + } + } + } + ] + } + ] + }, + "name": "jwks_cluster_okta", + "transportSocket": { + "name": "tls", + "typedConfig": { + "@type":"type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext", + "commonTlsContext": { + "validationContext": {} + } + } + }, + "type": "STRICT_DNS" +} \ No newline at end of file