# Mutual TLS (mTLS)

Mututal TLS (mTLS) authentication requires TLS encryption, this page shows you how to configure both at the same time and is a superset of configurations required just for [Configuring the WarpStream Agents to terminate TLS](https://docs.warpstream.com/warpstream/kafka/protect-data-in-motion-with-tls-encryption#option-1-configuring-the-warpstream-agents-to-terminate-tls).

## Creating TLS keys and Certificates for the WarpStream Agents

Every organization has different policies on how to create and manage certificate. We recommend talking with your IT team for how to best create certificates in your organization.

If running WarpStream in Kubernetes using [cert-manager](https://cert-manager.io/) can be the easiest way to create certificates. It supports a wide range of certificate providers including private certificate authorities.

We recommend that either the certificate is made with `IP SANs` if using IP addresses or `SANS` if using hostnames to connect to your WarpStream Agents.

## Creating TLS keys and Certificate for the Kafka/Schema Registry Clients

When using mutual TLS, it is highly recommended to use a private certificate authority for certificates. Most large organizations typically already have their own internal private certificate authority that you can use to generate client certificates.

For alternatives if your organization does not have an existing private certificate authority, every cloud provider offers a managed solution, for example [AWS Private CA](https://docs.aws.amazon.com/privateca/latest/userguide/PcaWelcome.html). You can also create a certificate authority manually using the `openssl` command line however that can be complex to manage in production environments.

When using mutual TLS is it recommended to give each application their own unique certificate with their own unique Distinguished Name(DN). If using [ACLs](https://docs.warpstream.com/warpstream/kafka/manage-security/configure-acls) having unique certificates with unique DN's will allow each application to have it's own set of permissions.

## Configure WarpStream Agents for Kafka Clients

Once your certificates are generated to must set the `WARPSTREAM_TLS_SERVER_CERT_FILE` environment variable to the public key of the certificate and set `WARPSTREAM_TLS_SERVER_PRIVATE_KEY_FILE` to the private key of the certificate.

First, to enable TLS you must set the `WARPSTREAM_TLS_ENABLED` environment variable to `true`, or set the `kafkaTLS` flag. Then, to enable mutual TLS you must set the `WARPSTREAM_REQUIRE_MTLS_AUTHENTICATION` environment variable to `true`, or set the `requireMTLSAuthentication` flag.

Once authentication is enabled on the Agent, it will enforce that all Apache Kafka clients that connect to them authenticate themselves via mTLS. Otherwise, it will refuse the connection.

It is also highly recommended to set the environment variable `WARPSTREAM_TLS_CLIENT_CA_CERT_FILE` to the public keys of the certificate authorities that sign your client certificates. If this environment variable is not set WarpStream defaults to trusting all client certificates from your Operating System's root certificate store. This store typically contains all the public keys for all the publicly accepted certificate authorities. If this environment variable is not set any certificate from any public certificate authority will be valid and authenticated against your WarpStream agent which could cause external data leaks.

By default, the Agent will use the Distinguished Name(DN) from the client TLS certificate as the principal for ACLs. A custom TLS mapping rule regex can be provided using the `-tlsPrincipalMappingRule` flag to extract a name from the DN. For example, the rule `CN=([^,]+)` will extract the Common Name(CN) from the DN, and use that as the ACL principal.

For example, given a certificate with the DN of `CN=test_principal,O=ACME Corp`, if `-tlsPrincipalMappingRule` is set to `CN=([^,]+)` then the name `test_principal` will be used as the mTLS ACL principal.

#### SPIFFE Support

Requires Agent Version: v735

WarpStream supports decoding [SPIFFE](https://spiffe.io/) identity documents in X.509 format. SPIFFE IDs are a Uniform Resource Identifier (URI) which takes the following format: `spiffe://trust domain/workload identifier` for example `spiffe://acme.com/billing/payments`.\
\
To enable SPIFFE decoding set the flag `-spiffeMTLSAuthentication` or environment variable `WARPSTREAM_SPIFFE_MTLS_AUTHENTICATION` to true.

Once enabled this will require all mTLS client certificates to have a URI SAN set on their certificate in the spiffe URI format.

ACLs can then be made with the following principal format `User:spiffe://trust domain/workload identifier` for example `User:spiffe://acme.com/billing/payments`. An ACL principal can be defined to allow any workload ID under a trust domain by using a `*` symbol, for example `User:spiffe://acme.com/*`.

## Configure WarpStream Agents for Internal Communication

Requires Agent Version: v693

WarpStream agents can be configured to encrypt and authenticate internal agent to agent communication.\
\
First, to enable TLS you must set the `WARPSTREAM_INTERNAL_TLS_ENABLED` environment variable to `true`, or set the `internalTLS` flag.\
\
Then set the following flags or environment variables to their respective public and private keys:

* `internalTLSServerCertFile` or `WARPSTREAM_INTERNAL_TLS_SERVER_CERT_FILE`
  * The path to the public key of the certificate
* `internalTLSServerPrivateKeyFile` or `WARPSTREAM_INTERNAL_TLS_SERVER_PRIVATE_KEY_FILE`
  * The path to the private key of the certificate
* `internalTLSClientCACertFile` or `WARPSTREAM_INTERNAL_TLS_CLIENT_CA_CERT_FILE`
  * The path to the public key of the certificate authority that signed the above certificate

WarpStream agents use the provided certificate for both the TLS server certificate and the mTLS client certificate.\
\
By default WarpStream agents do not perform validation on the contents of the certificate, they only validate that the certificate is signed by the provided certificate authority. It is therefore recommended to use a unique certificate authority for internal communicate that is different from Kafka Clients.

If certificate validation is desired or a unique certificate authority cannot be used it is recommended to use SPIFFE as described bellow. This can be done by creating a certificate with a URI SAN in the SPIFFE URL format, for example `openssl req -new -key agent_key.pem -out agent.csr -subj "/CN=warpstream-agent" -addext 'subjectAltName = URI:spiffe://example.com/agent'`. For details on how to do this with your specific certificate authority see it's documentation.

#### SPIFFE Support

Requires Agent Version: v734

WarpStream Agents can be configured to validate [SPIFFE](https://spiffe.io/) identity documents for internal agent to agent communication. SPIFFE IDs are a Uniform Resource Identifier (URI) which takes the following format: `spiffe://trust domain/workload identifier` for example `spiffe://acme.com/billing/payments`.\
\
The Trust domain and workload ID can be specified via flags (`-internalSpiffeTrustDomain` and `-internalSpiffeWorkloadID`) or environment variables (`WARPSTREAM_INTERNAL_SPIFFE_TRUST_DOMAIN` and `WARPSTREAM_INTERNAL_SPIFFE_WORKLOAD_ID`).\
\
When set certificates without the specified trust domain and workload identity will be rejected.

## Configure Kafka and Schema Registry clients

For configuring mTLS in your Kafka/Schema Registry clients it is recommended to review the documentation for your client. Every client configures mTLS differently and those configurations may change version to version.

We recommend using the [Confluent Platform documentation](https://docs.confluent.io/platform/current/security/authentication/mutual-tls/overview.html#clients) to learn how to configure Java-based clients for mTLS.


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.warpstream.com/warpstream/kafka/manage-security/mutual-tls-mtls.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
