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.
Before getting started, make sure you’re using the right Quarkus Helm version that is compatible with the Quarkus version you’re using in your project. See the following table to see the compatibility among versions:
Quarkus Cert-Manager Version | Quarkus Version |
---|---|
1.0.1 |
Quarkus 3+ |
1.0.0 |
Quarkus 3+ |
0.0.2 |
Quarkus 2.12+ |
0.0.1 |
Quarkus 2.12+ |
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:3.16.0: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>1.0.3</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:
name: http
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
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
Type |
Default |
|
---|---|---|
If enable/disable the Cert-Manager extension. Environment variable: |
boolean |
|
The name of the certificate resource to be generated. If not provided, it will use the default name for the application resources. Environment variable: |
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: |
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: |
string |
|
The lifetime of the Certificate. Environment variable: |
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: |
string |
|
The list of Subject Alternative Names. Environment variable: |
list of string |
|
The list of IP address subjectAltNames to be set on the Certificate. Environment variable: |
list of string |
|
The list of URI subjectAltNames to be set on the Certificate. Environment variable: |
list of string |
|
The list of email subjectAltNames to be set on the Certificate. Environment variable: |
list of string |
|
If true, it will mark this Certificate as valid for certificate signing. Environment variable: |
boolean |
|
The set of x509 usages that are requested for the certificate. Environment variable: |
list of string |
|
Environment variable: |
boolean |
|
Environment variable: |
string |
|
Environment variable: |
|
|
The reference to the issuer for this certificate This configuration section is optional |
Type |
Default |
The name of the resource being referred to. Environment variable: |
string |
required |
The kind of the resource being referred to. Environment variable: |
string |
|
The group of the resource being referred to. Environment variable: |
string |
|
The CA issuer configuration This configuration section is optional |
Type |
Default |
The name of the secret used to sign Certificates issued by this Issuer. Environment variable: |
string |
required |
The CRL distribution points is an X.509 v3 certificate extension which identifies the location of the CRL from which the revocation of this certificate can be checked. Environment variable: |
list of string |
|
The Vault issuer configuration This configuration section is optional |
Type |
Default |
The connection address for the Vault server, e.g: “https://vault.example.com:8200”. Environment variable: |
string |
required |
The mount path of the Vault PKI backend’s sign endpoint, e.g: “my_pki_mount/sign/my-role-name”. Environment variable: |
string |
required |
Environment variable: |
string |
|
The PEM-encoded CA bundle (base64-encoded) used to validate Vault server certificate. Environment variable: |
string |
required |
The reference where to retrieve the Vault token This configuration section is optional |
Type |
Default |
The name of the resource being referred to. Environment variable: |
string |
required |
The key of the entry in the Secret resource’s data field to be used. Environment variable: |
string |
required |
The Vault authentication using App Role auth mechanism This configuration section is optional |
Type |
Default |
The App Role authentication backend is mounted in Vault, e.g: “approle” Environment variable: |
string |
required |
The App Role authentication backend when setting up the authentication backend in Vault. Environment variable: |
string |
required |
The reference to a key in a Secret that contains the App Role secret used to authenticate with Vault This configuration section is optional |
Type |
Default |
The name of the resource being referred to. Environment variable: |
string |
required |
The key of the entry in the Secret resource’s data field to be used. Environment variable: |
string |
required |
The Vault authentication using Kubernetes service account This configuration section is optional |
Type |
Default |
The mount path to use when authenticating with Vault. Environment variable: |
string |
required |
The required Secret field containing a Kubernetes ServiceAccount JWT used for authenticating with Vault. Environment variable: |
string |
required |
The reference to a key in a Secret that contains the App Role secret used to authenticate with Vault This configuration section is optional |
Type |
Default |
The name of the resource being referred to. Environment variable: |
string |
required |
The key of the entry in the Secret resource’s data field to be used. Environment variable: |
string |
required |
The self-signed issuer configuration This configuration section is optional |
Type |
Default |
If the self-signed issuer should be generated. Environment variable: |
boolean |
|
The CRL distribution points is an X.509 v3 certificate extension which identifies the location of the CRL from which the revocation of this certificate can be checked. Environment variable: |
list of string |
|
Full X509 name specification (https://golang This configuration section is optional |
Type |
Default |
The organizations to be used on the Certificate. Environment variable: |
list of string |
|
The countries to be used on the Certificate. Environment variable: |
list of string |
|
The organizational Units to be used on the Certificate. Environment variable: |
list of string |
|
The cities to be used on the Certificate. Environment variable: |
list of string |
|
The State/Provinces to be used on the Certificate. Environment variable: |
list of string |
|
The street addresses to be used on the Certificate. Environment variable: |
list of string |
|
The postal codes to be used on the Certificate. Environment variable: |
list of string |
|
The serial number to be used on the Certificate. Environment variable: |
string |
|
The Keystores generation configuration This configuration section is optional |
Type |
Default |
JKS configures options for storing a JKS keystore in the spec This configuration section is optional |
Type |
Default |
Create enables keystore creation for the Certificate. Environment variable: |
boolean |
|
The name of the resource being referred to. Environment variable: |
string |
required |
The key of the entry in the Secret resource’s data field to be used. Environment variable: |
string |
required |
PKCS12 configures options for storing a PKCS12 keystore in the spec This configuration section is optional |
Type |
Default |
Create enables keystore creation for the Certificate. Environment variable: |
boolean |
|
The name of the resource being referred to. Environment variable: |
string |
required |
The key of the entry in the Secret resource’s data field to be used. Environment variable: |
string |
required |
#quarkus-certificate_quarkus.certificate.private-key This configuration section is optional |
Type |
Default |
RotationPolicy controls how private keys should be regenerated when a re-issuance is being processed. Environment variable: |
|
|
Environment variable: |
|
|
Environment variable: |
|
|
Environment variable: |
int |
|