Skip to content
Merged
Changes from all 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
108 changes: 108 additions & 0 deletions proposals/005-filter-api-to-expose-client-and-server-tls-info.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,108 @@

# Authentication APIs

This proposal describes a set of public APIs to expose client and server TLS certificates for downstream-to-proxy and proxy-to-upstream connections to plugin implementations.
It makes use of [proposal-004](proposal-004) for the terminology used.


## Current situation

The `Filter` and `FilterContext` APIs currently don't directly expose any authenticated client identity information.

## Motivation

The lack of API support makes implementing client identity aware plugins difficult, or impossible.

Goals:

* Allow the possibility for new kinds of KRPC intercepting plugins in the future by not assuming that `Filters` are the only kind of KRPC intercepting plugin. We'll use the term **plugin**, unless saying something specifically about `Filters`.
* Allow access to TLS-specific details by plugins should they need them.
* Provide a flexible API to make serving niche use cases possible (though perhaps not simple).

## Proposal

### API for Filters to access client TLS information

TLS (in contrast to SASL) is handled entirely by the proxy runtime.
By the time a `Filter` is instantiated the proxy already has an established TLS connection.
All that's required is an API for exposing appropriate details to `Filters`.

The following method will be added to the existing `FilterContext` interface:

```java
/**
* @return The TLS context for the connection between the Kafka client and the proxy,
* or empty if the client connection is not TLS.
*/
Optional<ClientTlsContext> clientTlsContext();
```

Where `ClientTlsContext` is a new interface in the new package `io.kroxylicious.proxy.tls`:

```
package io.kroxylicious.proxy.tls;

import java.security.cert.X509Certificate;
import java.util.Optional;

public interface ClientTlsContext {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

While I have fewer issues with calling this ClientTlsContext than I do with ServerTlsContext I think this is better named DownstreamTlsContext.

/**
* @return The TLS server certificate that the proxy presented to the client during TLS handshake.
*/
X509Certificate proxyServerCertificate();

/**
* @return the TLS client certificate was presented by the Kafka client to the proxy during TLS handshake,
* or empty if no TLS client certificate was presented.
*/
Optional<X509Certificate> clientCertificate();

}
```

Having a distinct type, `ClientTlsContext`, means we can easily expose the same information to future plugins that are not filters (and thus do not have access to a `FilterContext`).


### API for Filters to access server TLS information

The API for exposing the proxy-to-broker TLS information to `Filters` is very similar to the client one. The following method will be added to `FilterContext`:

```java
/**
* @return The TLS context for the connection between the proxy and the Kafka server,
* or empty if the server connection is not TLS.
*/
Optional<ServerTlsContext> serverTlsContext();
```

Where

```java
package io.kroxylicious.proxy.tls;

import java.security.cert.X509Certificate;
import java.util.Optional;

public interface ServerTlsContext {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I was wondering about changing server to broker here but then remembered we want to retain the idea we can proxy controllers as well so we are back to the usual upstream vs server argument.

I still think upstream is clearer and entirely unambiguous where as server is not.

/**
* @return The TLS server certificate that the proxy presented to the server during TLS handshake,
* or empty if no TLS server certificate was presented during TLS handshake.
*/
Optional<X509Certificate> proxyClientCertificate();

/**
* @return the TLS server certificate was presented by the Kafka server to the proxy during TLS handshake.
*/
X509Certificate serverCertificate();
Comment on lines +93 to +96
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Upstream clearly conveys that it is the remote certificate and avoids needing to talk about Kafka server which is not normal parlance when discussing Kafka.

Suggested change
/**
* @return the TLS server certificate was presented by the Kafka server to the proxy during TLS handshake.
*/
X509Certificate serverCertificate();
/**
* @return the TLS server certificate was presented by the remote Kafka process to the proxy during TLS handshake.
*/
X509Certificate upstreamCertificate();

}
```

## Affected/not affected projects

The `kroxylicous` repo.

## Compatibility

This change would be backwards compatible for `Filter` developers and proxy users (i.e. all existing proxy configurations files would still be valid).