# TLS certificates on client side

If your SonarQube server is [#securing-the-server-behind-a-proxy](https://docs.sonarsource.com/sonarqube-server/10.7/setup-and-upgrade/operating-the-server#securing-the-server-behind-a-proxy "mention") and a self-signed certificate then you must add the self-signed certificate to the trusted CA certificates of the SonarScanner.

In addition, if mutual TLS is used then you must define the access to the client certificate at the SonarScanner level.

## Managing the self-signed server certificate <a href="#self-signed-server-certificate" id="self-signed-server-certificate"></a>

### Introduction to server authentication <a href="#introduction-to-server-authentication" id="introduction-to-server-authentication"></a>

During the TLS authentication of the server, the client requests the server certificate from the server and verifies that this certificate is signed by a CA it trusts by checking its truststore. In case a self-signed server certificate is used, it must be added to the truststore of the client. The figure below shows the certificates involved in the authentication of the SonarQube server by the SonarScanner.

![](https://3272878703-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FI10pmJWeVVXYITlQJllp%2Fuploads%2Fgit-blob-cf11bf472fb8a0da9bb30e39d32c0701ac8708f1%2F04e98d3c487a19d47fd905fb5a2c32af4f313093.png?alt=media)

### Adding the self-signed server certificate to the trusted CA certificates <a href="#adding-the-selfsigned-server-certificate-to-the-trusted-ca-certificates" id="adding-the-selfsigned-server-certificate-to-the-trusted-ca-certificates"></a>

<details>

<summary>For all recent scanners, a common SSL configuration</summary>

We are aiming to simplify the SSL configuration for all scanners. This is a work in progress and not all scanners are updated, but we recommend always following those generic steps to be future-proof, and then look at each scanner-specific guidelines on top of it.

All scanners should support a PKCS #12 keystore containing the server or CA certificates to trust (a.k.a. the truststore).

The default location for the truststore is `$SONAR_USER_HOME/ssl/truststore.p12` (default value for SONAR\_USER\_HOME is \~/.sonar). This location can be overridden using the scanner property `sonar.scanner.truststorePath`

The default password for the truststore is "sonar". This password can be overridden using the property `sonar.scanner.truststorePassword`

</details>

<details>

<summary>For SonarScanner for Maven, Gradle, CLI &#x3C; 6.0 , or NPM &#x3C; 4.0</summary>

These scanners are still relying on the Java VM for the SSL configuration.

You can either:

* Insert your certificate in the default JVM truststore (something like `\jre\lib\security\cacerts`). To add the self-signed server certificate to the default truststore, use the JVM tool keytool. The instructions depend on your operating system and you will find many resources online, such as [this one](https://www.ibm.com/docs/en/tnpm/1.4.2?topic=security-import-certificate-jre-keystore) for Linux.

  See also: [troubleshooting](https://docs.sonarsource.com/sonarqube-server/10.7/setup-and-upgrade/install-the-server/troubleshooting "mention")
* Provide a custom Java truststore by using the following properties:
  * `javax.net.ssl.trustStore`: path to the truststore file (pkcs12 format is recommended)
  * `javax.net.ssl.trustStorePassword`: password of the truststore.

{% hint style="warning" %}
These javax.net properties are JVM properties, not scanner properties. They should be passed using the `SONAR_SCANNER_OPTS` environment variable.

For example: `SONAR_SCANNER_OPTS="-Djavax.net.ssl.trustStore=C:/ssl/truststore.p12 -Djavax.net.ssl.trustStorePassword=changeit"`

On Windows, use forward slashes as path separators.
{% endhint %}

</details>

<details>

<summary>For SonarScanner for .NET</summary>

Add the self-signed server certificate to the operating system truststore:

* On Linux and MacOS:
  1. Copy the self-signed server certificate to `/usr/local/share/ca-certificates`
  2. Run `sudo update-ca-certificates`
* On Windows: use [certutil](https://learn.microsoft.com/en-us/windows-server/administration/windows-commands/certutil).\
  Example:

```css-79elbk
certutil -addstore -f "ROOT" <path/to/certificate>
```

When using certstores, you must disable JRE provisioning and use the SonarScanner for CLI logic. Add the self-signed certificate to the Java truststore as explained above.

</details>

<details>

<summary>If running the scanner with Docker</summary>

If you need to configure a self-signed certificate for the scanner to communicate with your SonarQube instance, the preferred way is to mount a folder containing a PKCS #12 file named `truststore.p12` (default password "sonar") under `/opt/sonar-scanner/.sonar/ssl`.

If you have a PEM or DER certificate, you can use OpenSSL or Keytool to generate the PKCS #12 keystore:

* With OpenSSL:

```css-79elbk
openssl pkcs12 -export -caname sonar -out "truststore.p12" -in "server.pem" -passout pass:"<a password>" -nokeys
```

* With Keytool

```css-79elbk
keytool -import -storetype PKCS12 -alias sonar -keystore truststore.p12 -file server.pem -storepass "<a password>"
```

By default, the scanner expects the truststore password to be "sonar", but keytool will not accept such a short password. You’ll need to use a longer one and inform the scanner using the `-Dsonar.scanner.truststorePassword=<a password>` property.

```css-79elbk
docker pull sonarsource/sonar-scanner-cli
docker run \
    --rm \
    -v ${DIR_WITH_TRUSTSTORE_DOT_P12}:/opt/sonar-scanner/.sonar/ssl \
    -v ${YOUR_CACHE_DIR}:/opt/sonar-scanner/.sonar/cache \
    -v ${YOUR_REPO}:/usr/src \
    -e SONAR_HOST_URL="http://${SONARQUBE_URL}" \
    sonarsource/sonar-scanner-cli \
    -Dsonar.scanner.truststorePassword=<a password> // Not needed if the password is "sonar"
```

</details>

<details>

<summary>If running the SonarQube scan GitHub Action</summary>

If you use the [sonarqube-scan-action](https://github.com/SonarSource/sonarqube-scan-action) for your GitHub Action and your SonarQube server has certificates that need to be recognized by the GitHub runner, you’ll need to set the `SONAR_ROOT_CERT` environment variable in GitHub.

To do this, go to *your GitHub repository >* **Settings** > **Secrets and Variables** and add the `SONAR_ROOT_CERT` environment variable in PEM format. You can also add it at the level of your GitHub organization (recommended).

{% hint style="info" %}
Due to a known [GitHub issue](https://github.com/actions/runner/issues/863), if your GitHub Action `v4` and above

* uses `SONAR_ROOT_CERT`
* and is executed in a containerized environment, for example when the job running the action declares `container: <docker-image-name>`

you need to explicitly set the `SONAR_USER_HOME` environment variable to be the `"$HOME/.sonar"`.

You can do that by adding the following step before executing the action:

```css-79elbk
# Workaround for https://github.com/actions/runner/issues/863

- name: Workaround for containerized environments

  run: echo "SONAR_USER_HOME=$HOME/.sonar" >> $GITHUB_ENV

- name: Run sonar analysis

  uses: SonarSource/sonarqube-scan-action@<action version>

  ...
```

{% endhint %}

</details>

<details>

<summary>If using Azure DevOps</summary>

If you have integrated SonarQube with Azure DevOps, define the following environment variable to add the server self-signed certificate:

* Key: NODE\_EXTRA\_CA\_CERTS
* Value: path to the certificate

</details>

## Managing the client certificates <a href="#mutual-tls" id="mutual-tls"></a>

### Introduction to client authentication <a href="#introduction-to-client-authentication" id="introduction-to-client-authentication"></a>

If mutual TLS is used then both the client and the server authenticate the other party. During the TLS authentication of the client, the client must provide its certificate with the corresponding CA certificate chain (intermediate and root CA certificates) to the server. The client manages its certificates in its own keystore. The figure below shows the certificates involved in the TLS authentication of the SonarScanner by the SonarQube Server.

![](https://3272878703-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FI10pmJWeVVXYITlQJllp%2Fuploads%2Fgit-blob-f36a72ea9dc0e52af7fbf29bdb5000b23635d04d%2F3374c9d5df12b5eb3aaf5f5aad133c8b8d56a2e7.png?alt=media)

### Defining the access to the client certificates <a href="#defining-the-access-to-the-client-certificates" id="defining-the-access-to-the-client-certificates"></a>

<details>

<summary>For SonarScanner for Maven, Gradle, CLI, or NPM</summary>

Store the client certificate and CA certificate chain in a keystore file and define the access to this file through the following properties:

* `javax.net.ssl.keyStore` or (for SonarScanner CLI from version 6.0 and SonarScanner for NPM from version 4.0) `sonar.scanner.keystorePath`: path to the keystore file.
* `javax.net.ssl.keyStorePassword` or (for SonarScanner CLI from version 6.0 and SonarScanner for NPM from version 4.0) `sonar.scanner.keystorePassword`: password of the keystore file.

</details>

<details>

<summary>For SonarScanner for .NET</summary>

1. Store the client certificate and CA certificate chain in a keystore file and define the access to this file through the following properties:
   * `sonar.clientcert.path` : path to the keystore file, must be set in the begin step.
   * `sonar.clientcert.password:` password of the keystore file, must be set in both the begin and end steps.
2. In addition, set the following options before the end step (for the SonarScanner CLI invocation):
   * `javax.net.ssl.keyStore`: same value as `sonar.clientcert.path`
   * `javax.net.ssl.keyStorePassword`: same value as `sonar.clientcert.password`

</details>
