Using Quarkus Cert-Manager

The Quarkus Cert-Manager extension supports generating an X.509 certificate with the help of the Certificate and Issuer CRD resources handled by the Cert-Manager. When these CRD resources are deployed on the cluster, the Cert-Manager will process them to populate a Secret containing for example a: CA certificate, private key, server certificate, or java keystores, etc.

Under the hood, this extension uses Dekorate to generate all the Cert-Manager manifests at build time.

Create a Quarkus application with the Cert-Manager extension

In this example, we’ll create a Quarkus application with the Quarkus Cert-Manager and the Quarkus Kubernetes extensions by running the following command:

mvn io.quarkus.platform:quarkus-maven-plugin:2.13.0.Final:create \
    -DprojectGroupId=org.acme \
    -DprojectArtifactId=certmanager-quickstart \
    -DclassName="org.acme.quickstart.GreetingResource" \
    -Dpath="/hello" \
    -Dextensions="resteasy-reactive,kubernetes,certmanager"
cd certmanager-quickstart

If you already have your Quarkus project configured, you can add the certmanager extension to your project by running the following command in your project base directory:

./mvnw quarkus:add-extension -Dextensions="certmanager"

This command will add the following dependency to your pom.xml file:

<dependency>
    <groupId>io.quarkiverse.certmanager</groupId>
    <artifactId>quarkus-certmanager</artifactId>
    <version>0.0.2</version>
</dependency>

Once we add the Quarkus Cert-Manager extension to your project, you can now generate the resources by running the following Maven command:

./mvnw clean package

And next, we need to provide the certificate configuration. The minimal information that the extension needs is: * secretName: the name of the Kubernetes Secret resource that will include the Cert-Manager generated files. * the Issuer that represents the certificate authority (CA). See all the supported options in the Issuer section.

For all the configuration options, please go to the Configuration guide.

The minimal configuration can be provided using the properties file and the following keys:

quarkus.certificate.secret-name=tls-secret
# The selfSigned issuer:
quarkus.certificate.self-signed.enabled=true

This configuration will generate up to two resources under the target/kubernetes/kubernetes.yml file that should look like this:

apiVersion: cert-manager.io/v1
kind: Issuer
metadata:
  name: kubernetes-example
spec:
  selfSigned: {}
---
apiVersion: cert-manager.io/v1
kind: Certificate
metadata:
  name: kubernetes-example
spec:
  encodeUsagesInRequest: false
  isCA: false
  issuerRef:
    name: kubernetes-example
  secretName: tls-secret

The Quarkus Cert-Manager extension will add, part of the Deployment, a volume mounted from the secret that contains the Cert-Manager generated files to allow the application to access them and to configure the HTTPS/TLS endpoint:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: kubernetes-example
spec:
  replicas: 1
  template:
    spec:
      containers:
        - name: kubernetes-example
          volumeMounts:
            - mountPath: /etc/certs
              name: volume-certs
              readOnly: true
      volumes:
        - name: volume-certs
          secret:
            optional: false
            secretName: tls-secret

Moreover, the Quarkus Cert-Manager extension will also autoconfigure the application to accept SSL connections. By default, it will autoconfigure only the Ingress/Route resource if exposed, otherwise, it will enable the HTTPS/TLS configuration for the internal communications of the application. This configuration can be controlled using the property quarkus.certificate.autoconfigure which values:

  • (Default) AUTOMATIC: It will secure Ingress/Route resources if exposed, otherwise the HTTP endpoints.

  • NONE: It won’t autoconfigure anything.

  • ALL: It will secure the HTTP endpoints and also the Ingress/Route resources if exposed.

  • HTTPS_ONLY: It will secure only the HTTP endpoints.

  • CLUSTER_ONLY: It will secure only the Ingress/Route resources. It will throw an exception if it was not exposed.

