Skip to content
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

fix: use tls config from BTP when connecting to the OIDC provider's well-known endpoint. #4857

Merged
merged 22 commits into from
Jan 7, 2025
Merged
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
75 changes: 57 additions & 18 deletions internal/gatewayapi/securitypolicy.go
Original file line number Diff line number Diff line change
@@ -6,6 +6,8 @@
package gatewayapi

import (
"crypto/tls"
"crypto/x509"
"encoding/json"
"errors"
"fmt"
@@ -672,25 +674,10 @@ func (t *Translator) buildOIDCProvider(policy *egv1a1.SecurityPolicy, resources
protocol ir.AppProtocol
rd *ir.RouteDestination
traffic *ir.TrafficFeatures
providerTLS *ir.TLSUpstreamConfig
err error
)

// Discover the token and authorization endpoints from the issuer's
// well-known url if not explicitly specified
if provider.TokenEndpoint == nil || provider.AuthorizationEndpoint == nil {
tokenEndpoint, authorizationEndpoint, err = fetchEndpointsFromIssuer(provider.Issuer)
if err != nil {
return nil, fmt.Errorf("error fetching endpoints from issuer: %w", err)
}
} else {
tokenEndpoint = *provider.TokenEndpoint
authorizationEndpoint = *provider.AuthorizationEndpoint
}

if err = validateTokenEndpoint(tokenEndpoint); err != nil {
return nil, err
}

u, err := url.Parse(tokenEndpoint)
if err != nil {
return nil, err
@@ -708,6 +695,31 @@ func (t *Translator) buildOIDCProvider(policy *egv1a1.SecurityPolicy, resources
}
}

if rd != nil {
for _, st := range rd.Settings {
if st.TLS != nil {
providerTLS = st.TLS
break
}
}
}

// Discover the token and authorization endpoints from the issuer's
// well-known url if not explicitly specified
if provider.TokenEndpoint == nil || provider.AuthorizationEndpoint == nil {
tokenEndpoint, authorizationEndpoint, err = fetchEndpointsFromIssuer(provider.Issuer, providerTLS)
if err != nil {
return nil, fmt.Errorf("error fetching endpoints from issuer: %w", err)
}
} else {
tokenEndpoint = *provider.TokenEndpoint
authorizationEndpoint = *provider.AuthorizationEndpoint
}

if err = validateTokenEndpoint(tokenEndpoint); err != nil {
return nil, err
}

if traffic, err = translateTrafficFeatures(provider.BackendSettings); err != nil {
return nil, err
}
@@ -764,9 +776,36 @@ type OpenIDConfig struct {
AuthorizationEndpoint string `json:"authorization_endpoint"`
}

func fetchEndpointsFromIssuer(issuerURL string) (string, string, error) {
func fetchEndpointsFromIssuer(issuerURL string, providerTLS *ir.TLSUpstreamConfig) (string, string, error) {
var tlsConfig *tls.Config

if providerTLS != nil {
tlsConfig = &tls.Config{
ServerName: providerTLS.SNI,
MinVersion: tls.VersionTLS13,
}
if providerTLS.CACertificate != nil {
caCertPool := x509.NewCertPool()
caCertPool.AppendCertsFromPEM(providerTLS.CACertificate.Certificate)
tlsConfig.RootCAs = caCertPool
}
for _, cert := range providerTLS.ClientCertificates {
cert, err := tls.X509KeyPair(cert.Certificate, cert.PrivateKey)
if err != nil {
return "", "", err
}
tlsConfig.Certificates = append(tlsConfig.Certificates, cert)
}
}

// Fetch the OpenID configuration from the issuer URL
resp, err := http.Get(fmt.Sprintf("%s/.well-known/openid-configuration", issuerURL))
client := &http.Client{}
if tlsConfig != nil {
client.Transport = &http.Transport{
TLSClientConfig: tlsConfig,
}
}
resp, err := client.Get(fmt.Sprintf("%s/.well-known/openid-configuration", issuerURL))
if err != nil {
return "", "", err
}
Original file line number Diff line number Diff line change
@@ -99,3 +99,47 @@ securityPolicies:
defaultTokenTTL: 30m
refreshToken: true
defaultRefreshTokenTTL: 24h
configMaps:
- apiVersion: v1
kind: ConfigMap
metadata:
name: ca-cmap
namespace: envoy-gateway
data:
ca.crt: |
-----BEGIN CERTIFICATE-----
MIIDJzCCAg+gAwIBAgIUAl6UKIuKmzte81cllz5PfdN2IlIwDQYJKoZIhvcNAQEL
BQAwIzEQMA4GA1UEAwwHbXljaWVudDEPMA0GA1UECgwGa3ViZWRiMB4XDTIzMTAw
MjA1NDE1N1oXDTI0MTAwMTA1NDE1N1owIzEQMA4GA1UEAwwHbXljaWVudDEPMA0G
A1UECgwGa3ViZWRiMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAwSTc
1yj8HW62nynkFbXo4VXKv2jC0PM7dPVky87FweZcTKLoWQVPQE2p2kLDK6OEszmM
yyr+xxWtyiveremrWqnKkNTYhLfYPhgQkczib7eUalmFjUbhWdLvHakbEgCodn3b
kz57mInX2VpiDOKg4kyHfiuXWpiBqrCx0KNLpxo3DEQcFcsQTeTHzh4752GV04RU
Ti/GEWyzIsl4Rg7tGtAwmcIPgUNUfY2Q390FGqdH4ahn+mw/6aFbW31W63d9YJVq
ioyOVcaMIpM5B/c7Qc8SuhCI1YGhUyg4cRHLEw5VtikioyE3X04kna3jQAj54YbR
bpEhc35apKLB21HOUQIDAQABo1MwUTAdBgNVHQ4EFgQUyvl0VI5vJVSuYFXu7B48
6PbMEAowHwYDVR0jBBgwFoAUyvl0VI5vJVSuYFXu7B486PbMEAowDwYDVR0TAQH/
BAUwAwEB/zANBgkqhkiG9w0BAQsFAAOCAQEAMLxrgFVMuNRq2wAwcBt7SnNR5Cfz
2MvXq5EUmuawIUi9kaYjwdViDREGSjk7JW17vl576HjDkdfRwi4E28SydRInZf6J
i8HZcZ7caH6DxR335fgHVzLi5NiTce/OjNBQzQ2MJXVDd8DBmG5fyatJiOJQ4bWE
A7FlP0RdP3CO3GWE0M5iXOB2m1qWkE2eyO4UHvwTqNQLdrdAXgDQlbam9e4BG3Gg
d/6thAkWDbt/QNT+EJHDCvhDRKh1RuGHyg+Y+/nebTWWrFWsktRrbOoHCZiCpXI1
3eXE6nt0YkgtDxG22KqnhpAg9gUSs2hlhoxyvkzyF0mu6NhPlwAgnq7+/Q==
-----END CERTIFICATE-----
backendTLSPolicies:
- apiVersion: gateway.networking.k8s.io/v1alpha2
kind: BackendTLSPolicy
metadata:
name: policy-btls-backend-fqdn
namespace: envoy-gateway
spec:
targetRefs:
- group: gateway.envoyproxy.io
kind: Backend
name: backend-fqdn
validation:
caCertificateRefs:
- name: ca-cmap
group: ''
kind: ConfigMap
hostname: oauth.foo.com
Original file line number Diff line number Diff line change
@@ -1,3 +1,35 @@
backendTLSPolicies:
- apiVersion: gateway.networking.k8s.io/v1alpha2
kind: BackendTLSPolicy
metadata:
creationTimestamp: null
name: policy-btls-backend-fqdn
namespace: envoy-gateway
spec:
targetRefs:
- group: gateway.envoyproxy.io
kind: Backend
name: backend-fqdn
validation:
caCertificateRefs:
- group: ""
kind: ConfigMap
name: ca-cmap
hostname: oauth.foo.com
status:
ancestors:
- ancestorRef:
group: gateway.envoyproxy.io
kind: SecurityPolicy
name: policy-for-gateway
namespace: envoy-gateway
conditions:
- lastTransitionTime: null
message: Policy has been accepted.
reason: Accepted
status: "True"
type: Accepted
controllerName: gateway.envoyproxy.io/gatewayclass-controller
backends:
- apiVersion: gateway.envoyproxy.io/v1alpha1
kind: Backend
@@ -234,7 +266,12 @@ xdsIR:
endpoints:
- host: oauth.foo.com
port: 443
protocol: HTTPS
tls:
alpnProtocols: null
caCertificate:
certificate: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSURKekNDQWcrZ0F3SUJBZ0lVQWw2VUtJdUttenRlODFjbGx6NVBmZE4ySWxJd0RRWUpLb1pJaHZjTkFRRUwKQlFBd0l6RVFNQTRHQTFVRUF3d0hiWGxqYVdWdWRERVBNQTBHQTFVRUNnd0dhM1ZpWldSaU1CNFhEVEl6TVRBdwpNakExTkRFMU4xb1hEVEkwTVRBd01UQTFOREUxTjFvd0l6RVFNQTRHQTFVRUF3d0hiWGxqYVdWdWRERVBNQTBHCkExVUVDZ3dHYTNWaVpXUmlNSUlCSWpBTkJna3Foa2lHOXcwQkFRRUZBQU9DQVE4QU1JSUJDZ0tDQVFFQXdTVGMKMXlqOEhXNjJueW5rRmJYbzRWWEt2MmpDMFBNN2RQVmt5ODdGd2VaY1RLTG9XUVZQUUUycDJrTERLNk9Fc3ptTQp5eXIreHhXdHlpdmVyZW1yV3FuS2tOVFloTGZZUGhnUWtjemliN2VVYWxtRmpVYmhXZEx2SGFrYkVnQ29kbjNiCmt6NTdtSW5YMlZwaURPS2c0a3lIZml1WFdwaUJxckN4MEtOTHB4bzNERVFjRmNzUVRlVEh6aDQ3NTJHVjA0UlUKVGkvR0VXeXpJc2w0Umc3dEd0QXdtY0lQZ1VOVWZZMlEzOTBGR3FkSDRhaG4rbXcvNmFGYlczMVc2M2Q5WUpWcQppb3lPVmNhTUlwTTVCL2M3UWM4U3VoQ0kxWUdoVXlnNGNSSExFdzVWdGlraW95RTNYMDRrbmEzalFBajU0WWJSCmJwRWhjMzVhcEtMQjIxSE9VUUlEQVFBQm8xTXdVVEFkQmdOVkhRNEVGZ1FVeXZsMFZJNXZKVlN1WUZYdTdCNDgKNlBiTUVBb3dId1lEVlIwakJCZ3dGb0FVeXZsMFZJNXZKVlN1WUZYdTdCNDg2UGJNRUFvd0R3WURWUjBUQVFILwpCQVV3QXdFQi96QU5CZ2txaGtpRzl3MEJBUXNGQUFPQ0FRRUFNTHhyZ0ZWTXVOUnEyd0F3Y0J0N1NuTlI1Q2Z6CjJNdlhxNUVVbXVhd0lVaTlrYVlqd2RWaURSRUdTams3SlcxN3ZsNTc2SGpEa2RmUndpNEUyOFN5ZFJJblpmNkoKaThIWmNaN2NhSDZEeFIzMzVmZ0hWekxpNU5pVGNlL09qTkJRelEyTUpYVkRkOERCbUc1ZnlhdEppT0pRNGJXRQpBN0ZsUDBSZFAzQ08zR1dFME01aVhPQjJtMXFXa0UyZXlPNFVIdndUcU5RTGRyZEFYZ0RRbGJhbTllNEJHM0dnCmQvNnRoQWtXRGJ0L1FOVCtFSkhEQ3ZoRFJLaDFSdUdIeWcrWSsvbmViVFdXckZXc2t0UnJiT29IQ1ppQ3BYSTEKM2VYRTZudDBZa2d0RHhHMjJLcW5ocEFnOWdVU3MyaGxob3h5dmt6eUYwbXU2TmhQbHdBZ25xNysvUT09Ci0tLS0tRU5EIENFUlRJRklDQVRFLS0tLS0K
name: policy-btls-backend-fqdn/envoy-gateway-ca
sni: oauth.foo.com
weight: 1
tokenEndpoint: https://oauth.foo.com/token
traffic:
Original file line number Diff line number Diff line change
@@ -40,6 +40,12 @@ http:
port: 443
protocol: HTTPS
weight: 1
tls:
alpnProtocols: null
caCertificate:
certificate: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSURKekNDQWcrZ0F3SUJBZ0lVQWw2VUtJdUttenRlODFjbGx6NVBmZE4ySWxJd0RRWUpLb1pJaHZjTkFRRUwKQlFBd0l6RVFNQTRHQTFVRUF3d0hiWGxqYVdWdWRERVBNQTBHQTFVRUNnd0dhM1ZpWldSaU1CNFhEVEl6TVRBdwpNakExTkRFMU4xb1hEVEkwTVRBd01UQTFOREUxTjFvd0l6RVFNQTRHQTFVRUF3d0hiWGxqYVdWdWRERVBNQTBHCkExVUVDZ3dHYTNWaVpXUmlNSUlCSWpBTkJna3Foa2lHOXcwQkFRRUZBQU9DQVE4QU1JSUJDZ0tDQVFFQXdTVGMKMXlqOEhXNjJueW5rRmJYbzRWWEt2MmpDMFBNN2RQVmt5ODdGd2VaY1RLTG9XUVZQUUUycDJrTERLNk9Fc3ptTQp5eXIreHhXdHlpdmVyZW1yV3FuS2tOVFloTGZZUGhnUWtjemliN2VVYWxtRmpVYmhXZEx2SGFrYkVnQ29kbjNiCmt6NTdtSW5YMlZwaURPS2c0a3lIZml1WFdwaUJxckN4MEtOTHB4bzNERVFjRmNzUVRlVEh6aDQ3NTJHVjA0UlUKVGkvR0VXeXpJc2w0Umc3dEd0QXdtY0lQZ1VOVWZZMlEzOTBGR3FkSDRhaG4rbXcvNmFGYlczMVc2M2Q5WUpWcQppb3lPVmNhTUlwTTVCL2M3UWM4U3VoQ0kxWUdoVXlnNGNSSExFdzVWdGlraW95RTNYMDRrbmEzalFBajU0WWJSCmJwRWhjMzVhcEtMQjIxSE9VUUlEQVFBQm8xTXdVVEFkQmdOVkhRNEVGZ1FVeXZsMFZJNXZKVlN1WUZYdTdCNDgKNlBiTUVBb3dId1lEVlIwakJCZ3dGb0FVeXZsMFZJNXZKVlN1WUZYdTdCNDg2UGJNRUFvd0R3WURWUjBUQVFILwpCQVV3QXdFQi96QU5CZ2txaGtpRzl3MEJBUXNGQUFPQ0FRRUFNTHhyZ0ZWTXVOUnEyd0F3Y0J0N1NuTlI1Q2Z6CjJNdlhxNUVVbXVhd0lVaTlrYVlqd2RWaURSRUdTams3SlcxN3ZsNTc2SGpEa2RmUndpNEUyOFN5ZFJJblpmNkoKaThIWmNaN2NhSDZEeFIzMzVmZ0hWekxpNU5pVGNlL09qTkJRelEyTUpYVkRkOERCbUc1ZnlhdEppT0pRNGJXRQpBN0ZsUDBSZFAzQ08zR1dFME01aVhPQjJtMXFXa0UyZXlPNFVIdndUcU5RTGRyZEFYZ0RRbGJhbTllNEJHM0dnCmQvNnRoQWtXRGJ0L1FOVCtFSkhEQ3ZoRFJLaDFSdUdIeWcrWSsvbmViVFdXckZXc2t0UnJiT29IQ1ppQ3BYSTEKM2VYRTZudDBZa2d0RHhHMjJLcW5ocEFnOWdVU3MyaGxob3h5dmt6eUYwbXU2TmhQbHdBZ25xNysvUT09Ci0tLS0tRU5EIENFUlRJRklDQVRFLS0tLS0K
name: policy-btls-backend-fqdn/envoy-gateway-ca
sni: oauth.foo.com
tokenEndpoint: https://oauth.foo.com/token
traffic:
retry:
Original file line number Diff line number Diff line change
@@ -35,11 +35,36 @@
address: oauth.foo.com
portValue: 443
loadBalancingWeight: 1
metadata:
filterMetadata:
envoy.transport_socket_match:
name: securitypolicy/envoy-gateway/policy-for-gateway/0/tls/0
loadBalancingWeight: 1
locality:
region: securitypolicy/envoy-gateway/policy-for-gateway/0/backend/0
name: securitypolicy/envoy-gateway/policy-for-gateway/0
outlierDetection: {}
perConnectionBufferLimitBytes: 32768
respectDnsTtl: true
transportSocketMatches:
- match:
name: securitypolicy/envoy-gateway/policy-for-gateway/0/tls/0
name: securitypolicy/envoy-gateway/policy-for-gateway/0/tls/0
transportSocket:
name: envoy.transport_sockets.tls
typedConfig:
'@type': type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext
commonTlsContext:
combinedValidationContext:
defaultValidationContext:
matchTypedSubjectAltNames:
- matcher:
exact: oauth.foo.com
sanType: DNS
validationContextSdsSecretConfig:
name: policy-btls-backend-fqdn/envoy-gateway-ca
sdsConfig:
ads: {}
resourceApiVersion: V3
sni: oauth.foo.com
type: STRICT_DNS
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
- name: policy-btls-backend-fqdn/envoy-gateway-ca
validationContext:
trustedCa:
inlineBytes: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSURKekNDQWcrZ0F3SUJBZ0lVQWw2VUtJdUttenRlODFjbGx6NVBmZE4ySWxJd0RRWUpLb1pJaHZjTkFRRUwKQlFBd0l6RVFNQTRHQTFVRUF3d0hiWGxqYVdWdWRERVBNQTBHQTFVRUNnd0dhM1ZpWldSaU1CNFhEVEl6TVRBdwpNakExTkRFMU4xb1hEVEkwTVRBd01UQTFOREUxTjFvd0l6RVFNQTRHQTFVRUF3d0hiWGxqYVdWdWRERVBNQTBHCkExVUVDZ3dHYTNWaVpXUmlNSUlCSWpBTkJna3Foa2lHOXcwQkFRRUZBQU9DQVE4QU1JSUJDZ0tDQVFFQXdTVGMKMXlqOEhXNjJueW5rRmJYbzRWWEt2MmpDMFBNN2RQVmt5ODdGd2VaY1RLTG9XUVZQUUUycDJrTERLNk9Fc3ptTQp5eXIreHhXdHlpdmVyZW1yV3FuS2tOVFloTGZZUGhnUWtjemliN2VVYWxtRmpVYmhXZEx2SGFrYkVnQ29kbjNiCmt6NTdtSW5YMlZwaURPS2c0a3lIZml1WFdwaUJxckN4MEtOTHB4bzNERVFjRmNzUVRlVEh6aDQ3NTJHVjA0UlUKVGkvR0VXeXpJc2w0Umc3dEd0QXdtY0lQZ1VOVWZZMlEzOTBGR3FkSDRhaG4rbXcvNmFGYlczMVc2M2Q5WUpWcQppb3lPVmNhTUlwTTVCL2M3UWM4U3VoQ0kxWUdoVXlnNGNSSExFdzVWdGlraW95RTNYMDRrbmEzalFBajU0WWJSCmJwRWhjMzVhcEtMQjIxSE9VUUlEQVFBQm8xTXdVVEFkQmdOVkhRNEVGZ1FVeXZsMFZJNXZKVlN1WUZYdTdCNDgKNlBiTUVBb3dId1lEVlIwakJCZ3dGb0FVeXZsMFZJNXZKVlN1WUZYdTdCNDg2UGJNRUFvd0R3WURWUjBUQVFILwpCQVV3QXdFQi96QU5CZ2txaGtpRzl3MEJBUXNGQUFPQ0FRRUFNTHhyZ0ZWTXVOUnEyd0F3Y0J0N1NuTlI1Q2Z6CjJNdlhxNUVVbXVhd0lVaTlrYVlqd2RWaURSRUdTams3SlcxN3ZsNTc2SGpEa2RmUndpNEUyOFN5ZFJJblpmNkoKaThIWmNaN2NhSDZEeFIzMzVmZ0hWekxpNU5pVGNlL09qTkJRelEyTUpYVkRkOERCbUc1ZnlhdEppT0pRNGJXRQpBN0ZsUDBSZFAzQ08zR1dFME01aVhPQjJtMXFXa0UyZXlPNFVIdndUcU5RTGRyZEFYZ0RRbGJhbTllNEJHM0dnCmQvNnRoQWtXRGJ0L1FOVCtFSkhEQ3ZoRFJLaDFSdUdIeWcrWSsvbmViVFdXckZXc2t0UnJiT29IQ1ppQ3BYSTEKM2VYRTZudDBZa2d0RHhHMjJLcW5ocEFnOWdVU3MyaGxob3h5dmt6eUYwbXU2TmhQbHdBZ25xNysvUT09Ci0tLS0tRU5EIENFUlRJRklDQVRFLS0tLS0K
- genericSecret:
secret:
inlineBytes: Y2xpZW50MTpzZWNyZXQK
Loading