# Configure TLS with Keystores and Truststores

TLS is a cryptographic protocol that provides communications security for your Mule app. TLS offers
many different ways of exchanging keys for authentication, encrypting data, and guaranteeing message
integrity. This topic describes TLS as supported by Mule and how to configure TLS in Mule apps.

## TLS Compatibility Matrix

TLS compatibility differs by Mule deployment model and TLS version.

<table><colgroup><col> <col> <col> <col></colgroup><thead><tr><th>TLS Version</th><th>On-Premises</th><th>CloudHub</th><th>Anypoint Runtime Fabric</th></tr></thead><tbody><tr><td><p>1.3</p></td><td><p>Supported when running Mule on a JDK that supports TLS 1.3 but <em>not</em> enabled by default</p></td><td><p>Supported for Mule apps hosted in this deployment model</p></td><td><p>Supported and enabled when running on a JDK that supports TLS 1.3</p></td></tr><tr><td><p>1.2</p></td><td colspan="3"><p>Supported and enabled by all deployment models</p></td></tr></tbody></table>

## The tls:context Element

The `tls:context` element is used for all connectors that support TLS. For example, you can
configure TLS in HTTP (server and client), FTPS (client), Email (client) or Sockets (client)
connectors, among others.

> [!NOTE] If a connector supports TLS, Studio shows either:
>
> - A **TLS/SSL** tab on that connector’s Global Elements Properties.
> - A **TLS Configuration** field on the **General** tab of that connector’s Global Element
>   Properties.

## The TLS-Enabled Server and Client

A TLS-enabled server contains a private key and a public certificate:

- The private key never leaves the server.
- The public certificate is exposed through TLS.

TLS-enabled clients verify that they trust the server by validating the public certificate against
their own set of trusted certificates.

To use TLS communications security in Mule 4, import certificates and private keys into a keystore
file. Truststore files are also keystores that by convention include only public certificates of
trusted servers.

While there’s a default Java truststore, there is no default Java keystore in the standard JRE
distribution. Add your own keystore to the TLS context. You likely already have corporate
certificates for your client apps and don’t need to create them. Often, these certificates work with
the JRE truststore, so no setup is required in the TLS context.

A well-known Certificate Authority (CA) can generate certificates, or you can generate a certificate
locally without external approval (self-signed certificate). A truststore contains certificates from
trusted CAs that the client uses to verify a certificate presented by the server.

## Keystores and Truststores

In a Mule configuration, the `tls:trust-store` and `tls:key-store` elements allow you to reference
specific certificates and keys. If you don’t specify a `tls:trust-store`, Mule uses the default Java
truststore, which is maintained by Java and updated automatically when Java is updated. This helps
make sure that certificates from Certificate Authorities (CAs) remain current.

Using a custom Java Trust Store isn’t the standard approach in MuleSoft and can lead to connectivity
issues with the MuleSoft control plane when MuleSoft certificates are renewed.

> [!IMPORTANT] Use the default Java truststore to avoid connectivity issues. If you use a custom
> truststore, you’re responsible for managing and updating it.

Truststore and keystore contents differ depending on whether they are used for clients or servers:

- For servers: the truststore contains certificates of the trusted clients, the keystore contains
  the private and public key of the server.
- For clients: the truststore contains certificates of the trusted servers, the keystore contains
  the private and public key of the client.

Adding both a keystore and a truststore to the configuration implements two-way TLS authentication
also known as mutual authentication.

The keystore contains one or two passwords:

- `password` accesses the entire keystore file.
- `keyPassword` accesses the server’s private key inside the keystore.

## Client Configuration

If the `tls:context` has an empty truststore defined, then the default values of the JVM are used,
which usually include a truststore with certificates for all the major certifying authorities.
Consider the following scenarios:

- When the truststore is defined inline:

<tls:context name> <tls:trust-store /> </tls:context>

- When the truststore is defined with a global element:

<tls:context name="example"> <tls:trust-store /> </tls:context>

If the client requires a certificate from the server that it is trying to connect to, then add the
`tls:trust-store` element. Set `path` to the location within the artifact of the truststore file
that contains the certificates of the trusted servers.