For example, if you want to secure both the internal HTTPs connections and the ingress resource by setting the property quarkus.certificate.autoconfigure=ALL, it will update the Ingress resource as follows if the property quarkus.kubernetes.ingress.expose is true:

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  ...
spec:
  rules:
    ...
  tls:
    - hosts:
        - kubernetes-example.com
        - localhost
      secretName: tls-secret

And it will also autoconfigure the HTTP SSL configuration part of the Deployment resource:

apiVersion: apps/v1
kind: Deployment
metadata:
  ...
  name: quarkus-certmanager-integration-tests-certmanager-ssl
spec:
  replicas: 1
  selector:
    ...
  template:
    ...
    spec:
      containers:
        - env:
            - name: KUBERNETES_NAMESPACE
              valueFrom:
                fieldRef:
                  fieldPath: metadata.namespace
            - name: QUARKUS_HTTP_SSL_CERTIFICATE_KEY_STORE_FILE_TYPE
              value: PKCS12
            - name: QUARKUS_HTTP_SSL_CERTIFICATE_KEY_STORE_PASSWORD
              valueFrom:
                secretKeyRef:
                  key: password
                  name: pkcs12-pass
            - name: QUARKUS_HTTP_SSL_CERTIFICATE_KEY_STORE_FILE
              value: /etc/certs/keystore.p12

Securing Resources

When securing your resources, it’s important to validate that the requests are coming from known host names. For this purpose, we can use the dnsNames property which is part of the certificate configuration. For example, by adding the following quarkus.certificate.dns-names property (it’s a comma separated list of strings):

quarkus.certificate.dns-names=foo.bar.com

The certificate will only allow requests accessing the server host foo.bar.com. Remark: If the DNS Host name does not exist, then you will get an error.

Note that the applications in Kubernetes can be publicly exposed using Ingress resources, for example:

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: kubernetes-example
spec:
  rules:
  - host: foo.bar.com
    http:
      paths:
      - pathType: Prefix
        path: "/"
        backend:
          service:
            name: kubernetes-example
            port:
              number: 8080
  tls:
    - hosts:
        - foo.bar.com
      secretName: tls-secret # < cert-manager will store the created certificate in this secret.

Issuers

The Issuer is a Kubernetes resource that represents a certificate issuing authority that can generate signed certificates by honoring certificate signing requests. All cert-manager certificates require a referenced issuer to attempt to honor the request.

The supported issuers of this extension are SelfSigned, CA, Vault, and IssuerRef.

Only one issuer must be set between selfSigned, ca, vault, and issuerRef.

SelfSigned

Using the SelfSigned issuer, the certificate will sign itself using the given private key. To use the SelfSigned issuer, you need to add the following key property:

quarkus.certificate.self-signed.enabled=true

CA

Using the CA issuer, the certificate and private key are stored inside the cluster as a Kubernetes Secret and will be used to sign incoming certificate requests. To use the CA issuer, you need to add the following key properties:

quarkus.certificate.ca.secret-name=ca-key-pair

When this certificate is installed in the cluster, Cert-Manager will issue the certificate and generate the CA secret resource ca-key-pair which the following content:

apiVersion: v1
kind: Secret
metadata:
  name: ca-key-pair
data:
  tls.crt: <auto generated encrypted data>
  tls.key: <auto generated encrypted data>

Vault

Using the Vault issuer, the certificate will be issued by the certificate authority Vault. To use the Vault issuer, you need the following key properties:

quarkus.certificate.vault.server=https://vault.example.com:8200
quarkus.certificate.vault.path=my_pki_mount/sign/my-role-name
# Any of the auth mechanisms to login into Vault:
## 1.- Via token secret resource reference:
quarkus.certificate.vault.auth-token-secret-ref...
## 2.- Via using Application Role:
quarkus.certificate.vault.auth-app-role...
## 3.- Via using Kubernetes service account:
quarkus.certificate.vault.auth-kubernetes...

Using a pre-existing issuer

To use a pre-existing issuer type that is separately installed in the cluster, you can use the issuerRef type. For example:

