Skip to main content
Redhat Developers  Logo
  • Products

    Platforms

    • Red Hat Enterprise Linux
      Red Hat Enterprise Linux Icon
    • Red Hat AI
      Red Hat AI
    • Red Hat OpenShift
      Openshift icon
    • Red Hat Ansible Automation Platform
      Ansible icon
    • View All Red Hat Products

    Featured

    • Red Hat build of OpenJDK
    • Red Hat Developer Hub
    • Red Hat JBoss Enterprise Application Platform
    • Red Hat OpenShift Dev Spaces
    • Red Hat OpenShift Local
    • Red Hat Developer Sandbox

      Try Red Hat products and technologies without setup or configuration fees for 30 days with this shared Openshift and Kubernetes cluster.
    • Try at no cost
  • Technologies

    Featured

    • AI/ML
      AI/ML Icon
    • Linux
      Linux Icon
    • Kubernetes
      Cloud icon
    • Automation
      Automation Icon showing arrows moving in a circle around a gear
    • View All Technologies
    • Programming Languages & Frameworks

      • Java
      • Python
      • JavaScript
    • System Design & Architecture

      • Red Hat architecture and design patterns
      • Microservices
      • Event-Driven Architecture
      • Databases
    • Developer Productivity

      • Developer productivity
      • Developer Tools
      • GitOps
    • Automated Data Processing

      • AI/ML
      • Data Science
      • Apache Kafka on Kubernetes
    • Platform Engineering

      • DevOps
      • DevSecOps
      • Ansible automation for applications and services
    • Secure Development & Architectures

      • Security
      • Secure coding
  • Learn

    Featured

    • Kubernetes & Cloud Native
      Openshift icon
    • Linux
      Rhel icon
    • Automation
      Ansible cloud icon
    • AI/ML
      AI/ML Icon
    • View All Learning Resources

    E-Books

    • GitOps Cookbook
    • Podman in Action
    • Kubernetes Operators
    • The Path to GitOps
    • View All E-books

    Cheat Sheets

    • Linux Commands
    • Bash Commands
    • Git
    • systemd Commands
    • View All Cheat Sheets

    Documentation

    • Product Documentation
    • API Catalog
    • Legacy Documentation
  • Developer Sandbox

    Developer Sandbox

    • Access Red Hat’s products and technologies without setup or configuration, and start developing quicker than ever before with our new, no-cost sandbox environments.
    • Explore Developer Sandbox

    Featured Developer Sandbox activities

    • Get started with your Developer Sandbox
    • OpenShift virtualization and application modernization using the Developer Sandbox
    • Explore all Developer Sandbox activities

    Ready to start developing apps?

    • Try at no cost
  • Blog
  • Events
  • Videos

Automatic certificate provisioning with cert-manager and DNS challenge

Automatically acquire and renew certificates using the cert-manager operator for Red Hat OpenShift and Automated Certificate Management Environment (ACME)

August 1, 2025
Josep Andreu Font Ramon Gordillo Gutierrez
Related topics:
Automation and managementKubernetesOperators
Related products:
Red Hat Enterprise LinuxRed Hat OpenShiftRed Hat OpenShift Container Platform

