> ## Documentation Index
> Fetch the complete documentation index at: https://docs.automq.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Mutual TLS (mTLS) Authentication

> Configure mTLS client authentication for AutoMQ Kafka clients.

Mutual TLS (mTLS) authenticates both sides of a Kafka connection. The client validates the AutoMQ server certificate, and AutoMQ validates a client certificate issued by a trusted client CA. AutoMQ maps the certificate identity to a Kafka ACL user and applies ACL authorization.

## Certificate responsibilities

Server certificate responsibilities depend on the DNS Zone mode selected when the instance is created. In both modes, you provide the client CA and issue a unique client certificate for each client identity.

| DNS Zone mode | Server certificate | Client certificates |
| - | - | - |
| AutoMQ Managed Public DNS Zone | AutoMQ provides, installs, and renews the authoritative server certificate. Do not upload a user-issued Server Certificate or Private Key. | You provide the client CA certificate and use the client CA private key to issue client certificates. |
| Customer-managed Private DNS Zone | You provide and rotate the server CA, Server Certificate, and Private Key. The Server Certificate SAN must match the private endpoint domain. | You provide the client CA and use its private key to issue client certificates. If the server and client use different CAs, combine their public certificates into one CA bundle for upload. |

> [!NOTE]
>
> Select the DNS Zone mode and enable mTLS when you create the instance. Existing instances cannot be changed from an unencrypted listener to mTLS.

## Configuration workflow

Complete the following steps in order:

1. Create or select a client CA and issue a Client Certificate. This step is required for both DNS Zone modes.
2. Prepare the server identity. AutoMQ manages it for a Public DNS Zone; you provide it for a Private DNS Zone.
3. Configure the AutoMQ instance.
4. Configure the Kafka client.

## Step 1: Create a client CA and Client Certificate

Both DNS Zone modes require a client CA and a Client Certificate. Use your organization's certificate management system when available. If you need to create and maintain a private client CA, use the following procedure as a reference.

> [!WARNING]
>
> Protect `client-ca.key` and `client.key` according to your organization's key management requirements. For client authentication, upload `client-ca.crt`, but never upload the client CA private key or Client Private Key. A customer-managed Private DNS Zone also requires the server materials described in Step 3.

### Create a client CA

Create `client-ca.cnf`. Replace the distinguished-name values before running the commands.

```ini theme={null}
[ req ]
prompt = no
distinguished_name = distinguished_name
x509_extensions = extensions

[ distinguished_name ]
organizationName = <organization-name>
commonName = <client-ca-common-name>

[ extensions ]
basicConstraints = critical,CA:true,pathlen:1
keyUsage = critical,keyCertSign,cRLSign
subjectKeyIdentifier = hash
authorityKeyIdentifier = keyid:always,issuer
```

Generate the client CA private key and certificate:

```bash theme={null}
openssl genrsa -out client-ca.key 2048
chmod 400 client-ca.key
openssl req -new -x509 \
  -config client-ca.cnf \
  -key client-ca.key \
  -days 3650 \
  -out client-ca.crt
```

### Issue a Client Certificate

Create the corresponding Kafka ACL user before issuing the Client Certificate. Unless you configure a different principal mapping rule, set the certificate Common Name (CN) to the ACL username.

The default principal mapping extracts the CN from the Client Certificate:

```text theme={null}
RULE:.*CN=([^,]+).*/$1/
```

For example, a certificate with `CN=user01` maps to the ACL user `user01`.

Create `client.cnf`:

```ini theme={null}
[ req ]
prompt = no
distinguished_name = distinguished_name
req_extensions = extensions

[ distinguished_name ]
organizationName = <organization-name>
commonName = <kafka-acl-username>

[ extensions ]
basicConstraints = critical,CA:false
keyUsage = critical,digitalSignature,keyEncipherment
extendedKeyUsage = clientAuth
```

Generate the Client Private Key and CSR, and then sign the CSR with the client CA:

```bash theme={null}
openssl genrsa -out client.key 2048
chmod 400 client.key
openssl req -new \
  -config client.cnf \
  -key client.key \
  -out client.csr
openssl x509 -req \
  -in client.csr \
  -CA client-ca.crt \
  -CAkey client-ca.key \
  -CAcreateserial \
  -days 365 \
  -extfile client.cnf \
  -extensions extensions \
  -out client.crt
```

Verify the certificate identity, purpose, and validity period:

```bash theme={null}
openssl x509 -in client.crt -noout -subject -issuer -dates -ext extendedKeyUsage
```

## Step 2: Prepare the server identity

### AutoMQ Managed Public DNS Zone

No user action is required. AutoMQ provides, installs, and renews the authoritative Server Certificate. Do not create or upload a Server Certificate or Server Private Key.