quarkus.certificate.issuer-ref.name=my-issuer
quarkus.certificate.issuer-ref.kind=ClusterIssuer

In this example, we are using a ClusterIssuer resource that is part of the Cert-Manager API and that should have previously been installed in the cluster.

Configuration Reference

Configuration property fixed at build time - All other configuration properties are overridable at runtime

Configuration property

Type

Default

The name of the certificate resource to be generated. If not provided, it will use the default name for the application resources.

Environment variable: QUARKUS_CERTIFICATE_NAME

string

SecretName is the name of the secret resource that will be automatically created and managed by this Certificate resource. It will be populated with a private key and certificate, signed by the denoted issuer.

Environment variable: QUARKUS_CERTIFICATE_SECRET_NAME

string

required

CommonName is a common name to be used on the Certificate. The CommonName should have a length of 64 characters or fewer to avoid generating invalid CSRs.

Environment variable: QUARKUS_CERTIFICATE_COMMON_NAME

string

The lifetime of the Certificate.

Environment variable: QUARKUS_CERTIFICATE_DURATION

string

How long before the currently issued certificate’s expiry cert-manager should renew the certificate. The default is 2⁄3 of the issued certificate’s duration.

Environment variable: QUARKUS_CERTIFICATE_RENEW_BEFORE

string

Environment variable: QUARKUS_CERTIFICATE_DNS_NAMES

list of string

The list of IP address subjectAltNames to be set on the Certificate.

Environment variable: QUARKUS_CERTIFICATE_IP_ADDRESSES

list of string

The list of URI subjectAltNames to be set on the Certificate.

Environment variable: QUARKUS_CERTIFICATE_URIS

list of string

The list of email subjectAltNames to be set on the Certificate.

Environment variable: QUARKUS_CERTIFICATE_EMAIL_ADDRESSES

list of string

If true, it will mark this Certificate as valid for certificate signing.

Environment variable: QUARKUS_CERTIFICATE_IS_CA

boolean

The set of x509 usages that are requested for the certificate.

Environment variable: QUARKUS_CERTIFICATE_USAGES

list of string

Environment variable: QUARKUS_CERTIFICATE_ENCODE_USAGES_IN_REQUEST

boolean

false

Environment variable: QUARKUS_CERTIFICATE_VOLUME_MOUNT_PATH

string

/etc/certs

Environment variable: QUARKUS_CERTIFICATE_AUTOCONFIGURE

none, automatic, all, https-only, cluster-only

automatic

The reference to the issuer for this certificate This configuration section is optional

Type

Default

Environment variable: QUARKUS_CERTIFICATE_ISSUER_REF_NAME

string

required

Environment variable: QUARKUS_CERTIFICATE_ISSUER_REF_KIND

string

Environment variable: QUARKUS_CERTIFICATE_ISSUER_REF_GROUP

string

The CA issuer configuration This configuration section is optional

Type

Default

Environment variable: QUARKUS_CERTIFICATE_CA_SECRET_NAME

string

required

Environment variable: QUARKUS_CERTIFICATE_CA_CRL_DISTRIBUTION_POINTS

list of string

The Vault issuer configuration This configuration section is optional

Type

Default

Environment variable: QUARKUS_CERTIFICATE_VAULT_SERVER

string

required

Environment variable: QUARKUS_CERTIFICATE_VAULT_PATH

string

required

Environment variable: QUARKUS_CERTIFICATE_VAULT_NAMESPACE

string

Environment variable: QUARKUS_CERTIFICATE_VAULT_CA_BUNDLE

string

required

#quarkus-certificate_quarkus.certificate.vault.auth-token-secret-ref This configuration section is optional

Type

Default

Environment variable: QUARKUS_CERTIFICATE_VAULT_AUTH_TOKEN_SECRET_REF_NAME

string

required

Environment variable: QUARKUS_CERTIFICATE_VAULT_AUTH_TOKEN_SECRET_REF_KEY

string

required

