<a id="controlcenter-security-ssl"></a>

# Configure TLS for Control Center on Confluent Platform

You can configure TLS for Control Center so web access is secured through HTTPS.
In addition, since the Control Center acts as a proxy server for other components,
you can configure TLS for Control Center to secure its
communication with other secured Confluent Platform components.

<a id="controlcenter-ui-https"></a>

## Configure TLS for Control Center as a server

HTTPS can be configured for web access to Confluent Control Center. To enable HTTPS, you must first add
an HTTPS listener in the Control Center properties file using
the `confluent.controlcenter.rest.listeners` parameter. You must also set the
appropriate [TLS configuration options](../installation/configuration.md#https-settings). If you haven’t already,
you should [create TLS keys and certificates](/platform/current/security/security_tutorial.html#generating-keys-certs).

An example of the necessary additions to the appropriate [Control Center Configuration Examples for Confluent Platform](../installation/properties.md#c3-properties-files) is shown below:

```bash
confluent.controlcenter.rest.listeners=<listener-url>
confluent.controlcenter.rest.ssl.keystore.location=<keystore-location>
confluent.controlcenter.rest.ssl.keystore.password=<password>
confluent.controlcenter.rest.ssl.key.password=<key-password>
confluent.controlcenter.rest.ssl.truststore.location=<truststore-location>
confluent.controlcenter.rest.ssl.truststore.password=<password>
```

```bash
curl -vvv -X GET --tlsv1.2 https://localhost:9022
#for cases when using a self-signed certificate
curl -vvv -X GET --tlsv1.2 --cacert scripts/security/snakeoil-ca-1.crt https://localhost:9022
```

#### SEE ALSO
For an example that shows how to set Docker environment variables for Confluent Platform running in ZooKeeper mode, see the [Confluent Platform demo](/platform/current/tutorials/cp-demo/overview.html).
Refer to the demo’s [docker-compose.yml file](https://github.com/confluentinc/cp-demo/tree/latest/docker-compose.yml) for a configuration reference.

<a id="control-center-ssl-c3"></a>

## Configure TLS for Kafka Streams

Control Center needs to know when security is enabled for any other component. Internally, Control Center uses Kafka Streams as a state store, so with a secured broker, Kafka Streams
also need to be secured.

The following changes need to be made to the `control-center.properties` file as appropriate for the
environment:

```bash
confluent.controlcenter.streams.security.protocol=SSL
confluent.controlcenter.streams.ssl.keystore.location=<keystore-location>
confluent.controlcenter.streams.ssl.keystore.password=<password>
confluent.controlcenter.streams.ssl.key.password=<password>
confluent.controlcenter.streams.ssl.truststore.location=<truststore-location>
confluent.controlcenter.streams.ssl.truststore.password=<password>
```

<a id="control-center-ssl-proxy"></a>

## Configure TLS for Control Center as a proxy server

Confluent Control Center normally communicates with Confluent Platform components using the HTTP protocol.
You can enable HTTPS between the two components by securing them with TLS.

There are a number of ways to configure TLS for communication between Control Center
and other Confluent Platform components.

- Stores for each secured component: [Schema Registry](#controlcenter-ssl-sr),
  [Connect](#controlcenter-ssl-connect), and [ksqlDB](#controlcenter-ssl-ksqldb).
- [A single proxy server store](#c3-proxy-truststore)
- [Server store](#c3-server-truststore) (not recommended)

#### NOTE
Regardless how you configure stores for Confluent Control Center, the keystores are merged
into a single composite keystore and checked in the following order:

- Server store (`confluent.controlcenter.rest.ssl.*`)
- Schema Registry store
- Connect store
- ksqlDB store
- Proxy server store (`confluent.controlcenter.rest.proxy.ssl.*`)

For details on how Control Center picks a certificate from this composite
keystore, see [Certificate selection for outbound TLS connections](#c3-outbound-cert-selection).

When you configure each component separately, each component requires a specific configuration
to be set by its prefix. For example, for Schema Registry use the prefix: `confluent.controlcenter.schema.registry`.

The TLS truststore location is set as follows:

```bash
confluent.controlcenter.schema.registry.schema.registry.ssl.truststore.location=<value>
```

Each component
should be configured in their respective configuration files to secure Control Center end-to-end.

Not all configuration settings may be required;
consult the configuration reference for each component you are configuring.

<a id="controlcenter-ssl-sr"></a>

### Configure TLS proxy server access to Schema Registry

When Confluent Control Center connects to Schema Registry and Schema Registry has TLS enabled:

- Schema Registry communicates with Kafka over the Kafka protocol, which is secured with TLS.
- Control Center communicates with Kafka over the Kafka protocol, which is secured with TLS.
- Control Center communicates with Schema Registry with the HTTPS protocol,
  which is secured with TLS.

Essentially, Control Center functions as a proxy server to Schema Registry. To secure Control Center
with HTTPS, configure Schema Registry to allow HTTPS as described in [Configuring the REST API for HTTP or HTTPS](/platform/current/schema-registry/security/index.html#schema-registry-http-https).

In addition, Control Center should include a trusted certificate to its truststore to
connect to Schema Registry over HTTPS as described in [Additional configurations for HTTPS](/platform/current/schema-registry/security/index.html#sr-https-additional).

Be sure to prefix the Control Center configuration attributes in `control-center.properties`
with `confluent.controlcenter.` For example:

```bash
confluent.controlcenter.schema.registry.schema.registry.ssl.truststore.location=<truststore-location>
confluent.controlcenter.schema.registry.schema.registry.ssl.truststore.password=<password>
confluent.controlcenter.schema.registry.schema.registry.ssl.keystore.location=<keystore-location>
confluent.controlcenter.schema.registry.schema.registry.ssl.keystore.password=<password>
confluent.controlcenter.schema.registry.schema.registry.ssl.key.password=<password>
```

<a id="controlcenter-ssl-connect"></a>

<a id="controlcenter-connect-using-https"></a>

### Configure TLS proxy server access to Connect

Confluent Control Center normally communicates with Connect using the HTTP protocol.
You can enable HTTPS between the two components by securing them with SSL/TLS.
Make sure that Control Center has a certificate in its
truststore that is trusted by Connect to communicate over HTTPS.
Set the following properties to enable Control Center for HTTPS communication with Connect:

```bash
confluent.controlcenter.connect.connect.ssl.truststore.location=<truststore-location>
confluent.controlcenter.connect.connect.ssl.truststore.password=<password>
confluent.controlcenter.connect.connect.ssl.keystore.location=<keystore-location>
confluent.controlcenter.connect.connect.ssl.keystore.password=<password>
confluent.controlcenter.connect.connect.ssl.key.password=<password>
```

For additional information about accessing Connect over HTTPS, refer to [Configuring the Connect REST API for HTTP or HTTPS](/platform/current/connect/security.html#connect-rest-api-http).

<a id="controlcenter-ssl-ksqldb"></a>

### Configure TLS proxy server access to ksqlDB

Confluent Control Center normally communicates with ksqlDB using the HTTP protocol. You can enable HTTPS between the
two components by securing them with TLS. To configure Control Center to connect to ksqlDB over HTTPS, refer
to [Configure ksqlDB for HTTPS](/platform/current/ksqldb/operate-and-deploy/installation/security.html#ksqldb-installation-security-configure-listener-for-ssl-encryption).

Ensure that Control Center has a certificate in its truststore that is trusted by
ksqlDB to communicate over HTTPS. The following parameters should be included in the `control-center.properties` file:

```bash
confluent.controlcenter.ksql.ksql.ssl.truststore.location=<truststore-location>
confluent.controlcenter.ksql.ksql.ssl.truststore.password=<password>
confluent.controlcenter.ksql.ksql.ssl.keystore.location=<keystore-location>
confluent.controlcenter.ksql.ksql.ssl.keystore.password=<password>
confluent.controlcenter.ksql.ksql.ssl.key.password=<password>
```

<a id="c3-proxy-truststore"></a>

### Configure a single proxy server store

As an alternative to configuring Control Center for each component,
you can configure a single proxy server store.

To configure a proxy store, set the following properties:

```bash
confluent.controlcenter.rest.proxy.ssl.truststore.location=<truststore-location>
confluent.controlcenter.rest.proxy.ssl.truststore.password=<password>
confluent.controlcenter.rest.proxy.ssl.keystore.location=<keystore-location>
confluent.controlcenter.rest.proxy.ssl.keystore.password=<password>
confluent.controlcenter.rest.proxy.ssl.key.password=<password>
```

<a id="c3-server-truststore"></a>

### Use the server store

You can use the server store for proxy server TLS, although
this is not recommended.

If using the server TLS, Control Center uses the locations/passwords specified
by [Configure TLS for Control Center as a server](#controlcenter-ui-https).

<a id="c3-outbound-cert-selection"></a>

## Certificate selection for outbound TLS connections

When Control Center opens an outbound TLS connection to a Confluent Platform component, it must
choose which client certificate to present. When more than one keystore is
configured, the keystore that Control Center uses depends on which of three
independent outbound paths the connection takes. Understanding these paths
helps you avoid presenting the wrong certificate, which causes the remote
service to reject the connection.

#### NOTE
In the property names below, the `confluent.controlcenter.` prefix is
omitted for readability. For example, `rest.ssl.*` refers to
`confluent.controlcenter.rest.ssl.*`.

### Outbound TLS connection paths

Control Center uses three independent outbound TLS paths:

- **Composite keystore**: Used by every service health check and by
  Control Center server-side TLS. The composite keystore merges the configured
  keystores in this fixed order: `rest.ssl.*`, then
  `schema.registry.schema.registry.ssl.*`, `connect.connect.ssl.*`,
  `ksql.ksql.ssl.*`, and `rest.proxy.ssl.*`.
- **Single** `rest.ssl.*`: Used by all UI proxy traffic to Schema Registry,
  Connect, ksqlDB, REST Proxy, Metadata Service (MDS), and CMF.
  Per-service keystore configurations are ignored on this path.
- **Single per-service**: Used by the Prometheus query API and the
  Alertmanager API after a health check marks the endpoint as up. This path
  reads only `prometheus.ssl.*` or `alertmanager.ssl.*`. The frontend
  (`rest.ssl.*`) keystore is not used.

### Composite keystore selection rule

At handshake time, Control Center walks the merged composite keystore in the
order listed above and stops at the first keystore whose certificate is both:

- Signed by a certificate authority (CA) that the remote service accepts, and
- A match for the requested key type.

This selection rule has two important limitations:

- Control Center **does not check Extended Key Usage (EKU)** when selecting the
  certificate. A certificate stamped only with `serverAuth` can be selected
  for a connection that requires `clientAuth`.
- There is **no fallback**. If the selected certificate is then rejected by
  the remote service for any reason, the handshake fails. Control Center does
  not try the next keystore.

### Keystore used by each integration

The following table maps each outbound integration to the keystore that
Control Center uses for its health check, UI proxy traffic, and native API
query.

| Integration     | Health check                                                            | UI proxy traffic   | Native API query     |
|-----------------|-------------------------------------------------------------------------|--------------------|----------------------|
| Kafka           | Uses the Kafka protocol (`streams.ssl.*`), not an HTTP certificate path | Not applicable     | Not applicable       |
| Schema Registry | Composite keystore                                                      | `rest.ssl.*`       | Not applicable       |
| Connect         | Composite keystore                                                      | `rest.ssl.*`       | Not applicable       |
| ksqlDB          | Composite keystore                                                      | `rest.ssl.*`       | Not applicable       |
| REST Proxy      | Composite keystore                                                      | `rest.ssl.*`       | Not applicable       |
| MDS             | Composite keystore                                                      | `rest.ssl.*`       | Not applicable       |
| Prometheus      | Composite keystore                                                      | Not applicable     | `prometheus.ssl.*`   |
| Alertmanager    | Composite keystore                                                      | Not applicable     | `alertmanager.ssl.*` |
| CMF             | Composite keystore                                                      | `rest.ssl.*`       | Not applicable       |

### Recommended TLS configuration

For most deployments, configure a single certificate stamped with both the
`serverAuth` and `clientAuth` EKUs at `rest.ssl.*` and skip the
per-service keystores. A single dual-purpose certificate avoids the composite
selection conflicts described above because the same certificate is valid on
every outbound path.

If you must split certificate roles across integrations, use one of the
following approaches:

- **Use distinct CAs per integration.** When each integration trusts a
  different CA, the composite picker naturally falls through to the keystore
  whose certificate the remote service accepts.
- **Pin a specific certificate alias.** On the composite path, use the
  `alias.name` setting to pin the certificate that Control Center presents for
  a given integration:
  - `schema.registry.schema.registry.alias.name`
  - `connect.connect.alias.name`
  - `ksql.ksql.alias.name`
  - `rest.proxy.alias.name`

#### IMPORTANT
In Control Center 2.5.x and earlier, the `alias.name` settings for
Prometheus, Alertmanager, and CMF
(`confluent.controlcenter.prometheus.alias.name`,
`confluent.controlcenter.alertmanager.alias.name`, and
`confluent.controlcenter.cmf.alias.name`) have no effect, so you cannot
pin the certificate for these integrations. Instead, rely on a dual-purpose
certificate or distinct CAs to get the correct certificate selected.

In Control Center 2.6.0 and later, these settings work as expected and let you
pin the certificate that Control Center presents for each of these
integrations.

### Troubleshoot certificate selection

Use the following symptoms to identify a certificate-selection problem:

| Symptom                                                                                    | Likely cause                                                                                                                                                            |
|--------------------------------------------------------------------------------------------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| Dashboards stay empty and Prometheus is marked down.                                       | Control Center presented the frontend (`rest.ssl.*`) certificate<br/>instead of the Prometheus certificate, and Prometheus rejected it.                                 |
| `presented certificate specifies an incompatible key usage` in the<br/>Control Center log. | The composite picker selected a certificate without the required EKU<br/>(for example, a `serverAuth`-only certificate on a connection that<br/>requires `clientAuth`). |
| `no suitable certificate` in the Control Center log.                                       | No configured keystore contains a certificate signed by a CA that the<br/>remote service accepts.                                                                       |

To resolve these issues, apply the recommended TLS configuration: use a
dual-purpose certificate at `rest.ssl.*`, configure distinct CAs per
integration, or pin a certificate alias on the composite path.

## Related content

[Use TLS Authentication in Confluent Platform](/platform/current/security/authentication/mutual-tls/overview.html#kafka-ssl-authentication)
