Chapter 1. Management of security keys and certificates with the TLS Registry The TLS Registry is a Quarkus extension that centralizes TLS configuration, making it easier to manage and maintain secure connections across your application. When defining TLS configurations in a single centralized location, you can use the TLS Registry to reference these configurations from multiple components within the application, which ensures consistency and reduces the potential for configuration errors. The TLS Registry consolidates settings and supports multiple named configurations. Therefore, you can tailor TLS settings for different application parts. This flexibility is particularly useful when different components require distinct security configurations. The TLS Registry extension is automatically included in your project when you use compatible extensions, such as Quarkus REST, gRPC . As a result, applications that use the TLS Registry can be ready to handle secure communications out of the box. TLS Registry also provides automatic certificate reloading and compatibility with various keystore formats, such as PKCS12, PEM, and JKS. 1.1. Using the TLS registry To configure a TLS connection, including key and truststores, use the quarkus.tls.* properties. These properties are required for: Setting up the default TLS configuration, defined directly under quarkus.tls.* Creating separate, named configurations by using quarkus.tls.<name>.* . By specifying the quarkus.tls.<name>.* properties, you can adapt the TLS settings for a specific component. 1.1.1. Configuring HTTPS for a HTTP server To ensure secure client-server communication, the client is often required to verify the server's authenticity. The server must use a keystore that contains its certificate and private key The client needs to be configured with a truststore to validate the server's certificate During the TLS handshake, the server presents its certificate, which the client then validates. This prevents man-in-the-middle attacks and secures data transmission. The following sections guide you through setting up HTTPS by using PEM or PKCS12 keystore types. In addition, they provide information on how to use named configurations to specify and manage multiple TLS setups at once, which makes it possible for you to define distinct settings for each. Use one of the following configuration examples based on your keystore type: By using PEM files: quarkus.tls.key-store.pem.0.cert=server.crt quarkus.tls.key-store.pem.0.key=server.key quarkus.http.insecure-requests=disabled # Reject HTTP requests By using a p12 (PKCS12) keystore: quarkus.tls.key-store.p12.path=server-keystore.p12 quarkus.tls.key-store.p12.password=secret quarkus.http.insecure-requests=disabled # Reject HTTP requests Distinguishing multiple configurations with names: quarkus.tls.https.key-store.p12.path=server-keystore.p12 quarkus.tls.https.key-store.p12.password=secret quarkus.http.insecure-requests=disabled quarkus.http.tls-configuration-name=https 1.1.2. Configuring HTTPS for a client The following example configures a gRPC client named "hello" to use HTTPS with a truststore from the default TLS configuration: quarkus.tls.trust-store.jks.path=grpc-client-truststore.jks quarkus.tls.trust-store.jks.password=password quarkus.grpc.clients.hello.plain-text=false quarkus.grpc.clients.hello.use-quarkus-grpc-client=true 1.1.3. Configuring mTLS To set up mutual TLS (mTLS) in your Red Hat build of Quarkus application, configure the server and the client by creating and managing both a keystore and a truststore for each: Server keystore : Contains the server's certificate and private key. Client keystore : Contains the client's certificate and private key. Server truststore : Stores the client's certificate for authenticating the client. Client truststore : Stores the server's certificate for authenticating the server. An example configuration for specifying keystores and truststores: quarkus.tls.my-server.key-store.p12.path=target/certs/grpc-keystore.p12 quarkus.tls.my-server.key-store.p12.password=password quarkus.tls.my-server.trust-store.p12.path=target/certs/grpc-server-truststore.p12 quarkus.tls.my-server.trust-store.p12.password=password quarkus.tls.my-client.trust-store.p12.path=target/certs/grpc-client-truststore.p12 quarkus.tls.my-client.trust-store.p12.password=password quarkus.tls.my-client.key-store.p12.path=target/certs/grpc-client-keystore.p12 quarkus.tls.my-client.key-store.p12.password=password quarkus.grpc.clients.hello.plain-text=false quarkus.grpc.clients.hello.tls-configuration-name=my-client quarkus.grpc.clients.hello.use-quarkus-grpc-client=true quarkus.http.ssl.client-auth=REQUIRED # Enable mTLS quarkus.http.insecure-requests=disabled quarkus.http.tls-configuration-name=my-server quarkus.grpc.server.use-separate-server=false quarkus.grpc.server.plain-text=false This configuration enables mTLS by ensuring that both the server and client validate each other's certificates, which provides an additional layer of security. 1.2. Referencing a TLS configuration To reference an example named configuration that you created by using the quarkus.tls.<name>.* properties as explained in Using the TLS registry , use the tls-configuration-name property as shown in the following examples: Example configuration for the core HTTP server: # Reference the named configuration quarkus.http.tls-configuration-name=MY_TLS_CONFIGURATION Example configuration for a gRPC client: quarkus.grpc.clients.hello.tls-configuration-name=MY_TLS_CONFIGURATION 1.3. Configuring TLS TLS configuration primarily involves managing keystores and truststores. The specific setup depends on the format used, such as PEM, P12, or JKS. The following sections outline the various properties available for configuring TLS. 1.3.1. Key stores Key stores are used to store private keys and the certificates. They are mainly used on the server side but can also be used on the client side when mTLS is used. 1.3.1.1. PEM keystores Privacy Enhanced Mail (PEM) keystores are composed of a list of file pairs: The certificate file - a .crt or .pem file The private key file - often a .key file To configure a PEM keystore: quarkus.tls.key-store.pem.a.cert=server.crt quarkus.tls.key-store.pem.a.key=server.key quarkus.tls.key-store.pem.b.cert=my-second-cert.crt quarkus.tls.key-store.pem.b.key=my-second-key.key In most cases, you only need a single pair consisting of a certificate and a private key. Even if the certificate is part of a certificate chain, it includes only one private key that corresponds to the end-entity certificate. When multiple pairs are configured, the selection of one of the configured pairs of certificates and private keys is based on Server Name Indication (SNI). The client sends the name of the server to which the client is attempting to connect, and the server selects the appropriate pair of certificates and private keys. To use this feature, ensure that SNI is enabled on both the client and server. Important When configuring multiple key pairs or certificate pairs, the server executes the configured pairs in a lexicographical order of their names by default, as demonstrated with store.pem.a and store.pem.b in the example. The pair with the lowest lexicographical order is executed first. To change this, you can define the order by using the quarkus.tls.key-store.pem.order property. For example, quarkus.tls.key-store.pem.order=b,c,a . This setting is important when using SNI, because it uses the first specified pair as the default. 1.3.1.2. PKCS12 keystores PKCS12 keystores are single files that contain the certificate and the private key. To configure a PKCS12 keystore: quarkus.tls.key-store.p12.path=server-keystore.p12 quarkus.tls.key-store.p12.password=secret .p12 files are password-protected, so you need to provide the password to open the keystore. These files can include more than one certificate and private key. If this is the case, take either of the following actions: Provide and configure the alias of the certificate and the private key you want to use: quarkus.tls.key-store.p12.path=server-keystore.p12 quarkus.tls.key-store.p12.password=secret quarkus.tls.key-store.p12.alias=my-alias quarkus.tls.key-store.p12.alias-password=my-alias-password Alternatively, use SNI to select the appropriate certificate and private key. Note that all keys must use the same password. 1.3.1.3. JKS keystores JKS keystores are single files that contain the certificate and the private key for the server or client, used to authenticate and establish secure communications in TLS/SSL connections. Important JKS is an old but still widely used Java-specific format. However, to work with this format, you must use specific, and nowadays also deprecated, Java tooling. Thus, its use with your Red Hat build of Quarkus application is not recommended. Additionally, OpenShift cert-manager or Let's Encrypt does not typically provide JKS and remains PEM-only. To configure a JKS keystore: quarkus.tls.key-store.jks.path=server-keystore.jks quarkus.tls.key-store.jks.password=secret .jks files are password-protected, so you need to provide the password to open the keystore. Also, they can include more than one certificate and private key. If this is the case: Provide and configure the alias of the certificate and the private key you want to use: quarkus.tls.key-store.jks.path=server-keystore.jks quarkus.tls.key-store.jks.password=secret quarkus.tls.key-store.jks.alias=my-alias quarkus.tls.key-store.jks.alias-password=my-alias-password Alternatively, use SNI to select the appropriate certificate and private key. Note that all keys must use the same password. 1.3.1.4. SNI Server Name Indication (SNI) is a TLS extension that makes it possible for a client to specify the host name to which it attempts to connect during the TLS handshake. SNI enables a server to present different TLS certificates for multiple domains on a single IP address, which facilitates secure communication for virtual hosting scenarios. To enable SNI: quarkus.tls.key-store.sni=true # Disabled by default With SNI enabled, the client indicates the server name during the TLS handshake, which allows the server to select the appropriate certificate: When configuring the keystore with PEM files, multiple certificate (CRT) and key files must be provided. CRT is a common file extension for X.509 certificate files, typically in PEM (Privacy-Enhanced Mail) format. These files contain the public certificate. When configuring the keystore with a JKS or P12 file, the server selects the appropriate certificate based on the SNI host name provided by the client during the TLS handshake. The server matches the SNI hostname with the common name (CN) or subject alternative names (SAN) configured in the certificates stored in the keystore. All keystore and alias passwords must be identical. 1.3.1.5. Credential providers You can use a credential provider instead of passing the keystore password and alias password in the configuration. A credential provider offers a way to retrieve the keystore and alias password. Note that the credential provider is only used if the password or alias password is not set in the configuration. To configure a credential provider: # The name of the credential bucket in the credentials provider quarkus.tls.key-store.credentials-provider.name=my-credentials # The name of the bean providing the credential provider (optional, using the default credential provider if not set) quarkus.tls.key-store.credentials-provider.bean-name=my-credentials-provider # The key used to retrieve the keystore password, `password` by default quarkus.tls.key-store.credentials-provider.password-key=password # The key used to retrieve the alias password, `alias-password` by default quarkus.tls.key-store.credentials-provider.alias-password-key=alias-password Important The credential provider can only be used with PKCS12 and JKS keystores. 1.3.2. Trust stores Trust stores are used to store the certificates of the trusted parties. In regular TLS, the client uses a truststore to authenticate the server. With mutual TLS (mTLS), both the server and the client use truststores to authenticate each other. 1.3.2.1. PEM truststores PEM truststores are composed of a list of .crt or .pem files. Each of them contains a certificate. To configure a PEM truststore: quarkus.tls.trust-store.pem.certs=ca.crt,ca2.pem 1.3.2.2. PKCS12 truststores PKCS12 truststores are a single file containing the certificates. You can use the alias to select the appropriate certificate when multiple certificates are included. To configure a PKCS12 truststore: quarkus.tls.trust-store.p12.path=client-truststore.p12 quarkus.tls.trust-store.p12.password=password quarkus.tls.trust-store.p12.alias=my-alias .p12 files are password-protected, so you need to provide the password to open the truststore. However, unlike keystores, the alias does not require a password because it contains a public certificate, not a private key. 1.3.2.3. JKS truststores JKS truststores are single files that contain multiple certificates. You can use the alias to select the appropriate certificate when multiple certificates are present. However, avoid using the JKS format, because it is less secure than PKCS12. To configure a JKS truststore: quarkus.tls.trust-store.jks.path=client-truststore.jks quarkus.tls.trust-store.jks.password=password quarkus.tls.trust-store.jks.alias=my-alias .jks files are password-protected, so you need to provide the password to open the truststore. However, unlike keystores, the alias does not require a password because it contains a public certificate, not a private key. 1.3.2.4. Credential providers Instead of passing the truststore password in the configuration, you can use a credential provider. A credential provider allows you to retrieve passwords and other credentials. Note that the credential provider is used only if the password is not set in the configuration. To configure a credential provider: # The name of the credential bucket in the credentials provider quarkus.tls.trust-store.credentials-provider.name=my-credentials # The name of the bean providing the credential provider (optional, using the default credential provider if not set) quarkus.tls.trust-store.credentials-provider.bean-name=my-credentials-provider # The key used to retrieve the truststore password, `password` by default quarkus.tls.trust-store.credentials-provider.password-key=password Important The credential provider can only be used with PKCS12 and JKS truststores. 1.3.3. Other properties While keystores and truststores are the most important properties, there are other properties you can use to configure TLS. Note While the following examples use the default configuration, you can use the named configuration by prefixing the properties with the configuration's name. 1.3.3.1. Cipher suites Cipher suites are a list of ciphers that you can use during the TLS handshake. You can configure an ordered list of enabled cipher suites. If not configured, a reasonable default is selected from the built-in ciphers. However, when specified, your configuration precedes the default suite defined by the SSL engine in use. To configure the cipher suites: quarkus.tls.cipher-suites=TLS_AES_128_GCM_SHA256,TLS_AES_256_GCM_SHA384 1.3.3.2. TLS protocol versions The TLS protocol versions are the list of protocols that can be used during the TLS handshake. Enabled TLS protocol versions are specified as an ordered list separated by commas. The relevant configuration property is quarkus.tls.protocols (or quarkus.tls.<name>.protocols for named TLS configurations). It defaults to TLSv1.3, TLSv1.2 if not configured. The available options are TLSv1 , TLSv1.1 , TLSv1.2 , and TLSv1.3 . For example, to only enable TLSv1.3 : quarkus.tls.protocols=TLSv1.3 1.3.3.3. Handshake timeout When a TLS connection is established, the handshake phase is the first step. During this phase, the client and server exchange information to establish the connection, which typically includes the cipher suite, the TLS protocol version, and the certification validation. To configure the timeout for the handshake phase: quarkus.tls.handshake-timeout=10S # Default. 1.3.3.4. ALPN Application-Layer Protocol Negotiation (ALPN) is a TLS extension that allows the client and server to negotiate which protocol they will use for communication during the TLS handshake. ALPN enables more efficient communication by allowing the client to indicate its preferred application protocol to the server before establishing the TLS connection. This helps in scenarios like HTTP/2, where multiple protocols might be available, allowing for faster protocol selection. ALPN is enabled by default. To disable it: quarkus.tls.alpn=false Warning Disabling ALPN is not recommended for non-experts, as it can lead to performance degradation, protocol negotiation issues, and unexpected behavior, particularly with protocols like HTTP/2. However, disabling ALPN can be useful for diagnosing native inconsistencies or testing performance in specific edge cases where protocol negotiation causes conflicts. 1.3.3.5. Certificate Revocation List (CRL) A Certificate Revocation List (CRL) is a list of certificates that the issuing Certificate Authority (CA) revoked before their scheduled expiration date. When a certificate is compromised, no longer needed, or deemed invalid, the CA adds it to the CRL to inform relying parties not to trust it anymore. You can configure the CRL with the list of certificate files you no longer trust by using the DER or PKCS#7 (P7B) formats. For the DER format, pass DER-encoded CRLs. For the PKCS#7 format, pass the SignedData object, where the only significant field is crls . To configure the CRL: quarkus.tls.certificate-revocation-list=ca.crl, ca2.crl 1.3.3.6. Trusting all certificates and hostname verification You can configure your TLS connection to trust all certificates and disable the hostname verification. Note that these are two different processes: Trusting all certificates ignores the certificate validation, so all certificates are trusted. This method is useful for testing with self-signed certificates, but it should not be used in production. Hostname verification is the process of verifying the server's identity. It is useful to prevent man-in-the-middle attacks and often defaults to HTTPS or LDAPS . Important These two properties should not be used in production. To trust all certificates: quarkus.tls.trust-all=true To disable hostname verification: quarkus.tls.hostname-verification-algorithm=NONE 1.3.4. Configuration reference The following table lists the supported properties: Configuration property fixed at build time - All other configuration properties are overridable at runtime Configuration property Type Default quarkus.tls.lets-encrypt.enabled Set to true to enable let's encrypt support. Environment variable: QUARKUS_TLS_LETS_ENCRYPT_ENABLED boolean false quarkus.tls.key-store.pem.order The order of the key/cert files, based on the names in the keyCerts map. By default, Quarkus sorts the key using a lexicographical order. This property allows you to specify the order of the key/cert files. Environment variable: QUARKUS_TLS_KEY_STORE_PEM_ORDER list of string quarkus.tls.key-store.p12.path Path to the key store file (P12 / PFX format). Environment variable: QUARKUS_TLS_KEY_STORE_P12_PATH path required quarkus.tls.key-store.p12.password Password of the key store. When not set, the password must be retrieved from the credential provider. Environment variable: QUARKUS_TLS_KEY_STORE_P12_PASSWORD string quarkus.tls.key-store.p12.alias Alias of the private key and certificate in the key store. Environment variable: QUARKUS_TLS_KEY_STORE_P12_ALIAS string quarkus.tls.key-store.p12.alias-password Password of the alias in the key store. If not set, the password will be retrieved from the credential provider. Environment variable: QUARKUS_TLS_KEY_STORE_P12_ALIAS_PASSWORD string quarkus.tls.key-store.p12.provider Provider of the key store. Environment variable: QUARKUS_TLS_KEY_STORE_P12_PROVIDER string quarkus.tls.key-store.jks.path Path to the keystore file (JKS format). Environment variable: QUARKUS_TLS_KEY_STORE_JKS_PATH path required quarkus.tls.key-store.jks.password Password of the key store. When not set, the password must be retrieved from the credential provider. Environment variable: QUARKUS_TLS_KEY_STORE_JKS_PASSWORD string quarkus.tls.key-store.jks.alias Alias of the private key and certificate in the key store. Environment variable: QUARKUS_TLS_KEY_STORE_JKS_ALIAS string quarkus.tls.key-store.jks.alias-password Password of the alias in the key store. When not set, the password may be retrieved from the credential provider. Environment variable: QUARKUS_TLS_KEY_STORE_JKS_ALIAS_PASSWORD string quarkus.tls.key-store.jks.provider Provider of the key store. Environment variable: QUARKUS_TLS_KEY_STORE_JKS_PROVIDER string quarkus.tls.key-store.sni Enables Server Name Indication (SNI). Server Name Indication (SNI) is a TLS extension that allows a client to specify the hostname it is attempting to connect to during the TLS handshake. This enables a server to present different SSL certificates for multiple domains on a single IP address, facilitating secure communication for virtual hosting scenarios. With this setting enabled, the client indicate the server name during the TLS handshake, allowing the server to select the right certificate. When configuring the keystore with PEM files, multiple CRT/Key must be given. When configuring the keystore with a JKS or a P12 file, it selects one alias based on the SNI hostname. In this case, all the keystore password and alias password must be the same (configured with the password and alias-password properties. Do not set the alias property. Environment variable: QUARKUS_TLS_KEY_STORE_SNI boolean false quarkus.tls.key-store.credentials-provider.name The name of the "credential" bucket (map key passwords) to retrieve from the io.quarkus.credentials.CredentialsProvider . If not set, the credential provider will not be used. A credential provider offers a way to retrieve the key store password as well as alias password. Note that the credential provider is only used if the passwords are not set in the configuration. Environment variable: QUARKUS_TLS_KEY_STORE_CREDENTIALS_PROVIDER_NAME string quarkus.tls.key-store.credentials-provider.bean-name The name of the bean providing the credential provider. The name is used to select the credential provider to use. The credential provider must be exposed as a CDI bean and with the @Named annotation set to the configured name to be selected. If not set, the default credential provider is used. Environment variable: QUARKUS_TLS_KEY_STORE_CREDENTIALS_PROVIDER_BEAN_NAME string quarkus.tls.key-store.credentials-provider.password-key The key used to retrieve the key store password. If the selected credential provider does not support the key, the password is not retrieved. Otherwise, the retrieved value is used to open the key store. Environment variable: QUARKUS_TLS_KEY_STORE_CREDENTIALS_PROVIDER_PASSWORD_KEY string password quarkus.tls.key-store.credentials-provider.alias-password-key The key used to retrieve the key store alias password. If the selected credential provider does not contain the key, the alias password is not retrieved. Otherwise, the retrieved value is used to access the alias private key from the key store. Environment variable: QUARKUS_TLS_KEY_STORE_CREDENTIALS_PROVIDER_ALIAS_PASSWORD_KEY string alias-password quarkus.tls.trust-store.pem.certs List of the trusted cert paths (Pem format). Environment variable: QUARKUS_TLS_TRUST_STORE_PEM_CERTS list of path quarkus.tls.trust-store.p12.path Path to the trust store file (P12 / PFX format). Environment variable: QUARKUS_TLS_TRUST_STORE_P12_PATH path required quarkus.tls.trust-store.p12.password Password of the trust store. If not set, the password must be retrieved from the credential provider. Environment variable: QUARKUS_TLS_TRUST_STORE_P12_PASSWORD string quarkus.tls.trust-store.p12.alias Alias of the trust store. Environment variable: QUARKUS_TLS_TRUST_STORE_P12_ALIAS string quarkus.tls.trust-store.p12.provider Provider of the trust store. Environment variable: QUARKUS_TLS_TRUST_STORE_P12_PROVIDER string quarkus.tls.trust-store.jks.path Path to the trust store file (JKS format). Environment variable: QUARKUS_TLS_TRUST_STORE_JKS_PATH path required quarkus.tls.trust-store.jks.password Password of the trust store. If not set, the password must be retrieved from the credential provider. Environment variable: QUARKUS_TLS_TRUST_STORE_JKS_PASSWORD string quarkus.tls.trust-store.jks.alias Alias of the key in the trust store. Environment variable: QUARKUS_TLS_TRUST_STORE_JKS_ALIAS string quarkus.tls.trust-store.jks.provider Provider of the trust store. Environment variable: QUARKUS_TLS_TRUST_STORE_JKS_PROVIDER string quarkus.tls.trust-store.credentials-provider.name The name of the "credential" bucket (map key passwords) to retrieve from the io.quarkus.credentials.CredentialsProvider . If not set, the credential provider will not be used. A credential provider offers a way to retrieve the key store password as well as alias password. Note that the credential provider is only used if the passwords are not set in the configuration. Environment variable: QUARKUS_TLS_TRUST_STORE_CREDENTIALS_PROVIDER_NAME string quarkus.tls.trust-store.credentials-provider.bean-name The name of the bean providing the credential provider. The name is used to select the credential provider to use. The credential provider must be exposed as a CDI bean and with the @Named annotation set to the configured name to be selected. If not set, the default credential provider is used. Environment variable: QUARKUS_TLS_TRUST_STORE_CREDENTIALS_PROVIDER_BEAN_NAME string quarkus.tls.trust-store.credentials-provider.password-key The key used to retrieve the trust store password. If the selected credential provider does not contain the configured key, the password is not retrieved. Otherwise, the retrieved value is used to open the trust store. Environment variable: QUARKUS_TLS_TRUST_STORE_CREDENTIALS_PROVIDER_PASSWORD_KEY string password quarkus.tls.cipher-suites Sets the ordered list of enabled cipher suites. If none is given, a reasonable default is selected from the built-in ciphers. When suites are set, it takes precedence over the default suite defined by the SSLEngineOptions in use. Environment variable: QUARKUS_TLS_CIPHER_SUITES list of string quarkus.tls.protocols Sets the ordered list of enabled TLS protocols. If not set, it defaults to "TLSv1.3, TLSv1.2" . The following list of protocols are supported: TLSv1, TLSv1.1, TLSv1.2, TLSv1.3 . To only enable TLSv1.3 , set the value to to "TLSv1.3" . Note that setting an empty list, and enabling TLS is invalid. You must at least have one protocol. Also, setting this replaces the default list of protocols. Environment variable: QUARKUS_TLS_PROTOCOLS list of string TLSv1.3,TLSv1.2 quarkus.tls.handshake-timeout The timeout for the TLS handshake phase. If not set, it defaults to 10 seconds. Environment variable: QUARKUS_TLS_HANDSHAKE_TIMEOUT Duration 10S quarkus.tls.alpn Enables the Application-Layer Protocol Negotiation (ALPN). Application-Layer Protocol Negotiation is a TLS extension that allows the client and server during the TLS handshake to negotiate which protocol they will use for communication. ALPN enables more efficient communication by allowing the client to indicate its preferred application protocol to the server before the TLS connection is established. This helps in scenarios such as HTTP/2 where multiple protocols may be available, allowing for faster protocol selection. Environment variable: QUARKUS_TLS_ALPN boolean true quarkus.tls.certificate-revocation-list Sets the list of revoked certificates (paths to files). A Certificate Revocation List (CRL) is a list of digital certificates that have been revoked by the issuing Certificate Authority (CA) before their scheduled expiration date. When a certificate is compromised, no longer needed, or deemed invalid for any reason, the CA adds it to the CRL to inform relying parties not to trust the certificate anymore. Two formats are allowed: DER and PKCS#7 (also known as P7B). When using the DER format, you must pass DER-encoded CRLs. When using the PKCS#7 format, you must pass PKCS#7 SignedData object, with the only significant field being crls . Environment variable: QUARKUS_TLS_CERTIFICATE_REVOCATION_LIST list of path quarkus.tls.trust-all If set to true , the server trusts all certificates. This is useful for testing, but should not be used in production. Environment variable: QUARKUS_TLS_TRUST_ALL boolean false quarkus.tls.hostname-verification-algorithm The hostname verification algorithm to use in case the server's identity should be checked. Should be HTTPS (default), LDAPS or NONE . If set to NONE , it does not verify the hostname. If not set, the configured extension decides the default algorithm to use. For example, for HTTP, it will be "HTTPS". For TCP, it can depend on the protocol. Nevertheless, it is recommended to set it to "HTTPS" or "LDAPS". Environment variable: QUARKUS_TLS_HOSTNAME_VERIFICATION_ALGORITHM string quarkus.tls.reload-period When configured, the server will reload the certificates (from the file system for example) and fires a CertificateUpdatedEvent if the reload is successful This property configures the period to reload the certificates. IF not set, the certificates won't be reloaded automatically. However, the application can still trigger the reload manually using the io.quarkus.tls.TlsConfiguration#reload() method, and then fire the CertificateUpdatedEvent manually. The fired event is used to notify the application that the certificates have been updated, and thus proceed with the actual switch of certificates. Environment variable: QUARKUS_TLS_RELOAD_PERIOD Duration quarkus.tls.key-store.pem."key-certs".key The path to the key file (in PEM format). Environment variable: QUARKUS_TLS_KEY_STORE_PEM__KEY_CERTS__KEY path required quarkus.tls.key-store.pem."key-certs".cert The path to the certificate file (in PEM format). Environment variable: QUARKUS_TLS_KEY_STORE_PEM__KEY_CERTS__CERT path required quarkus.tls."tls-bucket-name".key-store.pem."key-certs".key The path to the key file (in PEM format). Environment variable: QUARKUS_TLS__TLS_BUCKET_NAME__KEY_STORE_PEM__KEY_CERTS__KEY path required quarkus.tls."tls-bucket-name".key-store.pem."key-certs".cert The path to the certificate file (in PEM format). Environment variable: QUARKUS_TLS__TLS_BUCKET_NAME__KEY_STORE_PEM__KEY_CERTS__CERT path required quarkus.tls."tls-bucket-name".key-store.pem.order The order of the key/cert files, based on the names in the keyCerts map. By default, Quarkus sorts the key using a lexicographical order. This property allows you to specify the order of the key/cert files. Environment variable: QUARKUS_TLS__TLS_BUCKET_NAME__KEY_STORE_PEM_ORDER list of string quarkus.tls."tls-bucket-name".key-store.p12.path Path to the key store file (P12 / PFX format). Environment variable: QUARKUS_TLS__TLS_BUCKET_NAME__KEY_STORE_P12_PATH path required quarkus.tls."tls-bucket-name".key-store.p12.password Password of the key store. When not set, the password must be retrieved from the credential provider. Environment variable: QUARKUS_TLS__TLS_BUCKET_NAME__KEY_STORE_P12_PASSWORD string quarkus.tls."tls-bucket-name".key-store.p12.alias Alias of the private key and certificate in the key store. Environment variable: QUARKUS_TLS__TLS_BUCKET_NAME__KEY_STORE_P12_ALIAS string quarkus.tls."tls-bucket-name".key-store.p12.alias-password Password of the alias in the key store. If not set, the password will be retrieved from the credential provider. Environment variable: QUARKUS_TLS__TLS_BUCKET_NAME__KEY_STORE_P12_ALIAS_PASSWORD string quarkus.tls."tls-bucket-name".key-store.p12.provider Provider of the key store. Environment variable: QUARKUS_TLS__TLS_BUCKET_NAME__KEY_STORE_P12_PROVIDER string quarkus.tls."tls-bucket-name".key-store.jks.path Path to the keystore file (JKS format). Environment variable: QUARKUS_TLS__TLS_BUCKET_NAME__KEY_STORE_JKS_PATH path required quarkus.tls."tls-bucket-name".key-store.jks.password Password of the key store. When not set, the password must be retrieved from the credential provider. Environment variable: QUARKUS_TLS__TLS_BUCKET_NAME__KEY_STORE_JKS_PASSWORD string quarkus.tls."tls-bucket-name".key-store.jks.alias Alias of the private key and certificate in the key store. Environment variable: QUARKUS_TLS__TLS_BUCKET_NAME__KEY_STORE_JKS_ALIAS string quarkus.tls."tls-bucket-name".key-store.jks.alias-password Password of the alias in the key store. When not set, the password may be retrieved from the credential provider. Environment variable: QUARKUS_TLS__TLS_BUCKET_NAME__KEY_STORE_JKS_ALIAS_PASSWORD string quarkus.tls."tls-bucket-name".key-store.jks.provider Provider of the key store. Environment variable: QUARKUS_TLS__TLS_BUCKET_NAME__KEY_STORE_JKS_PROVIDER string quarkus.tls."tls-bucket-name".key-store.sni Enables Server Name Indication (SNI). Server Name Indication (SNI) is a TLS extension that allows a client to specify the hostname it is attempting to connect to during the TLS handshake. This enables a server to present different SSL certificates for multiple domains on a single IP address, facilitating secure communication for virtual hosting scenarios. With this setting enabled, the client indicate the server name during the TLS handshake, allowing the server to select the right certificate. When configuring the keystore with PEM files, multiple CRT/Key must be given. When configuring the keystore with a JKS or a P12 file, it selects one alias based on the SNI hostname. In this case, all the keystore password and alias password must be the same (configured with the password and alias-password properties. Do not set the alias property. Environment variable: QUARKUS_TLS__TLS_BUCKET_NAME__KEY_STORE_SNI boolean false quarkus.tls."tls-bucket-name".key-store.credentials-provider.name The name of the "credential" bucket (map key passwords) to retrieve from the io.quarkus.credentials.CredentialsProvider . If not set, the credential provider will not be used. A credential provider offers a way to retrieve the key store password as well as alias password. Note that the credential provider is only used if the passwords are not set in the configuration. Environment variable: QUARKUS_TLS__TLS_BUCKET_NAME__KEY_STORE_CREDENTIALS_PROVIDER_NAME string quarkus.tls."tls-bucket-name".key-store.credentials-provider.bean-name The name of the bean providing the credential provider. The name is used to select the credential provider to use. The credential provider must be exposed as a CDI bean and with the @Named annotation set to the configured name to be selected. If not set, the default credential provider is used. Environment variable: QUARKUS_TLS__TLS_BUCKET_NAME__KEY_STORE_CREDENTIALS_PROVIDER_BEAN_NAME string quarkus.tls."tls-bucket-name".key-store.credentials-provider.password-key The key used to retrieve the key store password. If the selected credential provider does not support the key, the password is not retrieved. Otherwise, the retrieved value is used to open the key store. Environment variable: QUARKUS_TLS__TLS_BUCKET_NAME__KEY_STORE_CREDENTIALS_PROVIDER_PASSWORD_KEY string password quarkus.tls."tls-bucket-name".key-store.credentials-provider.alias-password-key The key used to retrieve the key store alias password. If the selected credential provider does not contain the key, the alias password is not retrieved. Otherwise, the retrieved value is used to access the alias private key from the key store. Environment variable: QUARKUS_TLS__TLS_BUCKET_NAME__KEY_STORE_CREDENTIALS_PROVIDER_ALIAS_PASSWORD_KEY string alias-password quarkus.tls."tls-bucket-name".trust-store.pem.certs List of the trusted cert paths (Pem format). Environment variable: QUARKUS_TLS__TLS_BUCKET_NAME__TRUST_STORE_PEM_CERTS list of path quarkus.tls."tls-bucket-name".trust-store.p12.path Path to the trust store file (P12 / PFX format). Environment variable: QUARKUS_TLS__TLS_BUCKET_NAME__TRUST_STORE_P12_PATH path required quarkus.tls."tls-bucket-name".trust-store.p12.password Password of the trust store. If not set, the password must be retrieved from the credential provider. Environment variable: QUARKUS_TLS__TLS_BUCKET_NAME__TRUST_STORE_P12_PASSWORD string quarkus.tls."tls-bucket-name".trust-store.p12.alias Alias of the trust store. Environment variable: QUARKUS_TLS__TLS_BUCKET_NAME__TRUST_STORE_P12_ALIAS string quarkus.tls."tls-bucket-name".trust-store.p12.provider Provider of the trust store. Environment variable: QUARKUS_TLS__TLS_BUCKET_NAME__TRUST_STORE_P12_PROVIDER string quarkus.tls."tls-bucket-name".trust-store.jks.path Path to the trust store file (JKS format). Environment variable: QUARKUS_TLS__TLS_BUCKET_NAME__TRUST_STORE_JKS_PATH path required quarkus.tls."tls-bucket-name".trust-store.jks.password Password of the trust store. If not set, the password must be retrieved from the credential provider. Environment variable: QUARKUS_TLS__TLS_BUCKET_NAME__TRUST_STORE_JKS_PASSWORD string quarkus.tls."tls-bucket-name".trust-store.jks.alias Alias of the key in the trust store. Environment variable: QUARKUS_TLS__TLS_BUCKET_NAME__TRUST_STORE_JKS_ALIAS string quarkus.tls."tls-bucket-name".trust-store.jks.provider Provider of the trust store. Environment variable: QUARKUS_TLS__TLS_BUCKET_NAME__TRUST_STORE_JKS_PROVIDER string quarkus.tls."tls-bucket-name".trust-store.credentials-provider.name The name of the "credential" bucket (map key passwords) to retrieve from the io.quarkus.credentials.CredentialsProvider . If not set, the credential provider will not be used. A credential provider offers a way to retrieve the key store password as well as alias password. Note that the credential provider is only used if the passwords are not set in the configuration. Environment variable: QUARKUS_TLS__TLS_BUCKET_NAME__TRUST_STORE_CREDENTIALS_PROVIDER_NAME string quarkus.tls."tls-bucket-name".trust-store.credentials-provider.bean-name The name of the bean providing the credential provider. The name is used to select the credential provider to use. The credential provider must be exposed as a CDI bean and with the @Named annotation set to the configured name to be selected. If not set, the default credential provider is used. Environment variable: QUARKUS_TLS__TLS_BUCKET_NAME__TRUST_STORE_CREDENTIALS_PROVIDER_BEAN_NAME string quarkus.tls."tls-bucket-name".trust-store.credentials-provider.password-key The key used to retrieve the trust store password. If the selected credential provider does not contain the configured key, the password is not retrieved. Otherwise, the retrieved value is used to open the trust store. Environment variable: QUARKUS_TLS__TLS_BUCKET_NAME__TRUST_STORE_CREDENTIALS_PROVIDER_PASSWORD_KEY string password quarkus.tls."tls-bucket-name".cipher-suites Sets the ordered list of enabled cipher suites. If none is given, a reasonable default is selected from the built-in ciphers. When suites are set, it takes precedence over the default suite defined by the SSLEngineOptions in use. Environment variable: QUARKUS_TLS__TLS_BUCKET_NAME__CIPHER_SUITES list of string quarkus.tls."tls-bucket-name".protocols Sets the ordered list of enabled TLS protocols. If not set, it defaults to "TLSv1.3, TLSv1.2" . The following list of protocols are supported: TLSv1, TLSv1.1, TLSv1.2, TLSv1.3 . To only enable TLSv1.3 , set the value to to "TLSv1.3" . Note that setting an empty list, and enabling TLS is invalid. You must at least have one protocol. Also, setting this replaces the default list of protocols. Environment variable: QUARKUS_TLS__TLS_BUCKET_NAME__PROTOCOLS list of string TLSv1.3,TLSv1.2 quarkus.tls."tls-bucket-name".handshake-timeout The timeout for the TLS handshake phase. If not set, it defaults to 10 seconds. Environment variable: QUARKUS_TLS__TLS_BUCKET_NAME__HANDSHAKE_TIMEOUT Duration 10S quarkus.tls."tls-bucket-name".alpn Enables the Application-Layer Protocol Negotiation (ALPN). Application-Layer Protocol Negotiation is a TLS extension that allows the client and server during the TLS handshake to negotiate which protocol they will use for communication. ALPN enables more efficient communication by allowing the client to indicate its preferred application protocol to the server before the TLS connection is established. This helps in scenarios such as HTTP/2 where multiple protocols may be available, allowing for faster protocol selection. Environment variable: QUARKUS_TLS__TLS_BUCKET_NAME__ALPN boolean true quarkus.tls."tls-bucket-name".certificate-revocation-list Sets the list of revoked certificates (paths to files). A Certificate Revocation List (CRL) is a list of digital certificates that have been revoked by the issuing Certificate Authority (CA) before their scheduled expiration date. When a certificate is compromised, no longer needed, or deemed invalid for any reason, the CA adds it to the CRL to inform relying parties not to trust the certificate anymore. Two formats are allowed: DER and PKCS#7 (also known as P7B). When using the DER format, you must pass DER-encoded CRLs. When using the PKCS#7 format, you must pass PKCS#7 SignedData object, with the only significant field being crls . Environment variable: QUARKUS_TLS__TLS_BUCKET_NAME__CERTIFICATE_REVOCATION_LIST list of path quarkus.tls."tls-bucket-name".trust-all If set to true , the server trusts all certificates. This is useful for testing, but should not be used in production. Environment variable: QUARKUS_TLS__TLS_BUCKET_NAME__TRUST_ALL boolean false quarkus.tls."tls-bucket-name".hostname-verification-algorithm The hostname verification algorithm to use in case the server's identity should be checked. Should be HTTPS (default), LDAPS or NONE . If set to NONE , it does not verify the hostname. If not set, the configured extension decides the default algorithm to use. For example, for HTTP, it will be "HTTPS". For TCP, it can depend on the protocol. Nevertheless, it is recommended to set it to "HTTPS" or "LDAPS". Environment variable: QUARKUS_TLS__TLS_BUCKET_NAME__HOSTNAME_VERIFICATION_ALGORITHM string quarkus.tls."tls-bucket-name".reload-period When configured, the server will reload the certificates (from the file system for example) and fires a CertificateUpdatedEvent if the reload is successful This property configures the period to reload the certificates. IF not set, the certificates won't be reloaded automatically. However, the application can still trigger the reload manually using the io.quarkus.tls.TlsConfiguration#reload() method, and then fire the CertificateUpdatedEvent manually. The fired event is used to notify the application that the certificates have been updated, and thus proceed with the actual switch of certificates. Environment variable: QUARKUS_TLS__TLS_BUCKET_NAME__RELOAD_PERIOD Duration About the Duration format To write duration values, use the standard java.time.Duration format. See the Duration#parse() Java API documentation for more information. You can also use a simplified format, starting with a number: If the value is only a number, it represents time in seconds. If the value is a number followed by ms , it represents time in milliseconds. In other cases, the simplified format is translated to the java.time.Duration format for parsing: If the value is a number followed by h , m , or s , it is prefixed with PT . If the value is a number followed by d , it is prefixed with P . 1.4. The registry API While extensions automatically use the TLS registry, you can also access the TLS configuration programmatically through the registry API. To access the TLS configuration, inject the TlsConfigurationRegistry bean. You can retrieve a named TLS configuration by calling get("<NAME>") or the default configuration by calling getDefault() . @Inject TlsConfigurationRegistry certificates; // ... TlsConfiguration def = certificates.getDefault().orElseThrow(); TlsConfiguration named = certificates.get("name").orElseThrow(); //... The TlsConfiguration object contains the keystores, truststores, cipher suites, protocols, and other properties. It also provides a way to create an SSLContext from the configuration. You can also use the TlsConfiguration object to configure the Vert.x client or server, such as KeyCertOptions , TrustOptions , and so on. 1.5. Registering a certificate from an extension This section is only for extension developers. An extension can register a certificate in the TLS registry. This is useful when an extension needs to provide a certificate to the application or provides a different format. To register a certificate in the TLS registry by using the extension, the processor extension must produce a TlsCertificateBuildItem composed of a name and a CertificateSupplier . TlsCertificateBuildItem item = new TlsCertificateBuildItem("named", new MyCertificateSupplier()); The certificate supplier is a runtime object generally retrieved by using a recorder method. An example of a certificate supplier: public class MyCertificateSupplier implements Supplier<TlsConfiguration> { @Override public TlsConfiguration get() { try { KeyStore ks = KeyStore.getInstance("PKCS12"); ks.load(getClass().getResourceAsStream("target/certs/test-registration-keystore.p12"), "password".toCharArray()); KeyStore ts = KeyStore.getInstance("PKCS12"); ts.load(getClass().getResourceAsStream("target/certs/test-registration-truststore.p12"), "password".toCharArray()); return new BaseTlsConfiguration() { @Override public KeyStore getKeyStore() { return ks; } @Override public KeyStore getTrustStore() { return ts; } }; } catch (Exception e) { throw new RuntimeException(e); } } } 1.6. Startup checks When an application that uses the TLS extension starts, the TLS registry performs several checks to ensure the configuration is correct: Keystores and truststores are accessible. Aliases are available and accessible in the keystores and truststores. Certificates are valid. Cipher suites and protocols are valid. Certificate Revocation Lists (CRLs) are valid. If any of these checks fail, the application will not start. 1.7. Reloading certificates The TlsConfiguration obtained from the TLSConfigurationRegistry includes a mechanism for reloading certificates. The reload method refreshes the keystores and truststores, typically by reloading them from the file system. Note The reload operation is not automatic and must be triggered manually. Additionally, the TlsConfiguration implementation must support reloading (which is the case for the configured certificate). The reload method returns a boolean indicating whether the reload was successful. A value of true means the reload operation was successful, not necessarily that there were updates to the certificates. After a TlsConfiguration has been reloaded, servers and clients using this configuration may need to perform specific actions to apply the new certificates. The recommended approach for informing clients and servers about the certificate reload is to fire a CDI event of type io.quarkus.tls.CertificateUpdatedEvent . To do so, inject a CDI event of this type and fire it when a reload occurs. Manually triggering a reload and firing a CertificateUpdatedEvent : 1.7.1. Periodic reloading The TLS registry includes a built-in mechanism for periodically checking the file system for changes and reloading certificates. The reload-period property specifies the interval for reloading certificates and emits a CertificateUpdatedEvent each time certificates are reloaded. To configure periodic certificate reloading: quarkus.tls.reload-period=1h quarkus.tls.key-store.pem.0.cert=tls.crt quarkus.tls.key-store.pem.0.key=tls.key For each named configuration, you can set a specific reload period: quarkus.tls.http.reload-period=30min quarkus.tls.http.key-store.pem.0.cert=tls.crt quarkus.tls.http.key-store.pem.0.key=tls.key Important Impacted server and client may need to listen to the CertificateUpdatedEvent to apply the new certificates. This is automatically done for the Quarkus HTTP server, including the management interface if it is enabled. 1.8. Working with OpenShift serving certificates When running your application in OpenShift, you can use the OpenShift serving certificates to generate and renew TLS certificates automatically. The Quarkus TLS registry can use these certificates and Certificate Authority (CA) files to handle HTTPS traffic and validate certificates securely. 1.8.1. Acquiring a certificate To have OpenShift generate a serving certificate, annotate an existing Service object. The generated certificate will be stored in a secret, which you can then mount in your pod. The following snippet uses an example Service object with an annotation for generating a TLS certificate. View the configuration of the Service object: apiVersion: v1 kind: Service metadata: labels: app.kubernetes.io/name: ... app.kubernetes.io/version: ... app.kubernetes.io/managed-by: quarkus name: hero-service spec: ports: - name: http port: 443 protocol: TCP targetPort: 8443 selector: app.kubernetes.io/name: ... app.kubernetes.io/version: ... type: ClusterIP To generate a certificate, add his annotation to your already created OpenShift service : oc annotate service hero-service \ service.beta.openshift.io/serving-cert-secret-name=my-tls-secret The annotation service.beta.openshift.io/serving-cert-secret-name instructs OpenShift to generate a certificate and store it in a secret named my-tls-secret . Mount the secret as a volume in your pod by updating your Deployment configuration: apiVersion: apps/v1 kind: Deployment metadata: labels: app.kubernetes.io/name: ... app.kubernetes.io/version: ... name: my-service spec: replicas: 1 selector: matchLabels: app.kubernetes.io/name: ... app.kubernetes.io/version: ... template: metadata: labels: app.kubernetes.io/name: ... app.kubernetes.io/version: ... spec: volumes: - name: my-tls-secret 1 secret: secretName: my-tls-secret containers: - env: - name: KUBERNETES_NAMESPACE valueFrom: fieldRef: fieldPath: metadata.namespace - name: QUARKUS_TLS_KEY_STORE_PEM_ACME_CERT 2 value: /etc/tls/tls.crt - name: QUARKUS_TLS_KEY_STORE_PEM_ACME_KEY value: /etc/tls/tls.key image: ... imagePullPolicy: Always name: my-service volumeMounts: 3 - name: my-tls-secret mountPath: /etc/tls readOnly: true ports: - containerPort: 8443 4 name: https protocol: TCP 1 Define a volume to mount the secret. Use the same name as the secret declared above. 2 Set up the keystore with the paths to the certificate and private key. This can be configured by using environment variables or configuration files. This example uses environment variables. OpenShift serving certificates always create the tls.crt and tls.key files. 3 Mount the secret in the container. Ensure that the path matches the one used in the configuration (here /etc/tls ). 4 Configure the port to serve HTTPS. Deploy your application to use the certificate generated by OpenShift. This will make the service available over HTTPS. Note By setting the quarkus.tls.key-store.pem.acme.cert and quarkus.tls.key-store.pem.acme.key variables or their environment variable variant, the TLS registry will use the certificate and private key from the secret. This configures the default keystore for the Quarkus HTTP server, which allows the server to use the certificate. For information about using this certificate in a named configuration, see Referencing a TLS configuration . 1.8.2. Trusting the Certificate Authority (CA) Prerequisites Acquiring a certificate Now that your service uses a certificate issued by OpenShift, configure your client applications to trust this certificate. To do so, create a ConfigMap that holds the CA certificate, and then configure the pod to mount it. The following steps use a Quarkus REST client as an example, but the same approach applies to any client. Start by defining an empty ConfigMap, which will be populated with the CA certificate: apiVersion: v1 kind: ConfigMap metadata: name: client-tls-config annotations: service.beta.openshift.io/inject-cabundle: "true" The service.beta.openshift.io/inject-cabundle annotation is used to inject the CA certificate into the ConfigMap. Note that the ConfigMap initially has no data - it is empty. During its processing, OpenShift injects the CA certificate into the ConfigMap in the service-ca.crt file. Mount the ConfigMap by adding a volume and mounting it in your Deployment configuration: apiVersion: apps/v1 kind: Deployment metadata: name: my-service-client labels: app.kubernetes.io/name: ... app.kubernetes.io/version: ... spec: replicas: 1 selector: matchLabels: app.kubernetes.io/name: ... app.kubernetes.io/version: ... template: metadata: labels: app.kubernetes.io/name: ... app.kubernetes.io/version: ... spec: containers: - name: my-service-client image: ... ports: - name: http containerPort: 8080 protocol: TCP volumeMounts: 1 - name: my-client-volume mountPath: /deployments/tls volumes: 2 - name: my-client-volume configMap: name: client-tls-config 1 Mount the ConfigMap in the container. Ensure that the path matches the one used in the configuration (in this example /deployments/tls ). 2 Define a volume to mount the ConfigMap and reference the ConfigMap that receives the CA certificate. Configure the REST client to use this CA certificate. Consider the following REST client interface: package org.acme; import jakarta.ws.rs.GET; import jakarta.ws.rs.Path; import org.eclipse.microprofile.rest.client.inject.RegisterRestClient; @RegisterRestClient(baseUri = "https://hero-service.cescoffi-dev.svc", configKey = "hero") 1 public interface HeroClient { record Hero (Long id, String name, String otherName, int level, String picture, String powers) { } @GET @Path("/api/heroes/random") Hero getRandomHero(); } 1 Configure the base URI and the configuration key. The name must be in the format <service-name>.<namespace>.svc . Otherwise, the certificate will not be trusted. Ensure that the configKey is also configured. Configure the REST client to trust the CA certificate generated by OpenShift: quarkus.rest-client.hero.tls-configuration-name=my-service-tls 1 quarkus.tls.my-service-tls.trust-store.pem.certs=/deployments/tls/service-ca.crt 2 1 Configure the hero REST client with the TLS configuration named my-service-tls . 2 Set up the my-service-tls TLS configuration, specifically the truststore with the CA certificate. Ensure the path matches the one used in the Kubernetes Deployment configuration. The file is always named service-ca.crt . 1.8.3. Certificate renewal OpenShift automatically renews the serving certificates it generates. When the certificate is renewed, the secret is updated with the new certificate and private key. To ensure your application uses the new certificate, you can use the periodic reloading feature of the Quarkus TLS registry. By setting the reload-period property, the TLS registry will periodically check the keystores and truststores for changes and reload them if needed: quarkus.tls.reload-period=24h Optionally, implement a custom mechanism to reload the certificates when the secret is updated. See Reloading certificates for more information. 1.9. Quarkus CLI commands and development Certificate Authority The TLS registry provides Quarkus CLI commands to generate a development Certificate Authority (CA) and trusted certificates. This avoids having to use self-signed certificates locally. The following snippet shows the description of the quarkus tls command, containing two sub-commands: > quarkus tls Install and Manage TLS development certificates Usage: tls [COMMAND] Commands: generate-quarkus-ca Generate Quarkus Dev CA certificate and private key. 1 generate-certificate Generate a TLS certificate with the Quarkus Dev CA if available. 2 1 This is useful for local development, as it allows Quarkus to act as its own certificate authority, which can be used to sign other certificates. 2 This is useful when creating a certificate for secure communication between your application and external services or clients during development. In most cases, you generate the Quarkus Development CA once and then generate certificates signed by this CA. The Quarkus Development CA is a Certificate Authority that can be used to sign certificates locally. It is only valid for development purposes and only trusted on the local machine. The generated CA is located in USDHOME/.quarkus/quarkus-dev-root-ca.pem , and installed in the system truststore. 1.9.1. Understanding self-signed versus CA-signed certificates When developing with TLS, you can use two types of certificates: Self-signed certificate : The certificate is signed by the same entity that uses it. It is not trusted by default. This type of certificate is typically used when a Certificate Authority (CA) is unavailable or you want a simple setup. It is not suitable for production and should only be used for development. CA-signed certificate : The certificate is signed by a Certificate CA, a trusted entity. This certificate is trusted by default and is the standard choice for production environments. While you can use a self-signed certificate for local development, it has limitations. Browsers and tools like curl , wget , and httpie typically do not trust self-signed certificates, requiring manual import of the CA in your OS. To avoid this issue, you can use a development CA to sign certificates and install the CA in the system truststore. This ensures that the system trusts all certificates signed by the CA. Quarkus simplifies the generation of a development CA and the certificates that are signed by this CA. 1.9.2. Generate a development CA The development CA is a Certificate Authority that can be used to sign certificates locally. Note that the generated CA is only valid for development purposes and can only be trusted on the local machine. To generate a development CA: quarkus tls generate-ca-certificate --install \ 1 --renew \ 2 --truststore 3 1 --install installs the CA in the system truststore. Windows, Mac, and Linux (Fedora and Ubuntu) are supported. However, depending on your browser, you might need to import the generated CA manually. Refer to your browser's documentation for more information. The generated CA is located in USDHOME/.quarkus/quarkus-dev-root-ca.pem . 2 --renew renews the CA if it already exists. When this option is used, the private key is changed, so you need to regenerate the certificates signed by the CA. If the CA expires, it will automatically renew without requiring the --renew option. 3 --truststore also generates a PKCS12 truststore containing the CA certificate. Warning When installing the certificate, your system might ask for your password to install the certificate in the system truststore or ask for confirmation in a dialog on Windows. Important On Windows, run as administrator from an elevated terminal to install the CA in the system truststore. 1.9.3. Generating a trusted (signed) certificate Prerequisites Generate a development CA After installing the Quarkus Development CA, generate a trusted certificate. This certificate will be signed by the Quarkus Development CA and trusted by your system. quarkus tls generate-certificate --name my-cert This command generates a certificate signed by the Quarkus Development CA, which your system will trust if properly installed or imported. The certificate is stored in ./.certs/ . Two files are generated: USDNAME-keystore.p12 : Contains the private key and the certificate. It is password-protected. USDNAME-truststore.p12 : Contains the CA certificate, which you can use as a truststore, for example, for testing. Additional options are available: Usage: tls generate-certificate [-hrV] [-c=<cn>] [-d=<directory>] -n=<name> [-p=<password>] Generate a TLS certificate with the Quarkus Dev CA if available. -c, --cn=<cn> The common name of the certificate. Default is 'localhost' -d, --directory=<directory> The directory in which the certificates will be created. Default is `.certs` -n, --name=<name> Name of the certificate. It will be used as file name and alias in the keystore -p, --password=<password> The password of the keystore. Default is 'password' -r, --renew Whether existing certificates will need to be replaced A .env file is also generated when generating the certificate, making the Quarkus dev mode aware of these certificates. Run your application in dev mode to use these certificates: ./mvnw quarkus:dev ... INFO [io.quarkus] (Quarkus Main Thread) demo 1.0.0-SNAPSHOT on JVM (powered by Quarkus 999-SNAPSHOT) started in 1.286s. Listening on: http://localhost:8080 and https://localhost:8443 Open the Dev UI by using HTTPS: https://localhost:8443/q/dev or by issuing a curl request: curl https://localhost:8443/hello Hello from Quarkus REST% Important Quarkus generates a self-signed certificate if the Quarkus Development CA is not installed. 1.9.4. Generating a self-signed certificate Even if the Quarkus Development CA is installed, you can generate a self-signed certificate: quarkus tls generate-certificate --name my-cert --self-signed This generates a self-signed certificate that the Quarkus Development CA does not sign. 1.9.5. Uninstalling the Quarkus Development CA Uninstalling the Quarkus Development CA from your system depends on your OS. 1.9.5.1. Deleting the CA certificate on Windows List the CA certificate on Windows by using the Powershell terminal with administrator rights: # First, we need to identify the serial number of the CA certificate > certutil -store -user Root root "Trusted Root Certification Authorities" ================ Certificate 0 ================ Serial Number: 019036d564c8 Issuer: O=Quarkus, CN=quarkus-dev-root-ca # <-That's the CA, copy the Serial Number (the line above) NotBefore: 6/19/2024 11:07 AM NotAfter: 6/20/2025 11:07 AM Subject: C=Cloud, S=world, L=home, OU=Quarkus Dev, O=Quarkus Dev, CN=quarkus-dev-root-ca Signature matches Public Key Non-root Certificate uses same Public Key as Issuer Cert Hash(sha1): 3679bc95b613a2112a3d3256fe8321b6eccce720 No key provider information Cannot find the certificate and private key for decryption. CertUtil: -store command completed successfully. Delete the stored CA certificate and replace USDSerial_Number with the serial number of the CA certificate: > certutil -delstore -user -v Root USDSerial_Number 1.9.5.2. Deleting the CA certificate on Linux On Fedora: sudo rm /etc/pki/ca-trust/source/anchors/quarkus-dev-root-ca.pem sudo update-ca-trust On Ubuntu: sudo rm /usr/local/share/ca-certificates/quarkus-dev-root-ca.pem sudo update-ca-certificates 1.9.5.3. Deleting the CA certificate on Mac On Mac: sudo security -v remove-trusted-cert -d /Users/clement/.quarkus/quarkus-dev-root-ca.pem