### Customer-managed Private DNS Zone

You must provide a Server Certificate whose Subject Alternative Name (SAN) covers the AutoMQ private endpoint names associated with the Private DNS Zone. Use a certificate issued by your organization's certificate authority when available.

The following reference procedure uses the client CA created in Step 1 to sign the Server Certificate. If your organization requires separate server and client CAs, use the server CA to sign the Server Certificate and retain both public CA certificates for the CA bundle in Step 3.

Create `server.cnf`. Use the exact DNS name or wildcard required by the instance endpoint. Do not rely on the Common Name for hostname verification.

```ini theme={null}
[ req ]
prompt = no
distinguished_name = distinguished_name
req_extensions = extensions

[ distinguished_name ]
organizationName = <organization-name>
commonName = <server-common-name>

[ extensions ]
basicConstraints = critical,CA:false
keyUsage = critical,digitalSignature,keyEncipherment
extendedKeyUsage = serverAuth
subjectAltName = @alt_names

[ alt_names ]
DNS.1 = <private-endpoint-dns-name-or-wildcard>
```

Generate the Server Private Key and CSR, and then sign the CSR:

```bash theme={null}
openssl genrsa -out server.key 2048
chmod 400 server.key
openssl req -new \
  -config server.cnf \
  -key server.key \
  -out server.csr
openssl x509 -req \
  -in server.csr \
  -CA client-ca.crt \
  -CAkey client-ca.key \
  -CAserial client-ca.srl \
  -days 365 \
  -extfile server.cnf \
  -extensions extensions \
  -out server.crt
```

Verify the certificate SAN, purpose, and validity period:

```bash theme={null}
openssl x509 -in server.crt -noout -subject -issuer -dates -ext subjectAltName,extendedKeyUsage
```

## Step 3: Configure AutoMQ

### AutoMQ Managed Public DNS Zone

1. When creating the instance, select `Public DNS Zone` and the AutoMQ managed mode.
2. Enable the mTLS listener.
3. Upload `client-ca.crt` as the Client CA certificate.
4. Do not upload a Server Certificate or Server Private Key.
5. Create the ACL user that matches the Client Certificate identity and grant only the required Topic and Consumer Group permissions.

### Customer-managed Private DNS Zone

1. When creating the instance, select the customer-managed `Private DNS Zone` and enable the mTLS listener.
2. Upload a PEM CA bundle that contains the client CA and server CA public certificates. If one CA issues both certificates as in this example, upload `client-ca.crt` once.
3. Upload `server.crt` as the Server Certificate and `server.key` as the Server Private Key.
4. Create the ACL user that matches the Client Certificate identity and grant only the required Topic and Consumer Group permissions.

## Step 4: Configure a Kafka client

Convert the Client Certificate and Client Private Key to a PKCS#12 keystore:

```bash theme={null}
openssl pkcs12 -export \
  -in client.crt \
  -inkey client.key \
  -certfile client-ca.crt \
  -out client.p12 \
  -name automq-client \
  -password pass:<keystore-password>
```

Configure the Kafka client:

```properties theme={null}
bootstrap.servers=<mtls-bootstrap-server>
security.protocol=SSL
ssl.keystore.type=PKCS12
ssl.keystore.location=/path/to/client.p12
ssl.keystore.password=<keystore-password>
ssl.key.password=<keystore-password>
```

For an AutoMQ Managed Public DNS Zone, the client normally trusts the public Server Certificate through the operating system or Java runtime. No custom server truststore is required unless your organization requires one.

For a customer-managed Private DNS Zone whose server CA is not already trusted, import the server CA certificate into a client truststore. In the single-CA example above, use `client-ca.crt` as the server CA certificate.

```bash theme={null}
keytool -importcert \
  -alias automq-server-ca \
  -file <server-ca-certificate>.crt \
  -keystore truststore.jks \
  -storepass <truststore-password>
```

Add the truststore settings to the client configuration:

```properties theme={null}
ssl.truststore.type=JKS
ssl.truststore.location=/path/to/truststore.jks
ssl.truststore.password=<truststore-password>
```

## Certificate expiration responsibility

* **AutoMQ Managed Public DNS Zone:** AutoMQ monitors and renews the server certificate. You monitor and rotate the client CA and all client certificates.
* **Customer-managed Private DNS Zone:** You monitor and rotate the server CA, Server Certificate, client CA, and client certificates.

The server exposes `kafka_stream_cert_expiry_timestamp_milliseconds` and `kafka_stream_cert_days_remaining` for the installed server certificate. For collection methods, see [Monitoring and Alerting with Prometheus](/automq-cloud/monitoring-alert/monitoring-alert-via-prometheus). Client certificate monitoring must be implemented in your certificate management process.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.