Description
Current State:
Today external scaler metadata has the following:
metadata:
scalerAddress: external-scaler-service:8080
tlsCertFile : /path/to/tls/cert.pem
the Grpc connection is created using:
if metadata.tlsCertFile != "" {
creds, err := credentials.NewClientTLSFromFile(metadata.tlsCertFile, "")
...
return grpc.Dial(metadata.scalerAddress, grpc.WithTransportCredentials(creds))
}
return grpc.Dial(metadata.scalerAddress, grpc.WithTransportCredentials(insecure.NewCredentials()))
This means that is tlsCertFile
is provided, the grpc connection will be tls. tlsCertFile
is expected to be the CA file the client expect to validate the server cert with credentials.NewClientTLSFromFile()
If no tlsCertFile
is defined, KEDA creates the grpc connection using insecure.NewCredentials()
which doesn't do auth or encryption (https).
Proposal:
- deprecate
tlsCertFile
(only because the naming is confusing considering what it does. - introduce new metadata properties:
metadata:
scalerAddress: external-scaler-service:8080
caCert : /path/to/tls/ca.pem # optional
tlsClientCert: /path/to/tls/cert.pem # optional
tlsClientKey: /path/to/tls/key.pem # optional
forceTls: false # optional
skipInsecureVerify: false # optional
If caCert
, tlsClientCert
, and/or tlsClientKey
are defined, the connection must be TLS.
If they are not defined, by default KEDA will do HTTP connection, but with forceTls
it'll use tls.
The code will look like:
// tlsCertFile behavies the same way, but is deprecated
if metadata.tlsCertFile != "" {
creds, err := credentials.NewClientTLSFromFile(metadata.tlsCertFile, "")
// handle err
return grpc.Dial(metadata.scalerAddress, grpc.WithTransportCredentials(creds))
}
// Build a full tls.Config{} based on supplied caCert, tlsClientCert, tlsClientKey, and insecureSkipVerify
tlsConfig := &tls.Config{}
if metadata.caCert != nil {
tlsConfig.RootCAs = metadata.caCert
}
if metadata.tlsClientCert != nil && metadata.tlsClientKey != nil {
tlsCert, err := tls.X509KeyPair(metadata.tlsClientCert, metadata.tlsClientKey)
// handle err
tlsConfig.Certificates = []tls.Certificate{ tlsCert }
}
if metadata.insecureSkipVerify {
tlsConfig.InsecureSkipVerify = metadata.insecureSkipVerify
}
// if there is a CA cert set, or a client cert, or forceTls, use the generated tls.Config{}
if metadata.forceTls || len(tlsConfig.Certificates) > 0 || tlsConfig.RootCAs != nil {
return grpc.Dial(metadata.scalerAddress, grpc.WithTransportCredentials(credentials.NewTLS(tlsConfig)))
}
// fall back to currect behavior of no auth, no encryption.
return grpc.Dial(metadata.scalerAddress, grpc.WithTransportCredentials(insecure.NewCredentials()))
- support
TriggerAuthentication
to resolve these values from a secret, rather than needing to mount them on KEDA pod
apiVersion: keda.sh/v1alpha1
kind: TriggerAuthentication
metadata:
name: keda-external-trigger-auth
spec:
secretTargetRef:
- parameter: caCert
name: external-scaler-secrets
key: ca.pem
- parameter: tlsClientCert
name: external-scaler-secrets
key: cert.pem
- parameter: tlsClientKey
name: external-scaler-secrets
key: key.pem
Use-Case
Today it's not possible to use mtls or just https without a ca file. This will enable these scenarios for external scalers.
Anything else?
No response
Metadata
Assignees
Labels
Type
Projects
Status
Ready To Ship