Commands:
quarkus.tls.key-store.pem.0.cert=server.crt quarkus.tls.key-store.pem.0.key=server.key quarkus.http.insecure-requests=disabled # Reject HTTP requests
quarkus.tls.key-store.p12.path=server-keystore.p12 quarkus.tls.key-store.p12.password=secret quarkus.http.insecure-requests=disabled # Reject HTTP requests
quarkus.tls.https.key-store.p12.path=server-keystore.p12 quarkus.tls.https.key-store.p12.password=secret quarkus.http.insecure-requests=disabled quarkus.http.tls-configuration-name=https
quarkus.tls.trust-store.jks.path=grpc-client-truststore.jks quarkus.tls.trust-store.jks.password=password quarkus.grpc.clients.hello.plain-text=false quarkus.grpc.clients.hello.use-quarkus-grpc-client=true
quarkus.tls.my-server.key-store.p12.path=target/certs/grpc-keystore.p12 quarkus.tls.my-server.key-store.p12.password=password quarkus.tls.my-server.trust-store.p12.path=target/certs/grpc-server-truststore.p12 quarkus.tls.my-server.trust-store.p12.password=password quarkus.tls.my-client.trust-store.p12.path=target/certs/grpc-client-truststore.p12 quarkus.tls.my-client.trust-store.p12.password=password quarkus.tls.my-client.key-store.p12.path=target/certs/grpc-client-keystore.p12 quarkus.tls.my-client.key-store.p12.password=password quarkus.grpc.clients.hello.plain-text=false quarkus.grpc.clients.hello.tls-configuration-name=my-client quarkus.grpc.clients.hello.use-quarkus-grpc-client=true quarkus.http.ssl.client-auth=REQUIRED # Enable mTLS quarkus.http.insecure-requests=disabled quarkus.http.tls-configuration-name=my-server quarkus.grpc.server.use-separate-server=false quarkus.grpc.server.plain-text=false
Reference the named configuration quarkus.http.tls-configuration-name=MY_TLS_CONFIGURATION
quarkus.grpc.clients.hello.tls-configuration-name=MY_TLS_CONFIGURATION
quarkus.tls.key-store.pem.a.cert=server.crt quarkus.tls.key-store.pem.a.key=server.key quarkus.tls.key-store.pem.b.cert=my-second-cert.crt quarkus.tls.key-store.pem.b.key=my-second-key.key
quarkus.tls.key-store.p12.path=server-keystore.p12 quarkus.tls.key-store.p12.password=secret
quarkus.tls.key-store.p12.path=server-keystore.p12 quarkus.tls.key-store.p12.password=secret quarkus.tls.key-store.p12.alias=my-alias quarkus.tls.key-store.p12.alias-password=my-alias-password
quarkus.tls.key-store.jks.path=server-keystore.jks quarkus.tls.key-store.jks.password=secret
quarkus.tls.key-store.jks.path=server-keystore.jks quarkus.tls.key-store.jks.password=secret quarkus.tls.key-store.jks.alias=my-alias quarkus.tls.key-store.jks.alias-password=my-alias-password
quarkus.tls.key-store.sni=true # Disabled by default
The name of the credential bucket in the credentials provider quarkus.tls.key-store.credentials-provider.name=my-credentials The name of the bean providing the credential provider (optional, using the default credential provider if not set) quarkus.tls.key-store.credentials-provider.bean-name=my-credentials-provider The key used to retrieve the keystore password, `password` by default quarkus.tls.key-store.credentials-provider.password-key=password The key used to retrieve the alias password, `alias-password` by default quarkus.tls.key-store.credentials-provider.alias-password-key=alias-password
quarkus.tls.trust-store.pem.certs=ca.crt,ca2.pem
quarkus.tls.trust-store.p12.path=client-truststore.p12 quarkus.tls.trust-store.p12.password=password quarkus.tls.trust-store.p12.alias=my-alias
quarkus.tls.trust-store.jks.path=client-truststore.jks quarkus.tls.trust-store.jks.password=password quarkus.tls.trust-store.jks.alias=my-alias
The name of the credential bucket in the credentials provider quarkus.tls.trust-store.credentials-provider.name=my-credentials The name of the bean providing the credential provider (optional, using the default credential provider if not set) quarkus.tls.trust-store.credentials-provider.bean-name=my-credentials-provider The key used to retrieve the truststore password, `password` by default quarkus.tls.trust-store.credentials-provider.password-key=password
quarkus.tls.cipher-suites=TLS_AES_128_GCM_SHA256,TLS_AES_256_GCM_SHA384
quarkus.tls.protocols=TLSv1.3
quarkus.tls.handshake-timeout=10S # Default.
quarkus.tls.alpn=false
quarkus.tls.certificate-revocation-list=ca.crl, ca2.crl
quarkus.tls.trust-all=true
quarkus.tls.hostname-verification-algorithm=NONE
@Inject TlsConfigurationRegistry certificates; // TlsConfiguration def = certificates.getDefault().orElseThrow(); TlsConfiguration named = certificates.get("name").orElseThrow(); //
TlsCertificateBuildItem item = new TlsCertificateBuildItem("named", new MyCertificateSupplier());
public class MyCertificateSupplier implements Supplier<TlsConfiguration> { @Override public TlsConfiguration get() { try { KeyStore ks = KeyStore.getInstance("PKCS12"); ks.load(getClass().getResourceAsStream("target/certs/test-registration-keystore.p12"), "password".toCharArray()); KeyStore ts = KeyStore.getInstance("PKCS12"); ts.load(getClass().getResourceAsStream("target/certs/test-registration-truststore.p12"), "password".toCharArray()); return new BaseTlsConfiguration() { @Override public KeyStore getKeyStore() { return ks; } @Override public KeyStore getTrustStore() { return ts; } }; } catch (Exception e) { throw new RuntimeException(e); } } }
// in the class that performs the reload @Inject Event<CertificateUpdatedEvent> event; @Inject TlsConfigurationRegistry registry; public void reload() { TlsConfiguration config = registry.get("name").orElseThrow(); if (config.reload()) { event.fire(new CertificateUpdatedEvent("name", config)); } } // In the server or client code public void onReload(@Observes CertificateUpdatedEvent reload) { if ("name".equals(event.getName())) { server.updateSSLOptions(reload.tlsConfiguration().getSSLOptions()); // Or update the SSLContext. } }
quarkus.tls.reload-period=1h quarkus.tls.key-store.pem.0.cert=tls.crt quarkus.tls.key-store.pem.0.key=tls.key
quarkus.tls.http.reload-period=30min quarkus.tls.http.key-store.pem.0.cert=tls.crt quarkus.tls.http.key-store.pem.0.key=tls.key
apiVersion: v1 kind: Service metadata: labels: app.kubernetes.io/name: app.kubernetes.io/version: app.kubernetes.io/managed-by: quarkus name: hero-service spec: ports: - name: http port: 443 protocol: TCP targetPort: 8443 selector: app.kubernetes.io/name: app.kubernetes.io/version: type: ClusterIP
annotate service hero-service service.beta.openshift.io/serving-cert-secret-name=my-tls-secret
apiVersion: apps/v1 kind: Deployment metadata: labels: app.kubernetes.io/name: app.kubernetes.io/version: name: my-service spec: replicas: 1 selector: matchLabels: app.kubernetes.io/name: app.kubernetes.io/version: template: metadata: labels: app.kubernetes.io/name: app.kubernetes.io/version: spec: volumes: - name: my-tls-secret 1 secret: secretName: my-tls-secret containers: - env: - name: KUBERNETES_NAMESPACE valueFrom: fieldRef: fieldPath: metadata.namespace - name: QUARKUS_TLS_KEY_STORE_PEM_ACME_CERT 2 value: /etc/tls/tls.crt - name: QUARKUS_TLS_KEY_STORE_PEM_ACME_KEY value: /etc/tls/tls.key image: imagePullPolicy: Always name: my-service volumeMounts: 3 - name: my-tls-secret mountPath: /etc/tls readOnly: true ports: - containerPort: 8443 4 name: https protocol: TCP
apiVersion: v1 kind: ConfigMap metadata: name: client-tls-config annotations: service.beta.openshift.io/inject-cabundle: "true"
apiVersion: apps/v1 kind: Deployment metadata: name: my-service-client labels: app.kubernetes.io/name: app.kubernetes.io/version: spec: replicas: 1 selector: matchLabels: app.kubernetes.io/name: app.kubernetes.io/version: template: metadata: labels: app.kubernetes.io/name: app.kubernetes.io/version: spec: containers: - name: my-service-client image: ports: - name: http containerPort: 8080 protocol: TCP volumeMounts: 1 - name: my-client-volume mountPath: /deployments/tls volumes: 2 - name: my-client-volume configMap: name: client-tls-config
package org.acme; import jakarta.ws.rs.GET; import jakarta.ws.rs.Path; import org.eclipse.microprofile.rest.client.inject.RegisterRestClient; @RegisterRestClient(baseUri = "https://hero-service.cescoffi-dev.svc", configKey = "hero") 1 public interface HeroClient { record Hero (Long id, String name, String otherName, int level, String picture, String powers) { } @GET @Path("/api/heroes/random") Hero getRandomHero(); }
quarkus.rest-client.hero.tls-configuration-name=my-service-tls 1 quarkus.tls.my-service-tls.trust-store.pem.certs=/deployments/tls/service-ca.crt 2
quarkus.tls.reload-period=24h
> quarkus tls Install and Manage TLS development certificates Usage: tls [COMMAND] Commands: generate-quarkus-ca Generate Quarkus Dev CA certificate and private key. 1 generate-certificate Generate a TLS certificate with the Quarkus Dev CA if available. 2
quarkus tls generate-ca-certificate --install \ 1 --renew \ 2 --truststore 3
quarkus tls generate-certificate --name my-cert
Usage: tls generate-certificate [-hrV] [-c=<cn>] [-d=<directory>] -n=<name> [-p=<password>] Generate a TLS certificate with the Quarkus Dev CA if available. -c, --cn=<cn> The common name of the certificate. Default is 'localhost' -d, --directory=<directory> The directory in which the certificates will be created. Default is `.certs` -n, --name=<name> Name of the certificate. It will be used as file name and alias in the keystore -p, --password=<password> The password of the keystore. Default is 'password' -r, --renew Whether existing certificates will need to be replaced
./mvnw quarkus:dev INFO [io.quarkus] (Quarkus Main Thread) demo 1.0.0-SNAPSHOT on JVM (powered by Quarkus 999-SNAPSHOT) started in 1.286s. Listening on: http://localhost:8080 and https://localhost:8443
curl https://localhost:8443/hello Hello from Quarkus REST%
quarkus tls generate-certificate --name my-cert --self-signed
First, we need to identify the serial number of the CA certificate > certutil -store -user Root root "Trusted Root Certification Authorities" ================ Certificate 0 ================ Serial Number: 019036d564c8 Issuer: O=Quarkus, CN=quarkus-dev-root-ca # <-That's the CA, copy the Serial Number (the line above) NotBefore: 6/19/2024 11:07 AM NotAfter: 6/20/2025 11:07 AM Subject: C=Cloud, S=world, L=home, OU=Quarkus Dev, O=Quarkus Dev, CN=quarkus-dev-root-ca Signature matches Public Key Non-root Certificate uses same Public Key as Issuer Cert Hash(sha1): 3679bc95b613a2112a3d3256fe8321b6eccce720 No key provider information Cannot find the certificate and private key for decryption. CertUtil: -store command completed successfully.
> certutil -delstore -user -v Root USDSerial_Number
sudo rm /etc/pki/ca-trust/source/anchors/quarkus-dev-root-ca.pem sudo update-ca-trust
sudo rm /usr/local/share/ca-certificates/quarkus-dev-root-ca.pem sudo update-ca-certificates
sudo security -v remove-trusted-cert -d /Users/clement/.quarkus/quarkus-dev-root-ca.pem