diff --git a/proposals/007-plugin-api-to-select-tls-credentials-for-server-connection.md b/proposals/007-plugin-api-to-select-tls-credentials-for-server-connection.md new file mode 100644 index 0000000..8d5266a --- /dev/null +++ b/proposals/007-plugin-api-to-select-tls-credentials-for-server-connection.md @@ -0,0 +1,180 @@ +# Plugin API for selecting TLS client credentials for proxy-to-server connection + +This proposes a new plugin API for allowing the selection of the TLS client credentials to be used for the connection between the proxy and a Kafka server. +It makes use of [proposal-004](proposal-004) for the terminology used. + +## Current situation + +Currently the end user configures the client TLS information to be used for connections between the proxy and a target cluster. +This means that the client TLS certificate used cannot depend on information known at runtime. +This includes, in particular information about the client, such as the TLS client certificate that it provided to the proxy. + +## Motivation + +The lack of API support means all proxied clients have the same TLS identity from the broker's point of view. +This means a broker using the `TLS` value for `security.protocol` cannot distinguish between those clients. + +Goals: + +* Enable the selection of TLS client certificates at runtime. + +## Proposal + + +### API for selecting target cluster TLS credentials + +We will add a new plugin interface, `ServerTlsCredentialSupplierFactory`. +It will use the usual Kroxylicious plugin mechanism, leveraging `java.util.Service`-based discovery. +However, this plugin is not the same thing as a `FilterFactory`. +Rather, an implementation class will be defined on the `TargetCluster` configuration object, and instantiated once for each target cluster. +The TargetCluster's `tls` object will gain a `tlsCredentialSupplier` property, supporting `type` and `config` properties (similarly to how filters are configured). +The interface itself is declared like this: + +```java +package io.kroxylicious.proxy.tls; + +/** + *
A pluggable source of {@link ServerTlsCredentialSupplier} instances.
+ *ServerTlsCredentialSupplierFactories are:
+ *The plugin manager type + * @throws UnknownPluginInstanceException If the plugin could not be instantiated. + */ +
P pluginInstance(Class
pluginClass,
+ String instanceName)
+ throws UnknownPluginInstanceException;
+
+ /**
+ * Creates some TLS credentials for the given parameters.
+ * @param key The key corresponding to the given client certificate.
+ * @param certificateChain The client certificate corresponding to the given {@code key}, plus any intermediate certificates forming the certificate chain up to (but not including) the TLS certificate trusted by the peer.
+ * @return The TLS credentials instance.
+ * @see ServerTlsCredentialSupplier.Context#tlsCredentials(PrivateKey, Certificate[])
+ */
+ TlsCredentials tlsCredentials(PrivateKey key,
+ Certificate[] certificateChain);
+ }
+
+```
+
+So what is a `ServerTlsCredentialSupplier` that this factory creates?
+
+```java
+package io.kroxylicious.proxy.tls;
+
+import java.security.PrivateKey;
+import java.security.cert.Certificate;
+import java.util.Optional;
+import java.util.concurrent.CompletionStage;
+
+import io.kroxylicious.proxy.authentication.ClientSaslContext;
+
+/**
+ * Implemented by a {@link io.kroxylicious.proxy.filter.Filter} that provides
+ * the credentials for the TLS connection between the proxy and the Kafka server.
+ */
+public interface ServerTlsCredentialSupplier {
+ /**
+ * Return the TlsCredentials for the connection.
+ * @param context The context.
+ * @return the TlsCredentials for the connection.
+ */
+ CompletionStage Factory methods for creating TLS credentials for the given parameters. The equivalent method on {@code FilterFactoryContext} can be used when the credentials
+ * are known at plugin configuration time.