Share:

    This article describes how to use the cert-manager operator for Red Hat OpenShift to automatically provide and renew certificates to OpenShift applications. This approach uses the Automated Certificate Management Environment (ACME) feature provided by Identity Management (IdM) with DNS challenge.

    This post follows a series of previous articles covering this feature:

    • Managing Automatic Certificate Management Environment (ACME) in Identity Management (IdM) introduces the ACME feature and describes its setup.
    • Automatically acquire and renew certificates using mod_md and Automated Certificate Management Environment (ACME) in Identity Management (IdM) covers how to use this feature with the mod_md client.
    • Automatic certificate issuing with IdM and cert-manager operator for OpenShift explains how to configure the http-01 challenge using an Ingress Controller to expose the deployed web application.

    This article provides an alternative to the previous article for those that use IdM as their DNS server. We will implement a DNS challenge to confirm domain authority for certificate requests.

    The ACME advantage

    As the previous articles demonstrate, the manual management of certificates that most companies currently perform has several limitations and introduces inefficiencies. This tedious process of monitoring and tracking certificate lifecycles requires significant time and effort, is prone to human error, and can lead to painful outages.

    In that sense, the ACME protocol, which was created by the Internet Research Security Group (ISRG) and its Certificate Authority (CA) Let’s Encrypt, is designed to solve all these challenges by removing the need for human interaction.

    Environment

    Our environment will consist of a Red Hat Enterprise Linux (RHEL) 10 IdM server and an OpenShift 4.14 cluster (though any newer version will also work for this solution). 

    It is important to note that RHEL 10 is the first release that provides the ACME feature as Generally Available (GA), so it is considered fully supported. As we saw in the first article, a key prerequisite is the automatic removal of expired certificates. RHEL 9 and older releases require explicit enablement with several limitations, which is why they do not support this feature. In RHEL 10, this is enabled by default on new installations.

    Additionally, RHEL 10 implements by default random serial numbers (RSNv3) in Dogtag CA. As a result, any new certificate issued by RHEL 10 IdM Dogtag CA has a random serial number and a default retention period of 30 days following the expiry date, after which the certificate will be automatically removed.

    First, we will install the IdM server in our RHEL 10 server with hostname idm.melmac.univ. For this, we will install the packages and then perform the installation:

    root@idm:~# dnf install ipa-server ipa-server-dns bind-dyndb-ldap

    For the installation, you do not need to specify the random serial numbers option (as in RHEL 9) because it’s selected by default:

    root@idm:~# ipa-server-install --ds-password=<ds_pass> --admin-password=<admin_pass> --setup-dns --auto-reverse 

    Accept all the options provided by default. After the installation has finished, execute:

    root@idm:~# firewall-cmd --add-service freeipa-ldap
    root@idm:~# firewall-cmd --add-service freeipa-ldaps
    root@idm:~# firewall-cmd --add-service dns
    root@idm:~# firewall-cmd --runtime-to-permanent

    Next, enable the ACME feature (it is disabled by default) with:

    root@idm:~# ipa-acme-manage enable
    The ipa-acme-manage command was successful

    Check the result with:

    root@idm:~# ipa-acme-manage status
    ACME is enabled
    The ipa-acme-manage command was successful

    In the IdM web UI (Figure 1), you’ll see all is ready to start providing certificates with RSNv3.

    The Red Hat Identity Management web UI showing the enabled Certificate Authority (CA) with support for RSNv3. The UI displays "CA is configured" and "All is ready to start providing certificates with RSNv3."
    Figure 1: IdM UI displays random serial number certificates.

    Next, we will focus on the cert-manager operator in our OpenShift 4.14 cluster. For the installation, navigate to Operators → OperatorHub, shown in Figure 2.

    The OpenShift 4.14 console, showing the left-hand navigation menu with "Operators" expanded and "OperatorHub" highlighted. The main content area displays the "OperatorHub" interface with various available operators.
    Figure 2: OpenShift web UI OperatorHub.

    As illustrated in Figure 2, there are two operators: one community upstream (ideal for pure vanilla Kubernetes clusters) and the cert-manager operator provided and curated by Red Hat. The latter is the one we will install. 

    Proceed with the installation using all default options (Figure 3).

    The OpenShift web console showing the "Install Operator" page for the cert-manager Operator. The default installation options are selected, and the "Install" button is visible at the bottom of the page.
    Figure 3: cert-manager operator installation.

    Wait for the installation to finish. Your base environment setup is now complete.

    Provide and enable dynamic updates to DNS zones

    To provide dynamic updates to the DNS zone in IdM, we need to authenticate as an approved nameserver or approved client. To accomplish that, IdM with Kerberos uses the standard TSIG (transaction signature) protocol, but given that programs do not typically use Kerberos for these tasks, we will choose another algorithm. Here, we select hmac-sha512.

    To create the key, execute the following:

    root@idm:~# tsig-keygen -a hmac-sha512 update | tee -a /etc/named/ipa-ext.conf

    This command appends a key with the name update to the named .conf file, /etc/named/ipa-ext.conf (this file is not modified during IdM upgrades). 

    Now we have to update the IdM named server and verify the update key loads effectively. Execute the following command:

    root@idm:~# rndc reconfig
    root@idm:~# rndc tsig-list |grep bind |grep update

    The last command should return the following:

    view "_bind"; type "static"; key "update";

    The last step is to modify the update policy of our DNS domain. First, we need to obtain a Kerberos ticket. Execute the following to enable updates in our DNS domain zone:

    root@idm:~# echo <admin_pass> | kinit admin
    root@idm:~# ipa dnszone-mod melmac.univ --update-policy='grant <MYDOMAIN.COM> krb5-self * A; grant <MYDOMAIN.COM> krb5-self * AAAA; grant <MYDOMAIN.COM> krb5-self * SSHFP; grant update subdomain <mydomain.com> TXT;'

    Substitute <MYDOMAIN.COM> with your domain in uppercase (in my case, MELMAC.UNIV) and <mydomain.com> with the same corresponding domain, but in lowercase. This grants the updates to our domain.

    You can check it and observe how the policy is updated. For our environment:

    root@idm:~# ipa dnszone-show melmac.univ
      Zone name: melmac.univ.
      Active zone: True
      Authoritative nameserver: idm.melmac.univ.
      Administrator e-mail address: hostmaster.melmac.univ.
      SOA serial: 1751873655
      SOA refresh: 3600
      SOA retry: 900
      SOA expire: 1209600
      SOA minimum: 3600
      BIND update policy: grant MELMAC.UNIV krb5-self * A; grant MELMAC.UNIV krb5-self * AAAA; grant MELMAC.UNIV krb5-self * SSHFP; grant update subdomain melmac.univ TXT;
      Dynamic update: True
      Allow query: any;
      Allow transfer: none;

    Now we can test the ACME server to get certificates.

    Trusting IdM CA

    To enable security in the communication between our ClusterIssuer resource in OpenShift Container Platform and IdM, we need to add the ca.crt from the IdM to the trusted CA list that cert-manager uses. 

    To do this, we will create a new ConfigMap in OpenShift Container Platform that contains the certificate located in the path /etc/ipa/ca.crt in IdM. Execute the following:

    [azure@bastion-76dv5 ~]$ oc create configmap custom-ca --from-file=ca-bundle.crt=./ca.crt -n openshift-config
    [azure@bastion-76dv5 ~]$ oc patch proxy/cluster --type=merge --patch='{"spec":{"trustedCA":{"name":"custom-ca"}}}'
    [azure@bastion-76dv5 ~]$ oc create configmap trusted-ca -n cert-manager
    [azure@bastion-76dv5 ~]$ oc label cm trusted-ca config.openshift.io/inject-trusted-cabundle=true -n cert-manager
    [azure@bastion-76dv5 ~]$ oc -n cert-manager-operator patch subscription openshift-cert-manager-operator --type='merge' -p '{"spec":{"config":{"env":[{"name":"TRUSTED_CA_CONFIGMAP_NAME","value":"trusted-ca"}]}}}'

    After that, roll out the cert-manager operator and all the cert-manager Deployments:

    [azure@bastion-76dv5 ~]$ oc rollout status deployment/cert-manager-operator-controller-manager -n cert-manager-operator
    [azure@bastion-76dv5 ~]$ oc rollout status deployment/cert-manager -n cert-manager
    [azure@bastion-76dv5 ~]$ oc rollout status deployment/cert-manager-webhook -n cert-manager
    [azure@bastion-76dv5 ~]$ oc rollout status deployment/cert-manager-cainjector -n cert-manager

    The most effective way to verify this is to inspect the certificates in the bundle imported into your cert-manager pods. Your IdM CA certificate must be in the first position:

    [azure@bastion-9psbk ~]$ oc get pods -n cert-manager
    NAME                                       READY   STATUS    RESTARTS   AGE
    cert-manager-647f56c54b-4ns5m              1/1     Running   0          15m
    cert-manager-cainjector-7b95fc9574-ngxm2   1/1     Running   0          15m
    cert-manager-webhook-5c68bc69bb-sptkl      1/1     Running   0          15m
    [azure@bastion-9psbk ~]$ oc exec -it cert-manager-647f56c54b-4ns5m -n cert-manager -- cat /etc/pki/tls/certs/cert-manager-tls-ca-bundle.crt

    Now that you trust the IdM CA, you can securely create your ClusterIssuer resource.

    Using cert-manager operator to acquire certificates

    The cert-manager is a very popular operator in Kubernetes world to provide certificates to workloads and Ingress controllers. 

    To enable ACME with DNS01 challenge, we need to configure an Issuer (in our case, a ClusterIssuer, due to the required cluster scope and its ability to be referenced by certificates in every namespace). For that, we need to add the previously created TSIG key to a Secret (which we will reference in our ClusterIssuer) in the cert-manager project, as illustrated in Figure 4.

    The OpenShift web console showing the process of creating a Secret within the cert-manager project. The "Create Secret" form is displayed, with fields for secret name, type, and data, where a TSIG key will be added.
    Figure 4: Creating a Secret in the OpenShift web UI.

    The ClusterIssuer resource in the OpenShift cluster is under the rfc2136 element and should look like this:

    apiVersion: cert-manager.io/v1
    kind: ClusterIssuer
    metadata:
      name: acme-issuer
      namespace: cert-manager
    spec:
      acme:
        email: admin@melmac.univ
        server: https://idm.melmac.univ/acme/directory
        privateKeySecretRef:
          name: acme-issuer-key
        solvers:
        - dns01:
            rfc2136:
              nameserver: idm.melmac.univ:53
              tsigKeyName: update
              tsigAlgorithm: HMACSHA512
              tsigSecretSecretRef:
                name: tsig-secret
                key: tsig-secret-key

    After performing an oc apply of the previous YAML file, you will see the following upon successful completion:

    [azure@bastion-76dv5 ~]$ oc get clusterissuer -n cert-manager
    NAME          READY   AGE
    acme-issuer   True    10s

    If you query the ClusterIssuer object by executing oc describe, you will obtain the following Status section:

    Status:
      Acme:
        Last Private Key Hash:  nL9MRT1L0e4dfEWXdt9sccC8UcoYoDQ5HKSPTHlnRcY=
        Last Registered Email:  admin@melmac.univ
        Uri:                    https://idm.melmac.univ/acme/v1/acct/DB21KAMgHWeWaC__4TyK56Uii7ZhSFrf9hfB-KA2JLo
      Conditions:
        Last Transition Time:  2025-07-03T10:36:30Z
        Message:               The ACME account was registered with the ACME server
        Observed Generation:   1
        Reason:                ACMEAccountRegistered
        Status:                True
        Type:                  Ready
    Events:                    <none>

    Next, acquire a new certificate against your recently created ClusterIssuer object for the application myapplication5.melmac.univ. To do this, create a Certificate object with the following:

    apiVersion: cert-manager.io/v1
    kind: Certificate
    metadata:
      name: www5
      namespace: cert-manager
    spec:
      secretName: www5
      duration: 2160h # 90d
      renewBefore: 360h # 15d
      subject:
        organizations:
          - MyOrg
      commonName: myapplication5.melmac.univ
      privateKey:
        algorithm: RSA
        encoding: PKCS1
        size: 2048
        rotationPolicy: Always
      usages:
        - server auth
        - client auth
      dnsNames:
        - myapplication5.melmac.univ
      issuerRef:
        name: acme-issuer
        kind: ClusterIssuer

    Regarding the previous YAML code, note that the duration: 2160h field sets the certificate validity to 3 months, aligning with Let's Encrypt and the default Dogtag CA configuration. But the ACME profile in Dogtag CA ultimately dictates this duration.

    To change the ACME profile lifetime of certificates, refer to the Certificates Lifecycle section in the blog Automatic certificate issuing with IdM and cert-manager operator for OpenShift. This configuration applies to both RHEL 9 and RHEL 10.

    After applying that YAML file, a Secret resource will be created containing the tls.key and tls.crt fields with the corresponding base64-encoded key and certificate values issued by Dogtag CA. First, tls.key will create almost immediately, and after a few seconds, tls.crt will issue and insert into the Secret:

    [azure@bastion-9psbk ~]$ oc get secret -n cert-manager
    [...]
    www5-65k5f                                Opaque                                1      3s
    [azure@bastion-9psbk ~]$ oc get secret -n cert-manager
    [...]
    www5                                      kubernetes.io/tls                     2      3s
    [azure@bastion-9psbk ~]$ oc describe secret www5 -n cert-manager
    Name:         www5
    Namespace:    cert-manager
    Labels:       controller.cert-manager.io/fao=true
    Annotations:  cert-manager.io/alt-names: myapplication5.melmac.univ
                  cert-manager.io/certificate-name: www5
                  cert-manager.io/common-name: myapplication5.melmac.univ
                  cert-manager.io/ip-sans: 
                  cert-manager.io/issuer-group: 
                  cert-manager.io/issuer-kind: ClusterIssuer
                  cert-manager.io/issuer-name: acme-issuer
                  cert-manager.io/uri-sans: 
     
    Type:  kubernetes.io/tls
     
    Data
    ====
    tls.crt:  3270 bytes
    tls.key:  1679 bytes

    To troubleshoot any incorrect behavior, you can check the logs of the cert-manager pod in the cert-manager project. A successful certificate acquisition or renewal will show the following:

    [azure@bastion-9psbk ~]$ oc logs -n cert-manager cert-manager-647f56c54b-4ns5m
    [...]
    I0704 08:48:43.631810       1 dns.go:90] "presenting DNS01 challenge for domain" logger="cert-manager.controller.Present" resource_name="www5-1-1869734104-2702398043" resource_namespace="cert-manager" resource_kind="Challenge" resource_version="v1" dnsName="myapplication5.melmac.univ" type="DNS-01" resource_name="www5-1-1869734104-2702398043" resource_namespace="cert-manager" resource_kind="Challenge" resource_version="v1" domain="myapplication5.melmac.univ"
    I0704 08:49:45.199661       1 acme.go:236] "certificate issued" logger="cert-manager.controller.sign" resource_name="www5-1" resource_namespace="cert-manager" resource_kind="CertificateRequest" resource_version="v1" related_resource_name="www5-1-1869734104" related_resource_namespace="cert-manager" related_resource_kind="Order" related_resource_version="v1"
    I0704 08:49:45.199810       1 conditions.go:252] Found status change for CertificateRequest "www5-1" condition "Ready": "False" -> "True"; setting lastTransitionTime to 2025-07-04 08:49:45.199781171 +0000 UTC m=+1601.571130576
    I0704 08:49:45.238131       1 conditions.go:192] Found status change for Certificate "www5" condition "Ready": "False" -> "True"; setting lastTransitionTime to 2025-07-04 08:49:45.238119612 +0000 UTC m=+1601.609469017

    Finally, note the renewBefore parameter of the previous YAML code. This refers to the time relative to the not After field of the issued certificate when the client will attempt renewal. It is a customizable and optional parameter that defaults to two-thirds of the current certificate’s validity period. 

    Before tls.crt expires, your IdM Dogtag CA will automatically re-issue a new certificate with the same characteristics as the old one. It will insert the new tls.key and tls.crt values into the same Secret, thus providing a completely renewed certificate automatically.

    Conclusion

    This article demonstrated how to use the IdM ACME feature with the cert-manager operator using the DNS challenge. This is an effective and scalable way to provide certificates automatically to your applications deployed on an OpenShift Container Platform cluster. 

    Because IdM is included in your Red Hat Enterprise Linux subscription, you can try to replicate this content in your lab environment without any additional subscriptions to set up your own ACME environment. An additional OpenShift subscription is needed to set up the OpenShift Container Platform cluster. 

    If you are not already a RHEL subscriber, get a no-cost trial from Red Hat.

    Related Posts

    • Automatic certificate issuing with IdM and cert-manager operator for OpenShift

    • Integrate OpenShift Service Mesh with cert-manager and Vault

    • Secure Kubernetes certificates with cert-manager and Dekorate

    • X.509 user certificate authentication with Red Hat's single sign-on technology

    • Set up Red Hat AMQ Streams custom certificates on OpenShift (update)

    • How OpenShift cert-manager simplifies cluster certificates

    Recent Posts

    • Kubernetes MCP server: AI-powered cluster management

    • Unlocking the power of OpenShift Service Mesh 3

    • Run DialoGPT-small on OpenShift AI for internal model testing

    • Skopeo: The unsung hero of Linux container-tools

    • Automate certificate management in OpenShift

    What’s up next?

    Learn efficient certificate management techniques on Red Hat OpenShift using the cert-manager Operator for OpenShift’s multi-architecture support.

    Start learning
    Red Hat Developers logo LinkedIn YouTube Twitter Facebook

    Platforms

    • Red Hat AI
    • Red Hat Enterprise Linux
    • Red Hat OpenShift
    • Red Hat Ansible Automation Platform
    • See all products

    Build

    • Developer Sandbox
    • Developer Tools
    • Interactive Tutorials
    • API Catalog

    Quicklinks

    • Learning Resources
    • E-books
    • Cheat Sheets
    • Blog
    • Events
    • Newsletter

    Communicate

    • About us
    • Contact sales
    • Find a partner
    • Report a website issue
    • Site Status Dashboard
    • Report a security problem

    RED HAT DEVELOPER

    Build here. Go anywhere.

    We serve the builders. The problem solvers who create careers with code.

    Join us if you’re a developer, software engineer, web designer, front-end designer, UX designer, computer scientist, architect, tester, product manager, project manager or team lead.

    Sign me up

    Red Hat legal and privacy links

    • About Red Hat
    • Jobs
    • Events
    • Locations
    • Contact Red Hat
    • Red Hat Blog
    • Inclusion at Red Hat
    • Cool Stuff Store
    • Red Hat Summit
    © 2025 Red Hat

    Red Hat legal and privacy links

    • Privacy statement
    • Terms of use
    • All policies and guidelines
    • Digital accessibility

    Report a website issue