Environment variable: QUARKUS_CERTIFICATE_VAULT_AUTH_APP_ROLE_PATH

string

required

Environment variable: QUARKUS_CERTIFICATE_VAULT_AUTH_APP_ROLE_ROLE_ID

string

required

Environment variable: QUARKUS_CERTIFICATE_VAULT_AUTH_KUBERNETES_MOUNT_PATH

string

required

Environment variable: QUARKUS_CERTIFICATE_VAULT_AUTH_KUBERNETES_ROLE

string

required

Environment variable: QUARKUS_CERTIFICATE_PRIVATE_KEY_ROTATION_POLICY

unset, never, always

unset

Environment variable: QUARKUS_CERTIFICATE_PRIVATE_KEY_ENCODING

unset, pkcs1, pkcs8

unset

Environment variable: QUARKUS_CERTIFICATE_PRIVATE_KEY_ALGORITHM

unset, rsa, ed25519, ecdsa

unset

Environment variable: QUARKUS_CERTIFICATE_PRIVATE_KEY_SIZE

int

-1

#quarkus-certificate_quarkus.certificate.vault.auth-app-role.secret-ref This configuration section is optional

Type

Default

Environment variable: QUARKUS_CERTIFICATE_VAULT_AUTH_APP_ROLE_SECRET_REF_NAME

string

required

Environment variable: QUARKUS_CERTIFICATE_VAULT_AUTH_APP_ROLE_SECRET_REF_KEY

string

required

Environment variable: QUARKUS_CERTIFICATE_VAULT_AUTH_KUBERNETES_SECRET_REF_NAME

string

required

Environment variable: QUARKUS_CERTIFICATE_VAULT_AUTH_KUBERNETES_SECRET_REF_KEY

string

required

The self-signed issuer configuration This configuration section is optional

Type

Default

Environment variable: QUARKUS_CERTIFICATE_SELF_SIGNED_ENABLED

boolean

false

Environment variable: QUARKUS_CERTIFICATE_SELF_SIGNED_CRL_DISTRIBUTION_POINTS

list of string

Full X509 name specification (https://golang This configuration section is optional

Type

Default

Environment variable: QUARKUS_CERTIFICATE_SUBJECT_ORGANIZATIONS

list of string

Environment variable: QUARKUS_CERTIFICATE_SUBJECT_COUNTRIES

list of string

Environment variable: QUARKUS_CERTIFICATE_SUBJECT_ORGANIZATIONAL_UNITS

list of string

Environment variable: QUARKUS_CERTIFICATE_SUBJECT_LOCALITIES

list of string

Environment variable: QUARKUS_CERTIFICATE_SUBJECT_PROVINCES

list of string

Environment variable: QUARKUS_CERTIFICATE_SUBJECT_STREET_ADDRESSES

list of string

Environment variable: QUARKUS_CERTIFICATE_SUBJECT_POSTAL_CODES

list of string

Environment variable: QUARKUS_CERTIFICATE_SUBJECT_SERIAL_NUMBER

string

The Keystores generation configuration This configuration section is optional

Type

Default

#quarkus-certificate_quarkus.certificate.keystores.jks This configuration section is optional

Type

Default

Environment variable: QUARKUS_CERTIFICATE_KEYSTORES_JKS_CREATE

boolean

false

Environment variable: QUARKUS_CERTIFICATE_KEYSTORES_JKS_PASSWORD_SECRET_REF_NAME

string

required

Environment variable: QUARKUS_CERTIFICATE_KEYSTORES_JKS_PASSWORD_SECRET_REF_KEY

string

required

Environment variable: QUARKUS_CERTIFICATE_KEYSTORES_PKCS12_CREATE

boolean

false

Environment variable: QUARKUS_CERTIFICATE_KEYSTORES_PKCS12_PASSWORD_SECRET_REF_NAME

string

required

Environment variable: QUARKUS_CERTIFICATE_KEYSTORES_PKCS12_PASSWORD_SECRET_REF_KEY

string

required

References