If the server validates certificates from the clients, then the `tls:key-store` element should be
added with `path` set to the location within the artifact of the keystore file that contains the
private/public keys of the client.

See [Configure TLS in Mule 4](#configure-tls-in-mule-4) for configuration instructions.

## Server Configuration

The `tls:context` must contain a `tls:key-store` element to listen for a request using a secure
connection such as HTTPS. Set `path` to the location within the artifact of the keystore file that
contains the private/public keys of the server.

If the server needs to validate certificates from clients, add a `tls:trust-store` element and set
`path` to the location within the artifact of the trust store file that contains the certificates of
the trusted clients.

Mule supports many types of keystores, including:

- `JCEKS`
- `PKCS12`
- `JKS`

Specify your keystore type in the JRE.

To fully configure TLS for a Mule app:

1.  [Generate a keystore and a truststore](#generate-a-keystore), using the Java Keytool from
    Oracle.
2.  [Configure TLS globally for client or server in Mule](#configure-tls-in-mule-4).
3.  [Optional: Specify Protocols and Cipher Suites](#optional-specify-protocols-and-cipher-suites).

## Keystore Generation

The standard JDK distribution doesn’t include a keystore by default, use `keytool` to generate your
keystores and certificates. The keystore you generate contains a private key and a public
certificate. This certificate is self-signed so it isn’t to be trusted by clients unless you share
the public certificate with them.

### Requirements

Use Java 17 to generate your keystores. Using a different JDK version generates an incompatible
keystore that causes an invalid keystore format runtime error when the Mule application tries to
read the keystore.

### Generate a Keystore

Follow these steps to generate a keystore and export a self-signed certificate.

1.  Generate a keystore that exposes your server’s credentials.  
    For example, run one of the following commands:

    keytool -genkey -keyalg RSA -alias <key-alias> -keystore <keystore-name>.jks

    keytool -genkey -alias <key-alias> -keyalg RSA -keystore <keystore-name>.jks -storepass
    <password>

    Replace `<key-alias>` with a unique alias of your choice.

    Replace `<password>` with a password of your choice.

    Replace `<keystore-name>` with the name you want for your keystore.

    Optionally, you can set the encryption algorithm to ECDSA by specifying `-keyalg EC` instead of
    `-keyalg RSA`.

    > [!IMPORTANT] If you don’t specify the encryption algorithm, the tool uses DSA by default which
    > isn’t compatible with TLS 1.2 and causes the SSL handshake to fail when the Mule app receives
    > an HTTPS request.

2.  Respond to the tool’s prompts. The following output shows example responses:

    Enter keystore password: mule123 Re-enter new password: mule123

3.  Respond to prompts to enter other values. Enter your desired values. The following output shows
    example responses:

    What is your first and last name? \[Unknown\]: max What is the name of your organizational unit?
    \[Unknown\]: MuleSoft What is the name of your organization? \[Unknown\]: MuleSoft Inc What is
    the name of your City or Locality? \[Unknown\]: San Francisco What is the name of your State or
    Province? \[Unknown\]: CA What is the two-letter country code for this unit? \[Unknown\]: 01

4.  In response to the following prompt, enter: `yes`.

    Is CN=max, OU=MuleSoft, O=MuleSoft Inc, L=San Francisco, ST=CA, C=01 correct? \[no\]: yes

5.  Respond to the following prompt. For example, use the same password by pressing RETURN.

    Enter key password for <key-alias> (RETURN if same as keystore password):

6.  Enter the following command to export a self-signed certificate authenticating the public key.

    keytool -export -alias <key-alias> -keystore <keystore-name>.jks -file <certificate-name>.cer

    Replace `<key-alias>` with the same value used in the previous steps.  
    Replace `<keystore-name>` with the same value used in the previous steps.  
    Replace `<certificate-name>` with the name you want for your certificate.

7.  Enter the password you set up for the keystore associated with the certificate:

    Enter keystore password: mule123

### Request Signing by a Certification Authority

If you want your certificate signed by a Certification Authority (CA), follow these steps:

1.  Export your certificate in the standard CSR format. To do so you can run this command:

    keytool -certreq -keystore <keystore-name>.jks -alias <key-alias> -file <certificate-name>.csr

    Replace `<key-alias>` with the same value used in the previous steps.  
    Replace `<keystore-name>` with the same value used in the previous steps.  
    Replace `<certificate-name>` with the name you want for your certificate sign request file.

2.  Send the CSR file generated in the previous step to the Certification Authority and follow their
    instructions to obtain their signature.

After you receive the CA’s signature, you can import the signed certificate file through the
following command:

keytool -import -keystore <keystore-name>.jks -alias <cert-alias> -file <signed_certificate_file>

Replace `<cert-alias>` with the new desired value. Make sure the alias you define isn’t linked to
any existing key, or the process fails.  
Replace `<keystore-name>` with the same value used in the previous steps.  
Replace `<signed_certificate_file>` with the name of the signed certificate you received from the
Certification Authority.

1.  Export your certificate in the standard PEM format. First verify the keystore type, then export
    the certificates:

keytool -list -v -keystore <keystore-name>.jks

openssl <keystore-type> -in <keystore-name>.jks -out <pem-name>.key.pem -nocerts -nodes openssl
<keystore-type> -in <keystore-name>.jks -out <pem-name>.crt.pem -nocerts -nodes

Replace `<keystore-type>` with the new desired value in keystore type format, for example PKCS12.  
Replace `<keystore-name>` with the name you want for the keystore.  
Replace `<pem-name>` with the name you want for the PEM file.

## Truststore Generation

The standard JRE distribution includes a default trust store with certificates for several major
certificate authorities (CA’s) which is used by default in the 'tls:trust-store' element, but you
can generate your own if you want greater security or if you use self-signed certificates.

To create a trust store, you can use the Oracle Java keytool.

The client trusts the server if a chain of trust can be established, either directly to the server
(in case its certificate is in the truststore) or through a signing CA whose certificate is present
in the truststore; otherwise, the connection fails. A trust store must be defined when using
self-signed certificates.

## Configure TLS in Mule 4

To enable TLS for Mule apps, configure the `tls:context` element in the Mule XML configuration file
in one of three ways:

- [Edit the XML file directly.](#edit-xml-to-configure-tls)
- [Use Anypoint Studio 7.](#use-anypoint-studio-to-configure-tls)
- [Use Design Center.](#use-design-center-to-configure-tls)

Whichever method you use, we recommend you review the information in
[Edit XML to Configure TLS](#edit-xml-to-configure-tls) to understand how the attributes of
`tls:context` function.

### Edit XML to Configure TLS

The `tls:context` element defines TLS communication in a Mule app. Unless you have a special
requirement, configure TLS globally and then apply it to each specific use, such as listening for or
sending HTTPS requests.

#### Globally Define a TLS Element

The `tls:context` element defines a configuration for TLS, which can be used from both the client
and server sides. The element can be referenced by other configuration objects of other modules or
defined as a nested element of one of them.

Include at least one of the nested elements: key-store and trust-store.

```xml
<tls:context name="customContext">
    <tls:trust-store path="trustStore" password="mulepassword"/>
    <tls:key-store path="clientKeystore" keyPassword="mulepassword" type="pkcs12"
password="mulepassword"/>
 </tls:context>
```

#### Optional Attributes of the `tls-context` Element

Optionally, specify the protocol and cipher suite to enable them:

- `enabledProtocols`: The protocols in the global TLS configuration
- `enabledCipherSuites`: The cipher suites in global TLS configuration

These values are used if there is nothing specified in the global TLS configuration, or if the
values are enabled in a global TLS configuration, as described in
[Optional: Specify Protocols and Cipher Suites](#optional-specify-protocols-and-cipher-suites).

#### Attributes of the `trust-store` Element

The `password` attribute is required if you specify a `path`. Otherwise, the attributes are
optional.

<table><colgroup><col> <col></colgroup><thead><tr><th>Attribute</th><th>Description</th></tr></thead><tbody><tr><td><p><code>path</code></p></td><td><p>The path to the file within the artifact that contains the trust store.</p></td></tr><tr><td><p><code>type</code></p></td><td><p>The type of the trust store. Default is <code>JKS</code>.</p></td></tr><tr><td><p><code>password</code></p></td><td><p>The trust store password. Required if you specify <code>path</code>.</p></td></tr><tr><td><p><code>algorithm</code></p></td><td><p>The algorithm the trust store uses. Default is <code>SunX509</code>.</p></td></tr><tr><td><p><code>insecure</code></p></td><td><p>Boolean that determines whether to validate the trust store. If set to <code>true</code>, no validation occurs. Default is <code>false</code>.</p></td></tr></tbody></table>

> [!IMPORTANT] Setting `insecure` to `true` renders connections vulnerable to attack. Use it only
> for prototyping or testing. Never use it in production environments.

#### Attributes of the `key-store` Element

The attributes other than `path` are optional.

<table><colgroup><col> <col></colgroup><thead><tr><th>Attribute</th><th>Description</th></tr></thead><tbody><tr><td><p><code>path</code></p></td><td><p>The path to the file within the artifact that contains the keystore. Required.</p></td></tr><tr><td><p><code>type</code></p></td><td><p>The type of the keystore. Default is <code>JKS</code>.</p></td></tr><tr><td><p><code>password</code></p></td><td><p>The keystore password.</p></td></tr><tr><td><p><code>keyPassword</code></p></td><td><p>The key manager password, which is the password for the private key inside the keystore.</p></td></tr><tr><td><p><code>algorithm</code></p></td><td><p>The algorithm used in the keystore. Default is <code>SunX509</code>.</p></td></tr></tbody></table>

> [!NOTE] By default, the `path` attribute loads trust and keystore files as classloader resources.
> For on-premises deployments (hybrid or standalone), set the system property
> `mule.tlsStores.filesystemLookup.enable` to `true` to enable file system access.

### Use Design Center to Configure TLS

You can configure TLS for your app in Design Center. For example, to configure TLS in HTTP Listener:

1.  Log into Design Center.
2.  Open the project.
3.  Open HTTP Listener.
4.  In the Configuration tab, click **Edit**.
5.  In the TLS tab, fill in the TLS Configuration fields as described above.
6.  Optionally, fill in the **Enabled Protocols** and **Enabled Cipher Suites** fields as described
    in
    [Optional: Specify Protocols and Cipher Suites](#optional-specify-protocols-and-cipher-suites).

Save your configuration and test.

### Use Anypoint Studio to Configure TLS

You can configure TLS for your app in Anypoint Studio (Studio). For example, to configure TLS in
HTTP Listener:

1.  Open Studio Center.
2.  Open the project.
3.  Open HTTP Listener.
4.  In the General tab, select an existing configuration or create a new one.
5.  In the HTTP Listener config dialog, select the TLS tab.
6.  In the TLS tab, choose the TLS Configuration type **Edit Inline**, and supply the values.
7.  Optionally, fill in the **Enabled Protocols** and **Enabled Cipher Suites** fields in the
    Advanced section as described in
    [Optional: Specify Protocols and Cipher Suites](#optional-specify-protocols-and-cipher-suites).

Save your configuration and test.

## Optional: Specify Protocols and Cipher Suites

When a TLS communication takes place between two systems, a negotiation determines which protocol
and cipher suite are used. Optionally, administrators can specify the protocols and cipher suites to
use, and then app developers can specify which cipher suites and protocols to use in `tls:context`.

> [!NOTE] Protocols and cipher suites must be enabled in Mule runtime and individual apps to be
> used. If the protocols and cipher suites aren’t enabled in both places, the default Java
> environment protocol and cipher suites are used.

To configure protocols and cipher suites in the Mule runtime:

1.  The Mule admin edits the `/conf` directory in `$MULE_HOME`. `$MULE_HOME` points to the directory
    where your Mule installation resides, for example `/opt/mule-4.0`. Select the appropriate file
    where you specify the cipher suites and protocols:
    - `tls-default.conf` allows fine-tuning when Mule isn’t configured to run in Federal Information
      Processing Standards (FIPS) security mode.
    - `tls-fips140-2.conf` allows fine-tuning when Mule is running in FIPS security mode.

      Open the relevant file and comment or uncomment items in the lists to manually configure the
      allowed cipher suites and TLS protocols. If you make no changes to these files, Mule allows
      the configured security manager to select cipher suites and protocols for an app.

2.  The list of protocols and cipher suites that the admin sets in these configuration files can
    then be constrained locally by what the app developer specifies in an individual `tls:context`
    element. The app developer specifies a subset of the configured or default values in the
    `tls:context` element for use by TLS. Configure the protocols and cipher suites in
    `enabledProtocols` and `enabledCipherSuites` in the `tls:context` element.

In the `tls:context` element, you can only reference protocols or cipher suites that are included in
the Mule global TLS configuration file or defaults. In `tls:context`, set `enabledProtocols` and
`enabledCipherSuite` for a Mule app to the value `default`. After these values are set, TLS uses the
following protocols and cipher suites:

- Those configured in your global TLS configuration if it exists
- The defaults provided by your Java environment if a global TLS configuration doesn’t exist

Cipher suite names can be long and reduce the readability of your XML code. To improve readability,
keep these names in an external properties file in your Mule project. You can then reference the
properties. For example:

```xml
<tls:context name="serverTlsContext" enabledCipherSuites="${myCipherSuites}" >
```

## Test after deployment Example

time curl -i -k --cert ./<pem-name>.crt.pem --cert-type PEM --key ./<pem-name>.key.pem
https://<anypoint-address>:<anypoint-port>

Replace `<pem-name>` with the value name defined.  
Replace `<anypoint-address>` with the value name defined by Anypoint Platform.  
Replace `<anypoint-port>` with the value name defined in the Mule application.

## TLS Configuration Examples

You can set up TLS in a Mule XML configuration file for a client or a server.

### Example: Configuring TLS for a Client

This example secures an FTPS client by setting up a truststore:

```xml
<ftps:config name="ftps">
    <ftps:connection username="anonymous" password="password" host="localhost" port="21" workingDir="/dev">
        <tls:context >
            <tls:trust-store path="trustStore" password="mulepassword" />
        </tls:context>
    </ftps:connection>
</ftps:config>
```

### Example: Configuring TLS for a Server

This example secures an HTTP listener by setting up a keystore:

```xml
<http:listener-config name="nestedConfig">
    <http:listener-connection protocol="HTTPS" host="localhost" port="8081">
        <tls:context>
            <tls:key-store path="tls/ssltest-keystore.jks" keyPassword="changeit" password="changeit"/>
        </tls:context>
    </http:listener-connection>
</http:listener-config>
```

### Example: Configuring TLS for Two-Way Authentication

This example sets up two-way authentication (also called mutual authentication), for an HTTP
listener:

```xml
<http:listener-config name="nestedConfig">
    <http:listener-connection protocol="HTTPS" host="localhost" port="8081">
        <tls:context>
            <tls:trust-store path="tls/ssltest-cacerts.jks" password="changeit"/>
            <tls:key-store path="tls/ssltest-keystore.jks" keyPassword="changeit" password="changeit"/>
        </tls:context>
    </http:listener-connection>
</http:listener-config>
```

### Example: Disabling TLS Validations

This example uses the `insecure` property to disable validations for prototyping and development.

> [!IMPORTANT] Don’t use the `insecure` property in production environments.

```xml
<tls:context>
    <tls:trust-store path="tls/ssltest-cacerts.jks" password="changeit" insecure="true"/>
</tls:context>
```

### Example: Adding Additional Cipher Suites and Protocol Restrictions

This example enables a protocol and cipher suite for an app, assuming a Mule admin has either
specified nothing in the global TLS configuration or enabled the cipher suites and protocols being
specified here. Use IANA (Internet Assigned Numbers Authority) naming convention for the cipher
suites. Check the [OpenSSL - IANA mapping](https://testssl.sh/openssl-iana.mapping.html) for
reference.

```xml
<tls:context name="tlsClientContext" enabledProtocols="TLSv1.2" enabledCipherSuites="TLS_DHE_DSS_WITH_AES_128_CBC_SHA256">
    <tls:trust-store path="tls/trustStore" password="mulepassword"/>
</tls:context>
```

## See Also

- [Oracle security](https://docs.oracle.com/javase/8/docs/technotes/tools/)
- [Oracle Java keytool](https://docs.oracle.com/javase/8/docs/technotes/tools/unix/keytool.html)
