Learn how to set up EJBCA to issue certificates with the cert-manager using the EJBCA cert-manager external issuer.

cert-manager is an open-source tool for issuing certificates in Kubernetes, integrating with various Public Key Infrastructure (PKI) providers. EJBCA integrates with cert-manager as an external certificate authority, enabling native integration to seamlessly request certificates through cert-manager, issued from EJBCA.

This tutorial is intended for users who wish to issue certificates in Kubernetes that has cert-manager deployed and wants to use a world-class PKI for the certificate issuance. Whether you have standardized on EJBCA as the corporate PKI, need a PKI that runs in a container, or just want to try something new, this integration is for you.

In this tutorial, you will learn how to: 

  • Create keys and certificate signing request (CSR) to request certificates from EJBCA for the EJBCA cert-manager external issuer​
  • Configure a new Registration Authority (RA) role in EJBCA for the cert-manager integration

  • Deploy cert-manager using a Helm chart

  • Deploy the EJBCA cert-manager external issuer using a Helm chart

  • Create an issuer and cluster issuer

  • Issue certificates with the EJBCA cert-manager external issuer

Prerequisites

Before you begin, you need:

  • SSH Access to the Kubernetes host.
  • Internet access to download the cert-manager components, EJBCA cert-manager external issuer container, and helm charts​.
  • An environment configured following the tutorial videos EJBCA - Getting started with Kubernetes.​ 

Step 1 - Create certificate for the RA credential

The EJBCA cert-manager external issuer requires an RA credential to connect to EJBCA for issuing and revoking certificates using the REST API.

Follow these steps to create the EJBCA cert-manager external issuer RA credential and upload it to the Kubernetes server. 

Create key and certificate signing request (CSR)

  1. SSH to the MicroK8s test host that has EJBCA deployed and configured.

  2. In your terminal, enter the following to create a directory to organize all the files for this tutorial:

    $ mkdir cert-manager
    
    CODE


  3. Change to the cert-manager directory:

    $ cd cert-manager
    
    CODE
  4. Create an OpenSSL configuration file for the EJBCA cert-manager external issuer RA certificate:

    $ cat > cert-manager-ra-01.conf <<EOF
    [req]
    default_bits = 2048
    prompt = no
    encrypt_key = yes
    distinguished_name = kubelet_serving
    req_extensions = v3_req
    [ kubelet_serving ]
    C = SE
    O = Keyfactor Community
    CN = cert-manager-ra-01
    [ v3_req ]
    keyUsage = digitalSignature
    extendedKeyUsage = clientAuth
    
    EOF
    
    CODE
     
  5. Generate the private key and create the CSR using the OpenSSL configuration file:

    $ openssl req -new -newkey rsa:2048 -nodes \
    -keyout cert-manager-ra-01-key.pem -sha256 \
    -out cert-manager-ra-01.csr -config cert-manager-ra-01.conf
    
    CODE
     
  6. Output the contents of the cert-manager-ra-01.csr to use with an upcoming step:

    $ cat cert-manager-ra-01.csr
    
    CODE
     
    • The output is similar to the following:

      -----BEGIN CERTIFICATE REQUEST-----
      MIICwDCCAagCAQAwSDELMAkGA1UEBhMCU0UxHDAaBgNVBAoME0tleWZhY3RvciBD
      b21tdW5pdHkxGzAZBgNVBAMMEmNlcnQtbWFuYWdlci1yYS0wMTCCASIwDQYJKoZI
      hvcNAQEBBQADggEPADCCAQoCggEBAM9o0DQ051oUyTRgW8mqOYzVpnJmeUcld0Q4
      Elg6OpqpWKqcIL0Avk3vsjpBQ9TTm5GUIOMgkaGVwfyiHefT8VReUD2XAouJSe+s
      INiaTZV4fsEndyQ2DEPhX9Yho2oV7fFMQPJATFZ9cZm4JczKfXtt7ya0aoyYH23t
      hB+ORT6eF0Eiv7bu/kl3/KlZlg0YxZUbYqKZQq4HbYJtXgEWErLVDKrLbyrc9uF8
      5y97eF2N4NmCM+EBS3Smd3UyrGqtuZFhJNF1ST3z9VQoTZBea+ZZO1j5E5fg5i8j
      Zmrp82rjJWx0WlXpwC6lXL70afGDyzQjF/YTTHA1LgsiUpbkkP8CAwEAAaAzMDEG
      CSqGSIb3DQEJDjEkMCIwCwYDVR0PBAQDAgeAMBMGA1UdJQQMMAoGCCsGAQUFBwMC
      MA0GCSqGSIb3DQEBCwUAA4IBAQC3S/u936GVC8ew2K9WtjhHX92/6UYtJ1VJ5wgy
      KElepwl4Lsp5i+3MFIFRYlYtypM1p9wZjRRnaBcnwmAsXqoYXjoHo5TXlcDXdxcB
      GRbuv25MoUCxdqWgDEqK3oui/qD3L/3YYLNpygToaDWFPBop8vEpj8qmjcZ4CVkw
      SvwELGeihJP0Ja+T+0q1NhnyjnYTXYUawxbND/Ma9OSJHnlCkHdprgZq0JB3H2Zq
      h1yYU/qxh1HdIqmbiRzvD6OqsY/FwvMUwF23DNu5r7N6urv9/sS+KaCZTx3T7ezp
      umTihw5jwzifQRKyq0A3yW8FtQ8J1hDXCDAvolLJxlUnDfaV
      -----END CERTIFICATE REQUEST-----
      
      CODE
       

Create RA role in EJBCA

The cert-manager RA role will allow the EJBCA cert-manager external issuer credential to connect to EJBCA using the REST API to issue and revoke certificates. Follow these steps to create a new role for the cert-manager RA:

  1. Go to the EJBCA Administration user interface using a web browser.

  2. In the EJBCA Admin UI, under System Functions, click Roles and Access Rules.

  3. Next to the list of available roles, click Add.

  4. For Role name, specify RA-cert-manager and click Add.
    The Roles Management page now lists the RA-cert-manager role.

  5. To update the access rules for the role, click Access Rules for the RA-cert-manager role.

  6. On the Edit Access Rules page, edit the following:

    • For Role Template, select RA Administrators.

    • For Authorized CAs, select My PKISubCA-G1.

    • For End Entity Profiles, select TLS Client Profile and TLS Server Profile.

  7. Click Save to store the updated access rules for the role.

  8. At the top right of the Edit Access Rules page, click Members.

  9. Members are defined by an attribute from the certificate DN and the serial number:

    • Match with: Select X509:CN, Common name.

    • CA: Verify that Management CA is selected for the CA to match on.

    • Match Value: Specify the name value from the certificate, in this example: "cert-manager-ra-01". Note that this is a case-sensitive matching.

  10. Click Add to add the user to the role.

You have now created a role for the cert-manager RA and can continue to create the certificate for the RA credential.

Submit the CSR to EJBCA to get the certificate

  1. Go to the EJBCA RA Web user interface using a web browser.

  2. Click Make New Request and update the following:

    • Select RA-Administrator for the Certificate Type.

    • Select Provided by user for Key-pair generation.

    • Paste the contents of the cert-manager-ra-01.csr from the terminal window into the CSR text field  (the PEM output in the terminal window), such as:

      -----BEGIN CERTIFICATE REQUEST-----
      MIICwDCCAagCAQAwSDELMAkGA1UEBhMCU0UxHDAaBgNVBAoME0tleWZhY3RvciBD
      b21tdW5pdHkxGzAZBgNVBAMMEmNlcnQtbWFuYWdlci1yYS0wMTCCASIwDQYJKoZI
      hvcNAQEBBQADggEPADCCAQoCggEBAM9o0DQ051oUyTRgW8mqOYzVpnJmeUcld0Q4
      Elg6OpqpWKqcIL0Avk3vsjpBQ9TTm5GUIOMgkaGVwfyiHefT8VReUD2XAouJSe+s
      INiaTZV4fsEndyQ2DEPhX9Yho2oV7fFMQPJATFZ9cZm4JczKfXtt7ya0aoyYH23t
      hB+ORT6eF0Eiv7bu/kl3/KlZlg0YxZUbYqKZQq4HbYJtXgEWErLVDKrLbyrc9uF8
      5y97eF2N4NmCM+EBS3Smd3UyrGqtuZFhJNF1ST3z9VQoTZBea+ZZO1j5E5fg5i8j
      Zmrp82rjJWx0WlXpwC6lXL70afGDyzQjF/YTTHA1LgsiUpbkkP8CAwEAAaAzMDEG
      CSqGSIb3DQEJDjEkMCIwCwYDVR0PBAQDAgeAMBMGA1UdJQQMMAoGCCsGAQUFBwMC
      MA0GCSqGSIb3DQEBCwUAA4IBAQC3S/u936GVC8ew2K9WtjhHX92/6UYtJ1VJ5wgy
      KElepwl4Lsp5i+3MFIFRYlYtypM1p9wZjRRnaBcnwmAsXqoYXjoHo5TXlcDXdxcB
      GRbuv25MoUCxdqWgDEqK3oui/qD3L/3YYLNpygToaDWFPBop8vEpj8qmjcZ4CVkw
      SvwELGeihJP0Ja+T+0q1NhnyjnYTXYUawxbND/Ma9OSJHnlCkHdprgZq0JB3H2Zq
      h1yYU/qxh1HdIqmbiRzvD6OqsY/FwvMUwF23DNu5r7N6urv9/sS+KaCZTx3T7ezp
      umTihw5jwzifQRKyq0A3yW8FtQ8J1hDXCDAvolLJxlUnDfaV
      -----END CERTIFICATE REQUEST-----
      
      CODE
       
    • Click Upload CSR.

    • Enter cert-manager-ra-01 for the Username.

    • Click Download PEM full chain.

  3. Return to the terminal window and open a new tab or terminal window.

  4. In your terminal, enter the following to upload the cert-manager-ra-01.pem to the MicroK8s VM:

    $ scp cert-manager-ra-01.pem user@172.16.170.187:~/cert-manager/cert-manager-ra-01.crt
    
    CODE


    The certificate.pem file is renamed to .crt when uploaded to the K8’s host

     

  5. Return to the original terminal window opened for connecting to the Kubernetes server.

  6. Output the contents of the cert-manager-ra-01.crt file with the cat command to copy the ManagementCA cert PEM blob:

    $ cat cert-manager-ra-01.crt
    
    CODE
     
    • The output is similar to the following:

      Subject: CN=cert-manager-ra-01,O=Keyfactor Community,C=SE
      Issuer: CN=ManagementCA,O=Keyfactor Community,C=SE
      -----BEGIN CERTIFICATE-----
      MIIEfzCCAmegAwIBAgIUdTaxyI6z9SZTQy6cM9ByquOsan4wDQYJKoZIhvcNAQEL
      BQAwQjEVMBMGA1UEAwwMTWFuYWdlbWVudENBMRwwGgYDVQQKDBNLZXlmYWN0b3Ig
      Q29tbXVuaXR5MQswCQYDVQQGEwJTRTAeFw0yNDAxMTExNzEyMzJaFw0yNTAxMDkx
      NzEyMzFaMEgxCzAJBgNVBAYTAlNFMRwwGgYDVQQKDBNLZXlmYWN0b3IgQ29tbXVu
      aXR5MRswGQYDVQQDDBJjZXJ0LW1hbmFnZXItcmEtMDEwggEiMA0GCSqGSIb3DQEB
      AQUAA4IBDwAwggEKAoIBAQDEdW7YbbQnWeYCzt4eE+dKg2rZ9gWD8JIJFsPo8Qbi
      aCI5otyyqXSdEki/9Z7Zsjo2nhFVG6HhsAsO02e29sJ54QERcAUEHatf1502fwWL
      Or7P5e4tLd6SsNeuJ74DC8dkppCHYdsS2X9xutqJnYvuQhqnfg84mlUG3my4qAMB
      G6ultKt8eCq39Be9/LTau9Ur08SWOluvf6DcpHlhtOJzfD3/UOrS4viGwy4hloau
      xSCQCKMUp51ifj0rGygvNHi58qdsAV2kz1/VCzWu7A4T5paeBAlAaD9shA8aci3R
      4x/KEG90gBXViZE/DJDOvxf7/Y7S04hY2ZRl7bnpZNslAgMBAAGjZzBlMB8GA1Ud
      IwQYMBaAFNf+MZRDSTxfobte/gWABCwE86DSMBMGA1UdJQQMMAoGCCsGAQUFBwMC
      MB0GA1UdDgQWBBTi+OUsnFKQHh1QWYIZNtIguiGJ9TAOBgNVHQ8BAf8EBAMCB4Aw
      DQYJKoZIhvcNAQELBQADggIBAAo6rV5JdKRsS8Z31YDdFWRG4D4pU/j15o7wiwSe
      FiVNACkYiXndoPZP+KaJVFt0FNxw/4ErGxgPLRS/XV9HgTAzCAbAAeGd2mHrMaEX
      eS1G4aQZd7AOgIDZ7+qSrlBdHpb8vXG6tfFKQcCpZxZmTEcTDfZt/YGS+IHxv9oZ
      NX7aLz+pOookjvsse4kS1FMYFUDlL5znzqMHLNwmUUzzsC11TiUZ7unG3k3ekkLG
      F3PSEeMp+y7zmy+skvFQYVDwFywc/2fd+JJ4oFDEPAklM+L+LtmLkhyLHtZzACO0
      LeSUnmVVInfQPT1uEtpL0pmbAbXspNf0nDzSxVhnr/dvN1xfKkFnTc2yvxyZ83Yu
      1DzDnLgu2HsP/1veyr6E8z8iD7o61CbSt/WiBeEDYNDgs8IUWDgVn026pUoTL8/p
      dtcAc+g+C0cr2ox6W1o4e2inQjYaXu2MlKkaAx4YTakqC1sXlb8NWRk8l7UUil+L
      0e+mFZDxIW3i8MepgXPDa05m4b1ZoXa3EAR8e2++f8nXqJlcjoKQOLLTP64t2r1p
      mrCjH+xke47uV36MaqIZ/W8Zx7CW1Cwt4wddzniySUjIfa8oB3OSvoHqx7kLfUvc
      VQWumG2ETi87VSAePUI1DG4aksqTIJ6ZI87Qd/16OUP+9ivwtyPnlemWoMnLiPu7
      GNPr
      -----END CERTIFICATE-----
      Subject: CN=ManagementCA,O=Keyfactor Community,C=SE
      Issuer: CN=ManagementCA,O=Keyfactor Community,C=SE
      -----BEGIN CERTIFICATE-----
      MIIFdTCCA12gAwIBAgIUWpEFjDfFuGU6I5s/zCpuXrVmZIswDQYJKoZIhvcNAQEL
      BQAwQjEVMBMGA1UEAwwMTWFuYWdlbWVudENBMRwwGgYDVQQKDBNLZXlmYWN0b3Ig
      Q29tbXVuaXR5MQswCQYDVQQGEwJTRTAeFw0yMzAxMTgwODM0MDJaFw0zMzAxMTUw
      ODM0MDFaMEIxFTATBgNVBAMMDE1hbmFnZW1lbnRDQTEcMBoGA1UECgwTS2V5ZmFj
      dG9yIENvbW11bml0eTELMAkGA1UEBhMCU0UwggIiMA0GCSqGSIb3DQEBAQUAA4IC
      DwAwggIKAoICAQDIf6n+++qldacqGvWlgiPx7AnSMuremYdrRhoylF+3kJbDFiMp
      KpVzEaeguionS4uXqErZAzgzcbu6huf4bRscYk04nCgXsFAMItsiEZ314oE4thv8
      fbPPu4K1joeDgdHv0QhA3dkRUNorH54wOR6gLDzn6nBwePJAoKxhc/WoaONta2/O
      tHeTemYZOLt+uMY+Hj3o2sMeTm3B/B/ED5BWzVMSPOCCV6qk5/cW/P2YvWfFHUja
      8xqqbBuuDZHTuX4X58BsHH+o8bgZjWhdwcZb8Oe2VajFX6DpiBZcESQL+0ir0ZqG
      zALBc8jADv0VZC0u1Pxj39p19Xosm46jelcH3CBD+65I+1Kg5aQ1tIpBHLvdJEuT
      X6WkNPMmi0VqawxtlgshlF10kLsHm/r+dlGTQ78EA23JkgglBPovCmWSb6+KJyk/
      q6dWElqrbdHwieuajb2D9s/P7RDU7h9gSf6C4nbIX1x5H/mpVCdZWDuqL0Y7tn9K
      kvhh3TNXZf1TiryJkw3GDxHS88mh+pGEZsnC3hH5rLKj/JFVQtbWeu1QdhI5fFlh
      PtUjIWeFHbgvMisd4qjouJfhuF2LRfpdn/u52MHTVntVGtGYNV3uUVpVR6YkFH0q
      GfAqP5clv1qSF5gRANIPVQSpF0wcvTHvgWdv9bOy7a9BLvWFg46Ys4HKWQIDAQAB
      o2MwYTAPBgNVHRMBAf8EBTADAQH/MB8GA1UdIwQYMBaAFNf+MZRDSTxfobte/gWA
      BCwE86DSMB0GA1UdDgQWBBTX/jGUQ0k8X6G7Xv4FgAQsBPOg0jAOBgNVHQ8BAf8E
      BAMCAYYwDQYJKoZIhvcNAQELBQADggIBAC17+M739nb2AG3bpKObDDlW+fYMdEhX
      tjQcOvHIUrITKryX3lmHyWDFFgFTeTYcoxq8ywFvpvXz4pHgeFWRZYQw7cSWwH8n
      JfLE+EJlpYU2yUGto/S8NPXV54dAYNsvQQncQixsIYgxsmX7yIzBt1+v3sLmQlp5
      CfZRCOxj+2fa9jb/jygdQC3AAS5uT86gYz0YcB5VXQ0+jYWsL7MDwgb8ORcmiugd
      uZ0kgBXd40Qg9bJhfz0N+BKWPTbS4dFst4ey5dndLp4QxWXzTt+gbmOMBpiwB6xx
      H3hw/LrRBEs7hrhVIlJ76cMx/f/5wERD0qS3uPXpCCtcKDBqHFruOI/NMNEVRFwi
      VxVD8w1jWYXDUyNVErU0LzqGOkyDuRwEDN8svaKn8+WdyumDB21tTWEbYPbFWc9R
      2epNj8moBVcfnxwsVP5TCXk6tEEOMkCVLNC3JBUWSfGJjg/2PDEdo2cPYCXYU4Hu
      eE/SnoUbRh0M34BfaHHt8S/vcEZWSkctJUmRZbTju57FKMlIHcgE5FHN5ahDAiSc
      GgncvFfPKXcEPFh5bhKdhT6FzbKysCoRw16rwhzfsm4X42jvzBEOKpUcFDpRuBJs
      zTk30lhAdmROkG5UTemobyKgDVw50VcFKbMk3Q5Gzs9TZ+uRAWJA7rF6MSc+cSlP
      qMN+i82CAMeU
      -----END CERTIFICATE-----
      
      CODE
       
  7. Select the PEM blob for the ManagementCA and copy it:

    Subject: CN=ManagementCA,O=Keyfactor Community,C=SE
    Issuer: CN=ManagementCA,O=Keyfactor Community,C=SE
    -----BEGIN CERTIFICATE-----
    MIIFdTCCA12gAwIBAgIUWpEFjDfFuGU6I5s/zCpuXrVmZIswDQYJKoZIhvcNAQEL
    BQAwQjEVMBMGA1UEAwwMTWFuYWdlbWVudENBMRwwGgYDVQQKDBNLZXlmYWN0b3Ig
    Q29tbXVuaXR5MQswCQYDVQQGEwJTRTAeFw0yMzAxMTgwODM0MDJaFw0zMzAxMTUw
    ODM0MDFaMEIxFTATBgNVBAMMDE1hbmFnZW1lbnRDQTEcMBoGA1UECgwTS2V5ZmFj
    dG9yIENvbW11bml0eTELMAkGA1UEBhMCU0UwggIiMA0GCSqGSIb3DQEBAQUAA4IC
    DwAwggIKAoICAQDIf6n+++qldacqGvWlgiPx7AnSMuremYdrRhoylF+3kJbDFiMp
    KpVzEaeguionS4uXqErZAzgzcbu6huf4bRscYk04nCgXsFAMItsiEZ314oE4thv8
    fbPPu4K1joeDgdHv0QhA3dkRUNorH54wOR6gLDzn6nBwePJAoKxhc/WoaONta2/O
    tHeTemYZOLt+uMY+Hj3o2sMeTm3B/B/ED5BWzVMSPOCCV6qk5/cW/P2YvWfFHUja
    8xqqbBuuDZHTuX4X58BsHH+o8bgZjWhdwcZb8Oe2VajFX6DpiBZcESQL+0ir0ZqG
    zALBc8jADv0VZC0u1Pxj39p19Xosm46jelcH3CBD+65I+1Kg5aQ1tIpBHLvdJEuT
    X6WkNPMmi0VqawxtlgshlF10kLsHm/r+dlGTQ78EA23JkgglBPovCmWSb6+KJyk/
    q6dWElqrbdHwieuajb2D9s/P7RDU7h9gSf6C4nbIX1x5H/mpVCdZWDuqL0Y7tn9K
    kvhh3TNXZf1TiryJkw3GDxHS88mh+pGEZsnC3hH5rLKj/JFVQtbWeu1QdhI5fFlh
    PtUjIWeFHbgvMisd4qjouJfhuF2LRfpdn/u52MHTVntVGtGYNV3uUVpVR6YkFH0q
    GfAqP5clv1qSF5gRANIPVQSpF0wcvTHvgWdv9bOy7a9BLvWFg46Ys4HKWQIDAQAB
    o2MwYTAPBgNVHRMBAf8EBTADAQH/MB8GA1UdIwQYMBaAFNf+MZRDSTxfobte/gWA
    BCwE86DSMB0GA1UdDgQWBBTX/jGUQ0k8X6G7Xv4FgAQsBPOg0jAOBgNVHQ8BAf8E
    BAMCAYYwDQYJKoZIhvcNAQELBQADggIBAC17+M739nb2AG3bpKObDDlW+fYMdEhX
    tjQcOvHIUrITKryX3lmHyWDFFgFTeTYcoxq8ywFvpvXz4pHgeFWRZYQw7cSWwH8n
    JfLE+EJlpYU2yUGto/S8NPXV54dAYNsvQQncQixsIYgxsmX7yIzBt1+v3sLmQlp5
    CfZRCOxj+2fa9jb/jygdQC3AAS5uT86gYz0YcB5VXQ0+jYWsL7MDwgb8ORcmiugd
    uZ0kgBXd40Qg9bJhfz0N+BKWPTbS4dFst4ey5dndLp4QxWXzTt+gbmOMBpiwB6xx
    H3hw/LrRBEs7hrhVIlJ76cMx/f/5wERD0qS3uPXpCCtcKDBqHFruOI/NMNEVRFwi
    VxVD8w1jWYXDUyNVErU0LzqGOkyDuRwEDN8svaKn8+WdyumDB21tTWEbYPbFWc9R
    2epNj8moBVcfnxwsVP5TCXk6tEEOMkCVLNC3JBUWSfGJjg/2PDEdo2cPYCXYU4Hu
    eE/SnoUbRh0M34BfaHHt8S/vcEZWSkctJUmRZbTju57FKMlIHcgE5FHN5ahDAiSc
    GgncvFfPKXcEPFh5bhKdhT6FzbKysCoRw16rwhzfsm4X42jvzBEOKpUcFDpRuBJs
    zTk30lhAdmROkG5UTemobyKgDVw50VcFKbMk3Q5Gzs9TZ+uRAWJA7rF6MSc+cSlP
    qMN+i82CAMeU
    -----END CERTIFICATE-----
    
    CODE
     
  8. Create the ManagementCA.crt file:

    $ vim ManagementCA.crt
    
    CODE
     
  9. Enter the letter i to insert text.

  10. Paste the ManagementCA PEM blob into the file:

    Subject: CN=ManagementCA,O=Keyfactor Community,C=SE
    Issuer: CN=ManagementCA,O=Keyfactor Community,C=SE
    -----BEGIN CERTIFICATE-----
    MIIFdTCCA12gAwIBAgIUWpEFjDfFuGU6I5s/zCpuXrVmZIswDQYJKoZIhvcNAQEL
    BQAwQjEVMBMGA1UEAwwMTWFuYWdlbWVudENBMRwwGgYDVQQKDBNLZXlmYWN0b3Ig
    Q29tbXVuaXR5MQswCQYDVQQGEwJTRTAeFw0yMzAxMTgwODM0MDJaFw0zMzAxMTUw
    ODM0MDFaMEIxFTATBgNVBAMMDE1hbmFnZW1lbnRDQTEcMBoGA1UECgwTS2V5ZmFj
    dG9yIENvbW11bml0eTELMAkGA1UEBhMCU0UwggIiMA0GCSqGSIb3DQEBAQUAA4IC
    DwAwggIKAoICAQDIf6n+++qldacqGvWlgiPx7AnSMuremYdrRhoylF+3kJbDFiMp
    KpVzEaeguionS4uXqErZAzgzcbu6huf4bRscYk04nCgXsFAMItsiEZ314oE4thv8
    fbPPu4K1joeDgdHv0QhA3dkRUNorH54wOR6gLDzn6nBwePJAoKxhc/WoaONta2/O
    tHeTemYZOLt+uMY+Hj3o2sMeTm3B/B/ED5BWzVMSPOCCV6qk5/cW/P2YvWfFHUja
    8xqqbBuuDZHTuX4X58BsHH+o8bgZjWhdwcZb8Oe2VajFX6DpiBZcESQL+0ir0ZqG
    zALBc8jADv0VZC0u1Pxj39p19Xosm46jelcH3CBD+65I+1Kg5aQ1tIpBHLvdJEuT
    X6WkNPMmi0VqawxtlgshlF10kLsHm/r+dlGTQ78EA23JkgglBPovCmWSb6+KJyk/
    q6dWElqrbdHwieuajb2D9s/P7RDU7h9gSf6C4nbIX1x5H/mpVCdZWDuqL0Y7tn9K
    kvhh3TNXZf1TiryJkw3GDxHS88mh+pGEZsnC3hH5rLKj/JFVQtbWeu1QdhI5fFlh
    PtUjIWeFHbgvMisd4qjouJfhuF2LRfpdn/u52MHTVntVGtGYNV3uUVpVR6YkFH0q
    GfAqP5clv1qSF5gRANIPVQSpF0wcvTHvgWdv9bOy7a9BLvWFg46Ys4HKWQIDAQAB
    o2MwYTAPBgNVHRMBAf8EBTADAQH/MB8GA1UdIwQYMBaAFNf+MZRDSTxfobte/gWA
    BCwE86DSMB0GA1UdDgQWBBTX/jGUQ0k8X6G7Xv4FgAQsBPOg0jAOBgNVHQ8BAf8E
    BAMCAYYwDQYJKoZIhvcNAQELBQADggIBAC17+M739nb2AG3bpKObDDlW+fYMdEhX
    tjQcOvHIUrITKryX3lmHyWDFFgFTeTYcoxq8ywFvpvXz4pHgeFWRZYQw7cSWwH8n
    JfLE+EJlpYU2yUGto/S8NPXV54dAYNsvQQncQixsIYgxsmX7yIzBt1+v3sLmQlp5
    CfZRCOxj+2fa9jb/jygdQC3AAS5uT86gYz0YcB5VXQ0+jYWsL7MDwgb8ORcmiugd
    uZ0kgBXd40Qg9bJhfz0N+BKWPTbS4dFst4ey5dndLp4QxWXzTt+gbmOMBpiwB6xx
    H3hw/LrRBEs7hrhVIlJ76cMx/f/5wERD0qS3uPXpCCtcKDBqHFruOI/NMNEVRFwi
    VxVD8w1jWYXDUyNVErU0LzqGOkyDuRwEDN8svaKn8+WdyumDB21tTWEbYPbFWc9R
    2epNj8moBVcfnxwsVP5TCXk6tEEOMkCVLNC3JBUWSfGJjg/2PDEdo2cPYCXYU4Hu
    eE/SnoUbRh0M34BfaHHt8S/vcEZWSkctJUmRZbTju57FKMlIHcgE5FHN5ahDAiSc
    GgncvFfPKXcEPFh5bhKdhT6FzbKysCoRw16rwhzfsm4X42jvzBEOKpUcFDpRuBJs
    zTk30lhAdmROkG5UTemobyKgDVw50VcFKbMk3Q5Gzs9TZ+uRAWJA7rF6MSc+cSlP
    qMN+i82CAMeU
    -----END CERTIFICATE-----
    
    CODE
     
  11. Enter :wq to save and close the file.

The EJBCA cert-manager external issuer RA credential has been created and uploaded to the Kubernetes server. Continue to the next step to deploy cert-manager and the EJBCA cert-manager external issuer.

Step 2 - Deploy cert-manager

To issue certificates using EJBCA and cert-manager, the cert-manager must be deployed. Using Helm and applying the Kubernetes Custom Resource Definitions (CRDs) gets cert-manager up and running quickly.

To deploy cert-manager, follow these steps:

  1. Continue from the terminal window of the previous step.

  2. Add the cert-manager helm repository:

    $ helm repo add jetstack https://charts.jetstack.io
    
    CODE
     
    • The output is similar to the following:

      "jetstack" has been added to your repositories
      
      CODE
       
  3. Update the helm repository cache:

    $ helm repo update
    
    CODE
     
    • The output is similar to the following:

      Hang tight while we grab the latest from your chart repositories...
      ...Successfully got an update from the "hashicorp" chart repository
      ...Successfully got an update from the "jetstack" chart repository
      Update Complete. ⎈Happy Helming!⎈
      
      CODE
       
  4. Install the cert-manager Custom Resource Definitions:

    $ kubectl apply -f https://github.com/cert-manager/cert-manager/releases/download/v1.13.3/cert-manager.crds.yaml
    
    CODE
     
    • The output is similar to the following:

      customresourcedefinition.apiextensions.k8s.io/certificaterequests.cert-manager.io configured
      customresourcedefinition.apiextensions.k8s.io/certificates.cert-manager.io configured
      customresourcedefinition.apiextensions.k8s.io/challenges.acme.cert-manager.io configured
      customresourcedefinition.apiextensions.k8s.io/clusterissuers.cert-manager.io configured
      customresourcedefinition.apiextensions.k8s.io/issuers.cert-manager.io configured
      customresourcedefinition.apiextensions.k8s.io/orders.acme.cert-manager.io configured
      
      CODE
       
  5. Deploy cert-manager using helm:

    $ helm install \
    cert-manager jetstack/cert-manager \
    --namespace cert-manager \
    --create-namespace \
    --version v1.13.3
    
    CODE
     
    • The output is similar to the following:

      NAME: cert-manager
      LAST DEPLOYED: Thu Jan 25 10:52:05 2024
      NAMESPACE: cert-manager
      STATUS: deployed
      REVISION: 1
      TEST SUITE: None
      NOTES:
      cert-manager v1.13.3 has been deployed successfully!
      
      In order to begin issuing certificates, you will need to set up a ClusterIssuer
      or Issuer resource (for example, by creating a 'letsencrypt-staging' issuer).
      
      More information on the different types of issuers and how to configure them
      can be found in our documentation:
      
      https://cert-manager.io/docs/configuration/
      
      For information on how to configure cert-manager to automatically provision
      Certificates for Ingress resources, take a look at the `ingress-shim`
      documentation:
      
      https://cert-manager.io/docs/usage/ingress/
      
      CODE
       

Deployment of cert-manager is now completed, you can continue to the next step to deploy the EJBCA cert-manager external issuer.

Step 3 - Deploy EJBCA cert-manager external issuer

To complete the integration, the EJBCA cert-manager external issuer container is deployed using Helm. This container is an external issuer for cert-manager which uses the EJBCA REST API to submit certificate requests and revoke certificates.

To deploy the EJBCA cert-manager external issuer, follow these steps:

  1. Continue from the terminal window of the previous step.

  2. Create the name space for the EJBCA cert-manager external issuer:

    $ kubectl create namespace ejbca-cert-manager
    
    CODE
     
    • The output is similar to the following:

      namespace/ejbca-cert-manager created
      
      CODE
       
  3. Create the secret for the cert-manager-ra-01 credential:

    $ kubectl -n ejbca-cert-manager create secret tls ejbca-secret --cert=cert-manager-ra-01.crt --key=cert-manager-ra-01-key.pem
    
    CODE
     
    • The output is similar to the following:

      secret/ejbca-secret created
      
      CODE
       
  4. Create the secret for the EJBCA TLS chain:

    $ kubectl -n ejbca-cert-manager create secret generic ejbca-ca-secret --from-file=ca.crt=ManagementCA.crt
    
    CODE
     
    • The output is similar to the following:

      secret/ejbca-ca-secret created
      
      CODE
       
  5. Add the EJBCA cert-manager external issuer helm repository:

    $ helm repo add ejbca-issuer https://keyfactor.github.io/ejbca-cert-manager-issuer
    
    CODE
     
    • The output is similar to the following:

      "ejbca-issuer" has been added to your repositories
      
      CODE
       
  6. Update the helm repository cache:

    $ helm repo update
    
    CODE
     
    • The output is similar to the following:

      Hang tight while we grab the latest from your chart repositories...
      ...Successfully got an update from the "ejbca-issuer" chart repository
      ...Successfully got an update from the "hashicorp" chart repository
      ...Successfully got an update from the "jetstack" chart repository
      Update Complete. ⎈Happy Helming!⎈
      
      CODE
       
  7. Deploy the EJBCA cert-manager external issuer:

    $ helm install ejbca-cert-manager-issuer ejbca-issuer/ejbca-cert-manager-issuer --namespace ejbca-cert-manager --set image.tag="1.3.2"
    
    CODE
     
    • The output is similar to the following:

      NAME: ejbca-cert-manager-issuer
      LAST DEPLOYED: Thu Jan 25 08:52:16 2024
      NAMESPACE: ejbca-cert-manager
      STATUS: deployed
      REVISION: 1
      TEST SUITE: None
      
      CODE
       
  8. Create a namespace for issuing certificates with the EJBCA cert-manager external issuer:

    $ kubectl create namespace pkirules
    
    CODE
     
    • The output is similar to the following:

      namespace/pkirules created
      
      CODE
       
  9. Create the issuer.yaml file:

    cat > issuer.yaml <<EOF 
    apiVersion: ejbca-issuer.keyfactor.com/v1alpha1
    kind: Issuer
    metadata:
    namespace: pkirules
    labels:
    # Customize to your deployment, but these are optional
    app.kubernetes.io/name: issuer
    app.kubernetes.io/instance: pkirules-tls
    app.kubernetes.io/part-of: ejbca-issuer
    app.kubernetes.io/created-by: ejbca-issuer
    name: pkirules-tls
    spec:
    hostname: "ejbca-internal.ejbca-k8s"
    ejbcaSecretName: "ejbca-secret"
    certificateAuthorityName: "MyPKISubCA-G1"
    certificateProfileName: "TLS Server Profile"
    endEntityProfileName: "TLS Server Profile"
    caBundleSecretName: ejbca-ca-secret 
    EOF
    
    CODE
     
  10. Apply the issuer.yaml file to create an issuer in the pkirules namespace:

    $ kubectl apply -f issuer.yaml
    
    CODE
     
    • The output is similar to the following:

      issuer.ejbca-issuer.keyfactor.com/pkirules-tls created
      
      CODE
       
  11. Create the clusterissuer.yaml file:

    $ cat > clusterissuer.yaml <<EOF
    apiVersion: ejbca-issuer.keyfactor.com/v1alpha1
    kind: ClusterIssuer
    metadata:
    namespace: pkirules 
    labels:
    # Customize to your deployment, but these are optional
    app.kubernetes.io/name: clusterissuer
    app.kubernetes.io/instance: clusterissuer-pkirules
    app.kubernetes.io/part-of: ejbca-issuer
    app.kubernetes.io/created-by: ejbca-issuer
    name: clusterissuer-pkirules
    spec:
    hostname: "ejbca-internal.ejbca-k8s"
    ejbcaSecretName: "ejbca-secret"
    certificateAuthorityName: "MyPKISubCA-G1"
    certificateProfileName: "TLS Server Profile"
    endEntityProfileName: "TLS Server Profile"
    caBundleSecretName: ejbca-ca-secret
    EOF
    
    CODE
    
    
  12. Apply the clusterissuer.yaml to create an issuer that uses EJBCA fro the Kubernetes cluster:

    $ kubectl apply -f clusterissuer.yaml
    
    CODE
     
    • The output is similar to the following:

      clusterissuer.ejbca-issuer.keyfactor.com/clusterissuer-pkirules created
      
      CODE
       
  13. Get the issuers.ejbca-issuer.keyfactor.com:

    $ kubectl -n pkirules get issuers.ejbca-issuer.keyfactor.com
    
    CODE
     
    • The output is similar to the following:

      NAME AGE
      pkirules-tls 1m
      
      CODE
       
  14. Describe the issuers.ejbca-issuer.keyfactor.com:

    $ kubectl -n pkirules describe issuers.ejbca-issuer.keyfactor.com
    
    CODE
     
    • The output is similar to the following:

      Name: pkirules-tls
      Namespace: pkirules
      Labels: app.kubernetes.io/created-by=ejbca-issuer
      app.kubernetes.io/instance=pkirules-tls
      app.kubernetes.io/name=issuer
      app.kubernetes.io/part-of=ejbca-issuer
      Annotations: <none>
      API Version: ejbca-issuer.keyfactor.com/v1alpha1
      Kind: Issuer
      Metadata:
      Creation Timestamp: 2024-01-25T14:02:01Z
      Generation: 1
      Managed Fields:
      API Version: ejbca-issuer.keyfactor.com/v1alpha1
      Fields Type: FieldsV1
      fieldsV1:
      f:metadata:
      f:annotations:
      .:
      f:kubectl.kubernetes.io/last-applied-configuration:
      f:labels:
      .:
      f:app.kubernetes.io/created-by:
      f:app.kubernetes.io/instance:
      f:app.kubernetes.io/name:
      f:app.kubernetes.io/part-of:
      f:spec:
      .:
      f:caBundleSecretName:
      f:certificateAuthorityName:
      f:certificateProfileName:
      f:ejbcaSecretName:
      f:endEntityProfileName:
      f:hostname:
      Manager: kubectl-client-side-apply
      Operation: Update
      Time: 2024-01-25T14:02:01Z
      API Version: ejbca-issuer.keyfactor.com/v1alpha1
      Fields Type: FieldsV1
      fieldsV1:
      f:status:
      .:
      f:conditions:
      Manager: manager
      Operation: Update
      Subresource: status
      Time: 2024-01-25T14:02:01Z
      Resource Version: 601159
      UID: 2f35a08b-c2f7-4612-b5be-bafd6bfaa2ad
      Spec:
      Ca Bundle Secret Name: ejbca-ca-secret
      Certificate Authority Name: MyPKISubCA-G1
      Certificate Profile Name: TLS Server Profile
      Ejbca Secret Name: ejbca-secret
      End Entity Profile Name: TLS Server Profile
      Hostname: ejbca-internal.ejbca-k8s
      Status:
      Conditions:
      Last Transition Time: 2024-01-25T14:02:01Z
      Message: Success
      Reason: ejbca-issuer.IssuerController.Reconcile
      Status: True
      Type: Ready
      Events: <none>
      
      CODE
       

You now have deployed the EJBCA cert-manager external issuer and can continue with issuing certificates.

Step 4 - Issue certificates with the EJBCA cert-manager external issuer

Now that cert-manager and the EJBCA cert-manager external issuer are deployed and configured, you can issue some certificates. The following sections demonstrate three different issuance methods: issuing a certificate manually, using a certificate object, and deploying a simple deployment that requests a TLS certificate for Ingress. 

Manual issuance

  1. Continue from the terminal window of the previous step.

  2. Create an OpenSSL configuration file to generate TLS certificate CSR:

    $ cat > test-cm-01.pkirules.conf <<EOF
    [ req ]
    distinguished_name = req_distinguished_name
    req_extensions = req_ext
    prompt = no
    
    [ req_distinguished_name ]
    countryName = SE
    organizationName = Keyfactor Community
    commonName = test-cm-01.pkirules
    
    [ req_ext ]
    subjectAltName = @alt_names
    
    [alt_names]
    DNS.1 = test-cm.pkirules
    
    EOF
    
    CODE
     
  3. Generate an EC P-256 key using OpenSSL:

    $ openssl ecparam -name prime256v1 -genkey -noout -out test-cm-01.pkirules.key
    
    CODE
     
  4. Generate a CSR with the EC Key and OpenSSL configuration file:

    $ openssl req -new -sha256 -key test-cm-01.pkirules.key -out test-cm-01.pkirules.csr -config test-cm-01.pkirules.conf
    
    CODE
     
  5. Use base64 to encode the CSR and export it to a variable:

    $ CSR64ECODE="$(base64 test-cm-01.pkirules.csr | tr -d \\n)"
    
    CODE
     
  6. Create a certificate request YAML file that is used to manually request a certificate with cert-manager:

    $ cat > test-cm-01.pkirules.yaml <<EOF
    apiVersion: cert-manager.io/v1
    kind: CertificateRequest
    metadata:
    name: test-cm-01.pkirules
    namespace: pkirules
    spec:
    request: $CSR64ECODE
    issuerRef:
    name: pkirules-tls
    group: ejbca-issuer.keyfactor.com
    kind: Issuer
    EOF
    
    CODE
     
  7. Apply the test-cm-01.pkirules.yaml file which creates the certificate request with cert-manager:

    $ kubectl apply -f test-cm-01.pkirules.yaml
    
    CODE
     
    • The output is similar to the following:

      certificaterequest.cert-manager.io/test-cm-01.pkirules created
      
      CODE
       
  8. List the certificate requests in the pkirules namespace:

    $ kubectl -n pkirules get CertificateRequest
    
    CODE
     
    • The output is similar to the following:

      NAME APPROVED DENIED READY ISSUER REQUESTOR AGE
      test-cm-01.pkirules True True pkirules-tls admin 2m18s
      
      CODE
       
  9. Describe the test-cm-01.pkirules certificate request to review the details:

    $ kubectl -n pkirules describe CertificateRequest/test-cm-01.pkirules
    
    CODE
     
    • The output is similar to the following:

      Name: test-cm-01.pkirules
      Namespace: pkirules
      Labels: <none>
      Annotations: <none>
      API Version: cert-manager.io/v1
      Kind: CertificateRequest
      Metadata:
      Creation Timestamp: 2024-01-26T10:29:46Z
      Generation: 1
      Managed Fields:
      API Version: cert-manager.io/v1
      Fields Type: FieldsV1
      fieldsV1:
      f:status:
      f:conditions:
      .:
      k:{"type":"Approved"}:
      .:
      f:lastTransitionTime:
      f:message:
      f:reason:
      f:status:
      f:type:
      Manager: cert-manager-certificaterequests-approver
      Operation: Update
      Subresource: status
      Time: 2024-01-26T10:29:46Z
      API Version: cert-manager.io/v1
      Fields Type: FieldsV1
      fieldsV1:
      f:metadata:
      f:annotations:
      .:
      f:kubectl.kubernetes.io/last-applied-configuration:
      f:spec:
      .:
      f:issuerRef:
      .:
      f:group:
      f:kind:
      f:name:
      f:request:
      Manager: kubectl-client-side-apply
      Operation: Update
      Time: 2024-01-26T10:29:46Z
      API Version: cert-manager.io/v1
      Fields Type: FieldsV1
      fieldsV1:
      f:status:
      .:
      f:ca:
      f:certificate:
      f:conditions:
      k:{"type":"Ready"}:
      .:
      f:lastTransitionTime:
      f:message:
      f:reason:
      f:status:
      f:type:
      Manager: manager
      Operation: Update
      Subresource: status
      Time: 2024-01-26T10:29:46Z
      Resource Version: 649945
      UID: 3d8fffb0-6876-4541-8df2-c8a8ab17ed19
      Spec:
      Groups:
      system:masters
      system:authenticated
      Issuer Ref:
      Group: ejbca-issuer.keyfactor.com
      Kind: Issuer
      Name: pkirules-tls
      Request: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURSBSRVFVRVNULS0tLS0KTUlJQk1qQ0IyUUlCQURCSk1Rc3dDUVlEVlFRR0V3SlRSVEVjTUJvR0ExVUVDZ3dUUzJWNVptRmpkRzl5SUVOdgpiVzExYm1sMGVURWNNQm9HQTFVRUF3d1RkR1Z6ZEMxamJTMHdNUzV3YTJseWRXeGxjekJaTUJNR0J5cUdTTTQ5CkFnRUdDQ3FHU000OUF3RUhBMElBQk5Va29xeHB3MGR5ZEQyWVdHSGN2UUNqS21ZbzdBZnVYK2NZeGpqWW5MZnEKVXpHZzkvTkxYM2VRRVlDd2pNTlQ4djNycVd2a2JmNFNmUWlJV29GSFoxMmdMakFzQmdrcWhraUc5dzBCQ1E0eApIekFkTUJzR0ExVWRFUVFVTUJLQ0VIUmxjM1F0WTIwdWNHdHBjblZzWlhNd0NnWUlLb1pJemowRUF3SURTQUF3ClJRSWdKQjArdCtySmZvNVRVYWVCcnFCU1RUYlZnTGVEeTh3Lzd1bFpNanJtTldnQ0lRRFdpNDJPcURHVVBqOHkKK3RWZmxXWTVWUWEreUQ4T1JURDZKMDZ5NHlKRWZBPT0KLS0tLS1FTkQgQ0VSVElGSUNBVEUgUkVRVUVTVC0tLS0tCg==
      UID: admin
      Username: admin
      Status:
      Ca: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUNtVENDQWorZ0F3SUJBZ0lVSjBlTDlJbmxubWNDRWpxT3pPTmZOdFZ2QVRFd0NnWUlLb1pJemowRUF3UXcKU1RFTE1Ba0dBMVVFQmhNQ1UwVXhIREFhQmdOVkJBb01FMHRsZVdaaFkzUnZjaUJEYjIxdGRXNXBkSGt4SERBYQpCZ05WQkFNTUUwMTVJRkJMU1NCU2IyOTBJRU5CSUMwZ1J6RXdIaGNOTWpNd01USXpNVFl5TkRRMVdoY05Nemd3Ck1URTVNVFl5TkRRMFdqQklNUXN3Q1FZRFZRUUdFd0pUUlRFY01Cb0dBMVVFQ2d3VFMyVjVabUZqZEc5eUlFTnYKYlcxMWJtbDBlVEViTUJrR0ExVUVBd3dTVFhrZ1VFdEpJRk4xWWlCRFFTQXRJRWN4TUZrd0V3WUhLb1pJemowQwpBUVlJS29aSXpqMERBUWNEUWdBRTZqUVhWWk9ha2JQNjFtdG5WVXcvVVl2RzNmQXhRdERBTjZqY0l6bzJLVXpqCmNaSzJkQ3BZUWhpZWdzQ0NLa20xYUhKYXlRNVFTb3hDcVFhUjUyYjZWYU9DQVFRd2dnRUFNQklHQTFVZEV3RUIKL3dRSU1BWUJBZjhDQVFBd0h3WURWUjBqQkJnd0ZvQVUxYzZkYUpDOWlJUzhQNzVlUTZybzB5UjRCNVV3WWdZSQpLd1lCQlFVSEFRRUVWakJVTURJR0NDc0dBUVVGQnpBQ2hpWm9kSFJ3T2k4dmJYa3VjR3RwTDJObGNuUnpMMDE1ClVFdEpVbTl2ZEVOQkxVY3hMbU55ZERBZUJnZ3JCZ0VGQlFjd0FZWVNhSFIwY0RvdkwyMTVMbkJyYVM5dlkzTncKTURZR0ExVWRId1F2TUMwd0s2QXBvQ2VHSldoMGRIQTZMeTl0ZVM1d2Eya3ZZM0pzY3k5TmVWQkxTVkp2YjNSRApRUzFITVM1amNtd3dIUVlEVlIwT0JCWUVGTERsZjNaMDRpcTR1UGhZWlRQZ1lxSEtwRlB0TUE0R0ExVWREd0VCCi93UUVBd0lCaGpBS0JnZ3Foa2pPUFFRREJBTklBREJGQWlBWGN5VjdOdW1PU0RCMDVmeFBqMnRlR3RSWm1vMi8KMklIb0duY3MrNStyaVFJaEFPUEpyZEpTdTYzbFFxRXJwdks2cm1adkxobnE4ZXFHYkF6ekx0WVVseXVWCi0tLS0tRU5EIENFUlRJRklDQVRFLS0tLS0KLS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUIyRENDQVg2Z0F3SUJBZ0lVQXV1TDFjL0FvRndzZnhnVXJPdmFSWGxkT1drd0NnWUlLb1pJemowRUF3UXcKU1RFTE1Ba0dBMVVFQmhNQ1UwVXhIREFhQmdOVkJBb01FMHRsZVdaaFkzUnZjaUJEYjIxdGRXNXBkSGt4SERBYQpCZ05WQkFNTUUwMTVJRkJMU1NCU2IyOTBJRU5CSUMwZ1J6RXdJQmNOTWpNd01USXpNVFl4T0RVNFdoZ1BNakExCk16QXhNVFV4TmpFNE5UZGFNRWt4Q3pBSkJnTlZCQVlUQWxORk1Sd3dHZ1lEVlFRS0RCTkxaWGxtWVdOMGIzSWcKUTI5dGJYVnVhWFI1TVJ3d0dnWURWUVFEREJOTmVTQlFTMGtnVW05dmRDQkRRU0F0SUVjeE1Ga3dFd1lIS29aSQp6ajBDQVFZSUtvWkl6ajBEQVFjRFFnQUVJTUw3a05LR0NqaktmeHd5Qi9zNHF0cEZnMi9hT1ZDZUFCeUVlRE1XCmR6SFlMTU9pZDQ5MDFaUFA1ak1HZ2hxODQreXp6TDV2Q1VYVEtCNDR6SmxVOXFOQ01FQXdEd1lEVlIwVEFRSC8KQkFVd0F3RUIvekFkQmdOVkhRNEVGZ1FVMWM2ZGFKQzlpSVM4UDc1ZVE2cm8weVI0QjVVd0RnWURWUjBQQVFILwpCQVFEQWdHR01Bb0dDQ3FHU000OUJBTUVBMGdBTUVVQ0lRQ2lGTi9vKytaK0FYa1ZVbk0yTTQydm1WVitLUGZMCnZka1JhT0g3RklJTEV3SWdFejBST1BQcFpBMlhGU2ExZG9ma0FZMWg1aUFid2c2Vk9hSTNLZm9hYlZBPQotLS0tLUVORCBDRVJUSUZJQ0FURS0tLS0tCg==
      Certificate: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUN5akNDQW5DZ0F3SUJBZ0lVWStUTkNXdHRLc0RmcXREL0ZpZS9aRSsvYzQ4d0NnWUlLb1pJemowRUF3UXcKU0RFTE1Ba0dBMVVFQmhNQ1UwVXhIREFhQmdOVkJBb01FMHRsZVdaaFkzUnZjaUJEYjIxdGRXNXBkSGt4R3pBWgpCZ05WQkFNTUVrMTVJRkJMU1NCVGRXSWdRMEVnTFNCSE1UQWVGdzB5TkRBeE1qWXhNREU1TkRaYUZ3MHlOVEF4Ck1qTXhNREU1TkRWYU1Fa3hDekFKQmdOVkJBWVRBbE5GTVJ3d0dnWURWUVFLREJOTFpYbG1ZV04wYjNJZ1EyOXQKYlhWdWFYUjVNUnd3R2dZRFZRUUREQk4wWlhOMExXTnRMVEF4TG5CcmFYSjFiR1Z6TUZrd0V3WUhLb1pJemowQwpBUVlJS29aSXpqMERBUWNEUWdBRTFTU2lyR25EUjNKMFBaaFlZZHk5QUtNcVppanNCKzVmNXhqR09OaWN0K3BUCk1hRDM4MHRmZDVBUmdMQ013MVB5L2V1cGErUnQvaEo5Q0loYWdVZG5YYU9DQVRVd2dnRXhNQjhHQTFVZEl3UVkKTUJhQUZMRGxmM1owNGlxNHVQaFlaVFBnWXFIS3BGUHRNR0VHQ0NzR0FRVUZCd0VCQkZVd1V6QXhCZ2dyQmdFRgpCUWN3QW9ZbGFIUjBjRG92TDIxNUxuQnJhUzlqWlhKMGN5OU5lVkJMU1ZOMVlrTkJMVWN4TG1OeWREQWVCZ2dyCkJnRUZCUWN3QVlZU2FIUjBjRG92TDIxNUxuQnJhUzl2WTNOd01EQUdBMVVkRVFRcE1DZUNFSFJsYzNRdFkyMHUKY0d0cGNuVnNaWE9DRTNSbGMzUXRZMjB0TURFdWNHdHBjblZzWlhNd0V3WURWUjBsQkF3d0NnWUlLd1lCQlFVSApBd0V3TlFZRFZSMGZCQzR3TERBcW9DaWdKb1lrYUhSMGNEb3ZMMjE1TG5CcmFTOWpjbXh6TDAxNVVFdEpVM1ZpClEwRXRSekV1WTNKc01CMEdBMVVkRGdRV0JCVFQ4YTJEUTEwSGZCenhPc05LS3J1NVBGYU5LekFPQmdOVkhROEIKQWY4RUJBTUNCYUF3Q2dZSUtvWkl6ajBFQXdRRFNBQXdSUUlnVGhtdTdsTUFZM092Nnk3SmloWmdHMTZRNzYvdgpzVVlGanlYT1NiVEFUZVFDSVFEK2ZRbldlSWRXeVlhYU1HdElhMnVJbURFTE1PeWN1eFZKRVd3YXYvZ3hTQT09Ci0tLS0tRU5EIENFUlRJRklDQVRFLS0tLS0K
      Conditions:
      Last Transition Time: 2024-01-26T10:29:46Z
      Message: Certificate request has been approved by cert-manager.io
      Reason: cert-manager.io
      Status: True
      Type: Approved
      Last Transition Time: 2024-01-26T10:29:46Z
      Message: Signed
      Reason: Issued
      Status: True
      Type: Ready
      Events:
      Type Reason Age From Message
      ---- ------ ---- ---- -------
      Normal cert-manager.io 3m57s cert-manager-certificaterequests-approver Certificate request has been approved by cert-manager.io
      
      CODE
       
  10. The certificate can be obtained from the output and decoded with base64 to view:

    $ echo "LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUN5akNDQW5DZ0F3SUJBZ0lVWStUTkNXdHRLc0RmcXREL0ZpZS9aRSsvYzQ4d0NnWUlLb1pJemowRUF3UXcKU0RFTE1Ba0dBMVVFQmhNQ1UwVXhIREFhQmdOVkJBb01FMHRsZVdaaFkzUnZjaUJEYjIxdGRXNXBkSGt4R3pBWgpCZ05WQkFNTUVrMTVJRkJMU1NCVGRXSWdRMEVnTFNCSE1UQWVGdzB5TkRBeE1qWXhNREU1TkRaYUZ3MHlOVEF4Ck1qTXhNREU1TkRWYU1Fa3hDekFKQmdOVkJBWVRBbE5GTVJ3d0dnWURWUVFLREJOTFpYbG1ZV04wYjNJZ1EyOXQKYlhWdWFYUjVNUnd3R2dZRFZRUUREQk4wWlhOMExXTnRMVEF4TG5CcmFYSjFiR1Z6TUZrd0V3WUhLb1pJemowQwpBUVlJS29aSXpqMERBUWNEUWdBRTFTU2lyR25EUjNKMFBaaFlZZHk5QUtNcVppanNCKzVmNXhqR09OaWN0K3BUCk1hRDM4MHRmZDVBUmdMQ013MVB5L2V1cGErUnQvaEo5Q0loYWdVZG5YYU9DQVRVd2dnRXhNQjhHQTFVZEl3UVkKTUJhQUZMRGxmM1owNGlxNHVQaFlaVFBnWXFIS3BGUHRNR0VHQ0NzR0FRVUZCd0VCQkZVd1V6QXhCZ2dyQmdFRgpCUWN3QW9ZbGFIUjBjRG92TDIxNUxuQnJhUzlqWlhKMGN5OU5lVkJMU1ZOMVlrTkJMVWN4TG1OeWREQWVCZ2dyCkJnRUZCUWN3QVlZU2FIUjBjRG92TDIxNUxuQnJhUzl2WTNOd01EQUdBMVVkRVFRcE1DZUNFSFJsYzNRdFkyMHUKY0d0cGNuVnNaWE9DRTNSbGMzUXRZMjB0TURFdWNHdHBjblZzWlhNd0V3WURWUjBsQkF3d0NnWUlLd1lCQlFVSApBd0V3TlFZRFZSMGZCQzR3TERBcW9DaWdKb1lrYUhSMGNEb3ZMMjE1TG5CcmFTOWpjbXh6TDAxNVVFdEpVM1ZpClEwRXRSekV1WTNKc01CMEdBMVVkRGdRV0JCVFQ4YTJEUTEwSGZCenhPc05LS3J1NVBGYU5LekFPQmdOVkhROEIKQWY4RUJBTUNCYUF3Q2dZSUtvWkl6ajBFQXdRRFNBQXdSUUlnVGhtdTdsTUFZM092Nnk3SmloWmdHMTZRNzYvdgpzVVlGanlYT1NiVEFUZVFDSVFEK2ZRbldlSWRXeVlhYU1HdElhMnVJbURFTE1PeWN1eFZKRVd3YXYvZ3hTQT09Ci0tLS0tRU5EIENFUlRJRklDQVRFLS0tLS0K" | base64 -d
    
    CODE
     
    • The output is similar to the following:

      -----BEGIN CERTIFICATE-----
      MIICyjCCAnCgAwIBAgIUY+TNCWttKsDfqtD/Fie/ZE+/c48wCgYIKoZIzj0EAwQw
      SDELMAkGA1UEBhMCU0UxHDAaBgNVBAoME0tleWZhY3RvciBDb21tdW5pdHkxGzAZ
      BgNVBAMMEk15IFBLSSBTdWIgQ0EgLSBHMTAeFw0yNDAxMjYxMDE5NDZaFw0yNTAx
      MjMxMDE5NDVaMEkxCzAJBgNVBAYTAlNFMRwwGgYDVQQKDBNLZXlmYWN0b3IgQ29t
      bXVuaXR5MRwwGgYDVQQDDBN0ZXN0LWNtLTAxLnBraXJ1bGVzMFkwEwYHKoZIzj0C
      AQYIKoZIzj0DAQcDQgAE1SSirGnDR3J0PZhYYdy9AKMqZijsB+5f5xjGONict+pT
      MaD380tfd5ARgLCMw1Py/eupa+Rt/hJ9CIhagUdnXaOCATUwggExMB8GA1UdIwQY
      MBaAFLDlf3Z04iq4uPhYZTPgYqHKpFPtMGEGCCsGAQUFBwEBBFUwUzAxBggrBgEF
      BQcwAoYlaHR0cDovL215LnBraS9jZXJ0cy9NeVBLSVN1YkNBLUcxLmNydDAeBggr
      BgEFBQcwAYYSaHR0cDovL215LnBraS9vY3NwMDAGA1UdEQQpMCeCEHRlc3QtY20u
      cGtpcnVsZXOCE3Rlc3QtY20tMDEucGtpcnVsZXMwEwYDVR0lBAwwCgYIKwYBBQUH
      AwEwNQYDVR0fBC4wLDAqoCigJoYkaHR0cDovL215LnBraS9jcmxzL015UEtJU3Vi
      Q0EtRzEuY3JsMB0GA1UdDgQWBBTT8a2DQ10HfBzxOsNKKru5PFaNKzAOBgNVHQ8B
      Af8EBAMCBaAwCgYIKoZIzj0EAwQDSAAwRQIgThmu7lMAY3Ov6y7JihZgG16Q76/v
      sUYFjyXOSbTATeQCIQD+fQnWeIdWyYaaMGtIa2uImDELMOycuxVJEWwav/gxSA==
      -----END CERTIFICATE-----
      CODE
       
  11. The certificate is ready to use from the manual request.

Certificate Kind Object Request

  1. Create the test-cm-02.pkirules.yaml file to create a certificate with the certificate kind object:

     $ cat > test-cm-02.pkirules.yaml <<EOF
    apiVersion: cert-manager.io/v1
    kind: Certificate
    metadata:
      name: test-cm-02.pkirules
      namespace: pkirules
    spec:
      subject:
        countries:
          - SE
        organizations:
          - Keyfactor Community
      commonName: test-cm-02.pkirules
      #dnsNames:
        #- test-cm-02.pkirules
      privateKey:
        algorithm: ECDSA
        size: 256
      secretName: test-cm-02
      issuerRef:
        name: pkirules-tls
        group: ejbca-issuer.keyfactor.com
        kind: Issuer
    EOF
    CODE
     
  2. Apply the test-cm-02.pkirules.yaml file which enrolls for a certificate with cert-manager and creates a secret for the private key:

     $ kubectl apply -f test-cm-02.pkirules.yaml
    CODE
     
    • The output is similar to the following:

       certificate.cert-manager.io/test-cm-02.pkirules created
      CODE
       
  3. List the certificate requests:

     $ kubectl -n pkirules get CertificateRequest
    CODE
     
    • The output is similar to the following:

       NAME                    APPROVED   DENIED   READY   ISSUER         REQUESTOR                                         AGE
      test-cm-01.pkirules     True                True    pkirules-tls   admin                                             68m
      test-cm-02.pkirules-1   True                True    pkirules-tls   system:serviceaccount:cert-manager:cert-manager   4m36s
      CODE
       
  4. Describe the test-cm-02.pkirules-1 certificate request:

    $ kubectl -n pkirules describe CertificateRequest test-cm-02.pkirules-1 
    CODE
     
    • The output is similar to the following:

       Name:         test-cm-02.pkirules-1
      Namespace:    pkirules
      Labels:       <none>
      Annotations:  cert-manager.io/certificate-name: test-cm-02.pkirules
                    cert-manager.io/certificate-revision: 1
                    cert-manager.io/private-key-secret-name: test-cm-02.pkirules-qkncz
      API Version:  cert-manager.io/v1
      Kind:         CertificateRequest
      Metadata:
        Creation Timestamp:  2024-01-26T11:33:44Z
        Generation:          1
        Managed Fields:
          API Version:  cert-manager.io/v1
          Fields Type:  FieldsV1
          fieldsV1:
            f:status:
              f:conditions:
                .:
                k:{"type":"Approved"}:
                  .:
                  f:lastTransitionTime:
                  f:message:
                  f:reason:
                  f:status:
                  f:type:
          Manager:      cert-manager-certificaterequests-approver
          Operation:    Update
          Subresource:  status
          Time:         2024-01-26T11:33:44Z
          API Version:  cert-manager.io/v1
          Fields Type:  FieldsV1
          fieldsV1:
            f:metadata:
              f:annotations:
                .:
                f:cert-manager.io/certificate-name:
                f:cert-manager.io/certificate-revision:
                f:cert-manager.io/private-key-secret-name:
              f:ownerReferences:
                .:
                k:{"uid":"9298479a-3cc1-4370-9146-a1c361007c4a"}:
            f:spec:
              .:
              f:issuerRef:
                .:
                f:group:
                f:kind:
                f:name:
              f:request:
          Manager:      cert-manager-certificates-request-manager
          Operation:    Update
          Time:         2024-01-26T11:33:44Z
          API Version:  cert-manager.io/v1
          Fields Type:  FieldsV1
          fieldsV1:
            f:status:
              .:
              f:ca:
              f:certificate:
              f:conditions:
                k:{"type":"Ready"}:
                  .:
                  f:lastTransitionTime:
                  f:message:
                  f:reason:
                  f:status:
                  f:type:
          Manager:      manager
          Operation:    Update
          Subresource:  status
          Time:         2024-01-26T11:33:44Z
        Owner References:
          API Version:           cert-manager.io/v1
          Block Owner Deletion:  true
          Controller:            true
          Kind:                  Certificate
          Name:                  test-cm-02.pkirules
          UID:                   9298479a-3cc1-4370-9146-a1c361007c4a
        Resource Version:        662225
        UID:                     8e9a8b60-07fa-4573-b1fe-23f3e67e2c39
      Spec:
        Extra:
          authentication.kubernetes.io/pod-name:
            cert-manager-55cf8685cb-tztzk
          authentication.kubernetes.io/pod-uid:
            6c69ccc4-46d3-45fd-a942-ec0df90a7ecc
        Groups:
          system:serviceaccounts
          system:serviceaccounts:cert-manager
          system:authenticated
        Issuer Ref:
          Group:   ejbca-issuer.keyfactor.com
          Kind:    Issuer
          Name:    pkirules-tls
        Request:   LS0tLS1CRUdJTiBDRVJUSUZJQ0FURSBSRVFVRVNULS0tLS0KTUlJQklUQ0J5UUlCQURCSk1Rc3dDUVlEVlFRR0V3SlRSVEVjTUJvR0ExVUVDaE1UUzJWNVptRmpkRzl5SUVOdgpiVzExYm1sMGVURWNNQm9HQTFVRUF4TVRkR1Z6ZEMxamJTMHdNaTV3YTJseWRXeGxjekJaTUJNR0J5cUdTTTQ5CkFnRUdDQ3FHU000OUF3RUhBMElBQkdQWXFsU3hhM0xIUUhCYW9aMkVKNnVxcnNPb2xrQjV1UnBReHJPZzc1SDAKdEUzR3UvNFd5YW9jTVRqTWtPQlBjOGsxcUI0Wm52anozWFREeU5ZYmFKaWdIakFjQmdrcWhraUc5dzBCQ1E0eApEekFOTUFzR0ExVWREd1FFQXdJRm9EQUtCZ2dxaGtqT1BRUURBZ05IQURCRUFpQjE0ckp4YkRaRlhnc2tDRW42Ci9xN1FvdDF5UncyYWxFWHJ4TEcwc1FLWUN3SWdSeTRidnNtdllWQ0laTVBPd0FKWG9GaW12Zk5HZGJOSXRhb1cKNlJVMGZMRT0KLS0tLS1FTkQgQ0VSVElGSUNBVEUgUkVRVUVTVC0tLS0tCg==
        UID:       9ec1c31a-f7af-486c-b881-92d55dd4da1f
        Username:  system:serviceaccount:cert-manager:cert-manager
      Status:
        Ca:           LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUNtVENDQWorZ0F3SUJBZ0lVSjBlTDlJbmxubWNDRWpxT3pPTmZOdFZ2QVRFd0NnWUlLb1pJemowRUF3UXcKU1RFTE1Ba0dBMVVFQmhNQ1UwVXhIREFhQmdOVkJBb01FMHRsZVdaaFkzUnZjaUJEYjIxdGRXNXBkSGt4SERBYQpCZ05WQkFNTUUwMTVJRkJMU1NCU2IyOTBJRU5CSUMwZ1J6RXdIaGNOTWpNd01USXpNVFl5TkRRMVdoY05Nemd3Ck1URTVNVFl5TkRRMFdqQklNUXN3Q1FZRFZRUUdFd0pUUlRFY01Cb0dBMVVFQ2d3VFMyVjVabUZqZEc5eUlFTnYKYlcxMWJtbDBlVEViTUJrR0ExVUVBd3dTVFhrZ1VFdEpJRk4xWWlCRFFTQXRJRWN4TUZrd0V3WUhLb1pJemowQwpBUVlJS29aSXpqMERBUWNEUWdBRTZqUVhWWk9ha2JQNjFtdG5WVXcvVVl2RzNmQXhRdERBTjZqY0l6bzJLVXpqCmNaSzJkQ3BZUWhpZWdzQ0NLa20xYUhKYXlRNVFTb3hDcVFhUjUyYjZWYU9DQVFRd2dnRUFNQklHQTFVZEV3RUIKL3dRSU1BWUJBZjhDQVFBd0h3WURWUjBqQkJnd0ZvQVUxYzZkYUpDOWlJUzhQNzVlUTZybzB5UjRCNVV3WWdZSQpLd1lCQlFVSEFRRUVWakJVTURJR0NDc0dBUVVGQnpBQ2hpWm9kSFJ3T2k4dmJYa3VjR3RwTDJObGNuUnpMMDE1ClVFdEpVbTl2ZEVOQkxVY3hMbU55ZERBZUJnZ3JCZ0VGQlFjd0FZWVNhSFIwY0RvdkwyMTVMbkJyYVM5dlkzTncKTURZR0ExVWRId1F2TUMwd0s2QXBvQ2VHSldoMGRIQTZMeTl0ZVM1d2Eya3ZZM0pzY3k5TmVWQkxTVkp2YjNSRApRUzFITVM1amNtd3dIUVlEVlIwT0JCWUVGTERsZjNaMDRpcTR1UGhZWlRQZ1lxSEtwRlB0TUE0R0ExVWREd0VCCi93UUVBd0lCaGpBS0JnZ3Foa2pPUFFRREJBTklBREJGQWlBWGN5VjdOdW1PU0RCMDVmeFBqMnRlR3RSWm1vMi8KMklIb0duY3MrNStyaVFJaEFPUEpyZEpTdTYzbFFxRXJwdks2cm1adkxobnE4ZXFHYkF6ekx0WVVseXVWCi0tLS0tRU5EIENFUlRJRklDQVRFLS0tLS0KLS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUIyRENDQVg2Z0F3SUJBZ0lVQXV1TDFjL0FvRndzZnhnVXJPdmFSWGxkT1drd0NnWUlLb1pJemowRUF3UXcKU1RFTE1Ba0dBMVVFQmhNQ1UwVXhIREFhQmdOVkJBb01FMHRsZVdaaFkzUnZjaUJEYjIxdGRXNXBkSGt4SERBYQpCZ05WQkFNTUUwMTVJRkJMU1NCU2IyOTBJRU5CSUMwZ1J6RXdJQmNOTWpNd01USXpNVFl4T0RVNFdoZ1BNakExCk16QXhNVFV4TmpFNE5UZGFNRWt4Q3pBSkJnTlZCQVlUQWxORk1Sd3dHZ1lEVlFRS0RCTkxaWGxtWVdOMGIzSWcKUTI5dGJYVnVhWFI1TVJ3d0dnWURWUVFEREJOTmVTQlFTMGtnVW05dmRDQkRRU0F0SUVjeE1Ga3dFd1lIS29aSQp6ajBDQVFZSUtvWkl6ajBEQVFjRFFnQUVJTUw3a05LR0NqaktmeHd5Qi9zNHF0cEZnMi9hT1ZDZUFCeUVlRE1XCmR6SFlMTU9pZDQ5MDFaUFA1ak1HZ2hxODQreXp6TDV2Q1VYVEtCNDR6SmxVOXFOQ01FQXdEd1lEVlIwVEFRSC8KQkFVd0F3RUIvekFkQmdOVkhRNEVGZ1FVMWM2ZGFKQzlpSVM4UDc1ZVE2cm8weVI0QjVVd0RnWURWUjBQQVFILwpCQVFEQWdHR01Bb0dDQ3FHU000OUJBTUVBMGdBTUVVQ0lRQ2lGTi9vKytaK0FYa1ZVbk0yTTQydm1WVitLUGZMCnZka1JhT0g3RklJTEV3SWdFejBST1BQcFpBMlhGU2ExZG9ma0FZMWg1aUFid2c2Vk9hSTNLZm9hYlZBPQotLS0tLUVORCBDRVJUSUZJQ0FURS0tLS0tCg==
        Certificate:  LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUN1RENDQWw2Z0F3SUJBZ0lVUGJYV3I5b1VIVUNzamtsZXBkY3Bva0s5V2JBd0NnWUlLb1pJemowRUF3UXcKU0RFTE1Ba0dBMVVFQmhNQ1UwVXhIREFhQmdOVkJBb01FMHRsZVdaaFkzUnZjaUJEYjIxdGRXNXBkSGt4R3pBWgpCZ05WQkFNTUVrMTVJRkJMU1NCVGRXSWdRMEVnTFNCSE1UQWVGdzB5TkRBeE1qWXhNVEl6TkRSYUZ3MHlOVEF4Ck1qTXhNVEl6TkROYU1Fa3hDekFKQmdOVkJBWVRBbE5GTVJ3d0dnWURWUVFLREJOTFpYbG1ZV04wYjNJZ1EyOXQKYlhWdWFYUjVNUnd3R2dZRFZRUUREQk4wWlhOMExXTnRMVEF5TG5CcmFYSjFiR1Z6TUZrd0V3WUhLb1pJemowQwpBUVlJS29aSXpqMERBUWNEUWdBRVk5aXFWTEZyY3NkQWNGcWhuWVFucTZxdXc2aVdRSG01R2xER3M2RHZrZlMwClRjYTcvaGJKcWh3eE9NeVE0RTl6eVRXb0hobWUrUFBkZE1QSTFodG9tS09DQVNNd2dnRWZNQjhHQTFVZEl3UVkKTUJhQUZMRGxmM1owNGlxNHVQaFlaVFBnWXFIS3BGUHRNR0VHQ0NzR0FRVUZCd0VCQkZVd1V6QXhCZ2dyQmdFRgpCUWN3QW9ZbGFIUjBjRG92TDIxNUxuQnJhUzlqWlhKMGN5OU5lVkJMU1ZOMVlrTkJMVWN4TG1OeWREQWVCZ2dyCkJnRUZCUWN3QVlZU2FIUjBjRG92TDIxNUxuQnJhUzl2WTNOd01CNEdBMVVkRVFRWE1CV0NFM1JsYzNRdFkyMHQKTURJdWNHdHBjblZzWlhNd0V3WURWUjBsQkF3d0NnWUlLd1lCQlFVSEF3RXdOUVlEVlIwZkJDNHdMREFxb0NpZwpKb1lrYUhSMGNEb3ZMMjE1TG5CcmFTOWpjbXh6TDAxNVVFdEpVM1ZpUTBFdFJ6RXVZM0pzTUIwR0ExVWREZ1FXCkJCUmJDNDJRV2dBNGdwWTdBeU9HU1k2eTJOakpPakFPQmdOVkhROEJBZjhFQkFNQ0JhQXdDZ1lJS29aSXpqMEUKQXdRRFNBQXdSUUloQU9tZWNCejN3YnVxU2psei9PZlNsdDJhOXMzOTMvV05oc2pWOEJ1akRoSE5BaUJ2Y0owNQorWk45UWRmNFEzbDFRY3hmakRnWW1IeWl4SElmci91dlBHbk9Ddz09Ci0tLS0tRU5EIENFUlRJRklDQVRFLS0tLS0K
        Conditions:
          Last Transition Time:  2024-01-26T11:33:44Z
          Message:               Certificate request has been approved by cert-manager.io
          Reason:                cert-manager.io
          Status:                True
          Type:                  Approved
          Last Transition Time:  2024-01-26T11:33:44Z
          Message:               Signed
          Reason:                Issued
          Status:                True
          Type:                  Ready
      Events:                    <none>
      CODE
       
  5. List the certificates created:

     $ kubectl -n pkirules get certificate
    CODE
     
    • The output is similar to the following:

       NAME                  READY   SECRET       AGE
      test-cm-02.pkirules   True    test-cm-02   9m51s
      CODE
       
  6. Describe the test-cm-02.pkirules certificate:

     $ kubectl -n pkirules describe certificate test-cm-02.pkirules
    CODE
     
    • The output is similar to the following:

       Name:         test-cm-02.pkirules
      Namespace:    pkirules
      Labels:       <none>
      Annotations:  <none>
      API Version:  cert-manager.io/v1
      Kind:         Certificate
      Metadata:
        Creation Timestamp:  2024-01-26T11:33:44Z
        Generation:          1
        Managed Fields:
          API Version:  cert-manager.io/v1
          Fields Type:  FieldsV1
          fieldsV1:
            f:status:
              f:revision:
          Manager:      cert-manager-certificates-issuing
          Operation:    Update
          Subresource:  status
          Time:         2024-01-26T11:33:44Z
          API Version:  cert-manager.io/v1
          Fields Type:  FieldsV1
          fieldsV1:
            f:status:
              .:
              f:conditions:
                .:
                k:{"type":"Ready"}:
                  .:
                  f:lastTransitionTime:
                  f:message:
                  f:observedGeneration:
                  f:reason:
                  f:status:
                  f:type:
              f:notAfter:
              f:notBefore:
              f:renewalTime:
          Manager:      cert-manager-certificates-readiness
          Operation:    Update
          Subresource:  status
          Time:         2024-01-26T11:33:44Z
          API Version:  cert-manager.io/v1
          Fields Type:  FieldsV1
          fieldsV1:
            f:metadata:
              f:annotations:
                .:
                f:kubectl.kubernetes.io/last-applied-configuration:
            f:spec:
              .:
              f:commonName:
              f:issuerRef:
                .:
                f:group:
                f:kind:
                f:name:
              f:privateKey:
                .:
                f:algorithm:
                f:size:
              f:secretName:
              f:subject:
                .:
                f:countries:
                f:organizations:
          Manager:         kubectl-client-side-apply
          Operation:       Update
          Time:            2024-01-26T11:33:44Z
        Resource Version:  662231
        UID:               9298479a-3cc1-4370-9146-a1c361007c4a
      Spec:
        Common Name:  test-cm-02.pkirules
        Issuer Ref:
          Group:  ejbca-issuer.keyfactor.com
          Kind:   Issuer
          Name:   pkirules-tls
        Private Key:
          Algorithm:  ECDSA
          Size:       256
        Secret Name:  test-cm-02
        Subject:
          Countries:
            SE
          Organizations:
            Keyfactor Community
      Status:
        Conditions:
          Last Transition Time:  2024-01-26T11:33:44Z
          Message:               Certificate is up to date and has not expired
          Observed Generation:   1
          Reason:                Ready
          Status:                True
          Type:                  Ready
        Not After:               2025-01-23T11:23:43Z
        Not Before:              2024-01-26T11:23:44Z
        Renewal Time:            2024-09-24T11:23:43Z
        Revision:                1
      Events:                    <none>
      CODE
       
  7. List the secrets:

     $ kubectl -n pkirules get secrets
    CODE
     
    • The output is similar to the following:

       NAME         TYPE                DATA   AGE
      test-cm-02   kubernetes.io/tls   3      13m
      CODE
       
  8. Describe the test-cm-02 secret:

     $ kubectl -n pkirules describe secrets test-cm-02
    CODE
     
    • The output is similar to the following:

      Name:         test-cm-02
      Namespace:    pkirules
      Labels:       controller.cert-manager.io/fao=true
      Annotations:  cert-manager.io/alt-names: test-cm-02.pkirules
                    cert-manager.io/certificate-name: test-cm-02.pkirules
                    cert-manager.io/common-name: test-cm-02.pkirules
                    cert-manager.io/ip-sans:
                    cert-manager.io/issuer-group: ejbca-issuer.keyfactor.com
                    cert-manager.io/issuer-kind: Issuer
                    cert-manager.io/issuer-name: pkirules-tls
                    cert-manager.io/subject-countries: SE
                    cert-manager.io/subject-organizations: Keyfactor Community
                    cert-manager.io/uri-sans:
      
      Type:  kubernetes.io/tls
      
      Data
      ====
      ca.crt:   1660 bytes
      tls.crt:  1005 bytes
      tls.key:  227 bytes
      CODE
       
  9. The certificate can now be used, for example by mounting the secret into a container.

Request certificate for Ingress using a simple deployment

  1. Create the simple deployment YAML file to deploy a container and issue a certificate to ingress:

     $ cat > ejbca-cm-issuer-hello-world.yaml <<EOF
    ---
    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: ejbca-cm-issuer-helloworld-one
      namespace: pkirules
    spec:
      replicas: 1
      selector:
        matchLabels:
          app: ejbca-cm-issuer-helloworld-one
      template:
        metadata:
          labels:
            app: ejbca-cm-issuer-helloworld-one
        spec:
          containers:
          - name: ejbca-cm-issuer-helloworld-one
            image: hashicorp/http-echo:latest
            ports:
            - containerPort: 80
    ---
    apiVersion: v1
    kind: Service
    metadata:
      name: helloworld
      namespace: pkirules
    spec:
      #type: ClusterIP
      ports:
      - port: 80
        targetPort: 80
        protocol: TCP
      selector:
        app: ejbca-cm-issuer-helloworld-one
    
    apiVersion: networking.k8s.io/v1
    kind: Ingress
    metadata:
      name: hellowworld-ingress
      namespace: pkirules
      annotations:
        cert-manager.io/issuer: "pkirules-tls"
        cert-manager.io/issuer-kind: "Issuer"
        cert-manager.io/issuer-group: "ejbca-issuer.keyfactor.com"
        cert-manager.io/common-name: "test-cm-03.pkirules"
        cert-manager.io/subject-organizations: "Keyfactor Community"
        cert-manager.io/subject-countries: "SE"
        cert-manager.io/private-key-algorithm: "ECDSA"
        cert-manager.io/private-key-size: "256"
    spec:
      ingressClassName: public
      tls:
      - hosts:
        - test-cm-03.pkirules
        secretName: test-cm-03.pkirules
      rules:
      - host: test-cm-03.pkirules
        http:
          paths:
          - path: /
            pathType: Prefix
            backend:
              service:
                name: helloworld
                port:
                  number: 80
    EOF
    CODE
     
  2. Apply ejbca-cm-issuer-hello-world.yaml file which starts the deployment and requests a certificate for Ingress using cert-manager:

     $ kubectl apply -f ejbca-cm-issuer-hello-world.yaml
    CODE
     
    • The output is similar to the following:

       deployment.apps/ejbca-cm-issuer-helloworld-one created
      ingress.networking.k8s.io/hellowworld-ingress created
      CODE
       
  3. List the certificate requests:

    $ kubectl -n pkirules get CertificateRequest
    CODE
     
    • The output is similar to the following:

       NAME                    APPROVED   DENIED   READY   ISSUER         REQUESTOR                                         AGE
      test-cm-01.pkirules     True                True    pkirules-tls   admin                                             177m
      test-cm-02.pkirules-1   True                True    pkirules-tls   system:serviceaccount:cert-manager:cert-manager   113m
      test-cm-03.pkirules-1   True                True    pkirules-tls   system:serviceaccount:cert-manager:cert-manager   65s
      CODE
       
  4. Describe the test-cm-03.pkirules-1 certificate request:

     $ kubectl -n pkirules describe CertificateRequest test-cm-03.pkirules-1
    CODE

    • The output is similar to the following:

       Name:         test-cm-03.pkirules-1
      Namespace:    pkirules
      Labels:       <none>
      Annotations:  cert-manager.io/certificate-name: test-cm-03.pkirules
                    cert-manager.io/certificate-revision: 1
                    cert-manager.io/private-key-secret-name: test-cm-03.pkirules-fkdg8
      API Version:  cert-manager.io/v1
      Kind:         CertificateRequest
      Metadata:
        Creation Timestamp:  2024-01-26T13:26:35Z
        Generation:          1
        Managed Fields:
          API Version:  cert-manager.io/v1
          Fields Type:  FieldsV1
          fieldsV1:
            f:status:
              f:conditions:
                .:
                k:{"type":"Approved"}:
                  .:
                  f:lastTransitionTime:
                  f:message:
                  f:reason:
                  f:status:
                  f:type:
          Manager:      cert-manager-certificaterequests-approver
          Operation:    Update
          Subresource:  status
          Time:         2024-01-26T13:26:35Z
          API Version:  cert-manager.io/v1
          Fields Type:  FieldsV1
          fieldsV1:
            f:metadata:
              f:annotations:
                .:
                f:cert-manager.io/certificate-name:
                f:cert-manager.io/certificate-revision:
                f:cert-manager.io/private-key-secret-name:
              f:ownerReferences:
                .:
                k:{"uid":"9ec95bfc-a645-417c-9634-8e727bdeacf3"}:
            f:spec:
              .:
              f:issuerRef:
                .:
                f:group:
                f:kind:
                f:name:
              f:request:
              f:usages:
          Manager:      cert-manager-certificates-request-manager
          Operation:    Update
          Time:         2024-01-26T13:26:35Z
          API Version:  cert-manager.io/v1
          Fields Type:  FieldsV1
          fieldsV1:
            f:status:
              .:
              f:ca:
              f:certificate:
              f:conditions:
                k:{"type":"Ready"}:
                  .:
                  f:lastTransitionTime:
                  f:message:
                  f:reason:
                  f:status:
                  f:type:
          Manager:      manager
          Operation:    Update
          Subresource:  status
          Time:         2024-01-26T13:26:35Z
        Owner References:
          API Version:           cert-manager.io/v1
          Block Owner Deletion:  true
          Controller:            true
          Kind:                  Certificate
          Name:                  test-cm-03.pkirules
          UID:                   9ec95bfc-a645-417c-9634-8e727bdeacf3
        Resource Version:        683881
        UID:                     347ccb7b-fb8c-4e26-97da-d22739a565cc
      Spec:
        Extra:
          authentication.kubernetes.io/pod-name:
            cert-manager-55cf8685cb-tztzk
          authentication.kubernetes.io/pod-uid:
            6c69ccc4-46d3-45fd-a942-ec0df90a7ecc
        Groups:
          system:serviceaccounts
          system:serviceaccounts:cert-manager
          system:authenticated
        Issuer Ref:
          Group:  ejbca-issuer.keyfactor.com
          Kind:   Issuer
          Name:   pkirules-tls
        Request:  LS0tLS1CRUdJTiBDRVJUSUZJQ0FURSBSRVFVRVNULS0tLS0KTUlJQlF6Q0I2UUlCQURCSk1Rc3dDUVlEVlFRR0V3SlRSVEVjTUJvR0ExVUVDaE1UUzJWNVptRmpkRzl5SUVOdgpiVzExYm1sMGVURWNNQm9HQTFVRUF4TVRkR1Z6ZEMxamJTMHdNeTV3YTJseWRXeGxjekJaTUJNR0J5cUdTTTQ5CkFnRUdDQ3FHU000OUF3RUhBMElBQkNJSVhlaTNnd00zc1cwZ0trOUQyQkV5U3E4NDVET29oRVhwblBWODdBbm8KUFRXeE5qMjlzaUVxN1RqR2lLTlhBUGpzRjBqcU1VNFVQbTJxWHlncmdZK2dQakE4QmdrcWhraUc5dzBCQ1E0eApMekF0TUI0R0ExVWRFUVFYTUJXQ0UzUmxjM1F0WTIwdE1ETXVjR3RwY25Wc1pYTXdDd1lEVlIwUEJBUURBZ1dnCk1Bb0dDQ3FHU000OUJBTUNBMGtBTUVZQ0lRRC9kS0E1VEpyYzZxMHhEUEhGNkJLRmppWjVJSkhWY3FDMnQ5TnAKSjQrcnRnSWhBTGxzNVpROGlJbmtHNjZ1NTNYdnUveVdIYzJDbGpCdFk3bFUvdSt2VVVKaQotLS0tLUVORCBDRVJUSUZJQ0FURSBSRVFVRVNULS0tLS0K
        UID:      9ec1c31a-f7af-486c-b881-92d55dd4da1f
        Usages:
          digital signature
          key encipherment
        Username:  system:serviceaccount:cert-manager:cert-manager
      Status:
        Ca:           LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUNtVENDQWorZ0F3SUJBZ0lVSjBlTDlJbmxubWNDRWpxT3pPTmZOdFZ2QVRFd0NnWUlLb1pJemowRUF3UXcKU1RFTE1Ba0dBMVVFQmhNQ1UwVXhIREFhQmdOVkJBb01FMHRsZVdaaFkzUnZjaUJEYjIxdGRXNXBkSGt4SERBYQpCZ05WQkFNTUUwMTVJRkJMU1NCU2IyOTBJRU5CSUMwZ1J6RXdIaGNOTWpNd01USXpNVFl5TkRRMVdoY05Nemd3Ck1URTVNVFl5TkRRMFdqQklNUXN3Q1FZRFZRUUdFd0pUUlRFY01Cb0dBMVVFQ2d3VFMyVjVabUZqZEc5eUlFTnYKYlcxMWJtbDBlVEViTUJrR0ExVUVBd3dTVFhrZ1VFdEpJRk4xWWlCRFFTQXRJRWN4TUZrd0V3WUhLb1pJemowQwpBUVlJS29aSXpqMERBUWNEUWdBRTZqUVhWWk9ha2JQNjFtdG5WVXcvVVl2RzNmQXhRdERBTjZqY0l6bzJLVXpqCmNaSzJkQ3BZUWhpZWdzQ0NLa20xYUhKYXlRNVFTb3hDcVFhUjUyYjZWYU9DQVFRd2dnRUFNQklHQTFVZEV3RUIKL3dRSU1BWUJBZjhDQVFBd0h3WURWUjBqQkJnd0ZvQVUxYzZkYUpDOWlJUzhQNzVlUTZybzB5UjRCNVV3WWdZSQpLd1lCQlFVSEFRRUVWakJVTURJR0NDc0dBUVVGQnpBQ2hpWm9kSFJ3T2k4dmJYa3VjR3RwTDJObGNuUnpMMDE1ClVFdEpVbTl2ZEVOQkxVY3hMbU55ZERBZUJnZ3JCZ0VGQlFjd0FZWVNhSFIwY0RvdkwyMTVMbkJyYVM5dlkzTncKTURZR0ExVWRId1F2TUMwd0s2QXBvQ2VHSldoMGRIQTZMeTl0ZVM1d2Eya3ZZM0pzY3k5TmVWQkxTVkp2YjNSRApRUzFITVM1amNtd3dIUVlEVlIwT0JCWUVGTERsZjNaMDRpcTR1UGhZWlRQZ1lxSEtwRlB0TUE0R0ExVWREd0VCCi93UUVBd0lCaGpBS0JnZ3Foa2pPUFFRREJBTklBREJGQWlBWGN5VjdOdW1PU0RCMDVmeFBqMnRlR3RSWm1vMi8KMklIb0duY3MrNStyaVFJaEFPUEpyZEpTdTYzbFFxRXJwdks2cm1adkxobnE4ZXFHYkF6ekx0WVVseXVWCi0tLS0tRU5EIENFUlRJRklDQVRFLS0tLS0KLS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUIyRENDQVg2Z0F3SUJBZ0lVQXV1TDFjL0FvRndzZnhnVXJPdmFSWGxkT1drd0NnWUlLb1pJemowRUF3UXcKU1RFTE1Ba0dBMVVFQmhNQ1UwVXhIREFhQmdOVkJBb01FMHRsZVdaaFkzUnZjaUJEYjIxdGRXNXBkSGt4SERBYQpCZ05WQkFNTUUwMTVJRkJMU1NCU2IyOTBJRU5CSUMwZ1J6RXdJQmNOTWpNd01USXpNVFl4T0RVNFdoZ1BNakExCk16QXhNVFV4TmpFNE5UZGFNRWt4Q3pBSkJnTlZCQVlUQWxORk1Sd3dHZ1lEVlFRS0RCTkxaWGxtWVdOMGIzSWcKUTI5dGJYVnVhWFI1TVJ3d0dnWURWUVFEREJOTmVTQlFTMGtnVW05dmRDQkRRU0F0SUVjeE1Ga3dFd1lIS29aSQp6ajBDQVFZSUtvWkl6ajBEQVFjRFFnQUVJTUw3a05LR0NqaktmeHd5Qi9zNHF0cEZnMi9hT1ZDZUFCeUVlRE1XCmR6SFlMTU9pZDQ5MDFaUFA1ak1HZ2hxODQreXp6TDV2Q1VYVEtCNDR6SmxVOXFOQ01FQXdEd1lEVlIwVEFRSC8KQkFVd0F3RUIvekFkQmdOVkhRNEVGZ1FVMWM2ZGFKQzlpSVM4UDc1ZVE2cm8weVI0QjVVd0RnWURWUjBQQVFILwpCQVFEQWdHR01Bb0dDQ3FHU000OUJBTUVBMGdBTUVVQ0lRQ2lGTi9vKytaK0FYa1ZVbk0yTTQydm1WVitLUGZMCnZka1JhT0g3RklJTEV3SWdFejBST1BQcFpBMlhGU2ExZG9ma0FZMWg1aUFid2c2Vk9hSTNLZm9hYlZBPQotLS0tLUVORCBDRVJUSUZJQ0FURS0tLS0tCg==
        Certificate:  LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUN6RENDQW5PZ0F3SUJBZ0lVUmlhY0p1Vkk2TzhKTHNaajY1QW93aGwxNVcwd0NnWUlLb1pJemowRUF3UXcKU0RFTE1Ba0dBMVVFQmhNQ1UwVXhIREFhQmdOVkJBb01FMHRsZVdaaFkzUnZjaUJEYjIxdGRXNXBkSGt4R3pBWgpCZ05WQkFNTUVrMTVJRkJMU1NCVGRXSWdRMEVnTFNCSE1UQWVGdzB5TkRBeE1qWXhNekUyTXpWYUZ3MHlOVEF4Ck1qTXhNekUyTXpSYU1Fa3hDekFKQmdOVkJBWVRBbE5GTVJ3d0dnWURWUVFLREJOTFpYbG1ZV04wYjNJZ1EyOXQKYlhWdWFYUjVNUnd3R2dZRFZRUUREQk4wWlhOMExXTnRMVEF6TG5CcmFYSjFiR1Z6TUZrd0V3WUhLb1pJemowQwpBUVlJS29aSXpqMERBUWNEUWdBRUlnaGQ2TGVEQXpleGJTQXFUMFBZRVRKS3J6amtNNmlFUmVtYzlYenNDZWc5Ck5iRTJQYjJ5SVNydE9NYUlvMWNBK093WFNPb3hUaFErYmFwZktDdUJqNk9DQVRnd2dnRTBNQjhHQTFVZEl3UVkKTUJhQUZMRGxmM1owNGlxNHVQaFlaVFBnWXFIS3BGUHRNR0VHQ0NzR0FRVUZCd0VCQkZVd1V6QXhCZ2dyQmdFRgpCUWN3QW9ZbGFIUjBjRG92TDIxNUxuQnJhUzlqWlhKMGN5OU5lVkJMU1ZOMVlrTkJMVWN4TG1OeWREQWVCZ2dyCkJnRUZCUWN3QVlZU2FIUjBjRG92TDIxNUxuQnJhUzl2WTNOd01ETUdBMVVkRVFRc01DcUNFM1JsYzNRdFkyMHQKTURNdWNHdHBjblZzWlhPQ0UzUmxjM1F0WTIwdE1ETXVjR3RwY25Wc1pYTXdFd1lEVlIwbEJBd3dDZ1lJS3dZQgpCUVVIQXdFd05RWURWUjBmQkM0d0xEQXFvQ2lnSm9Za2FIUjBjRG92TDIxNUxuQnJhUzlqY214ekwwMTVVRXRKClUzVmlRMEV0UnpFdVkzSnNNQjBHQTFVZERnUVdCQlE1OUhCOVFnNEtYNFNNUjVMdDRPbzMybHZCeERBT0JnTlYKSFE4QkFmOEVCQU1DQmFBd0NnWUlLb1pJemowRUF3UURSd0F3UkFJZ0o1STB6UVZNVk8zdy9zSGpCdEdhTEt3Ugo2dnd1QWNQQkErTnNvc3ozbGVnQ0lCNEpOTmpXb3dmMXpKSFRiNkFXUXR4UDlIL2M4aDBiNWY0aDluN3ptVFc3Ci0tLS0tRU5EIENFUlRJRklDQVRFLS0tLS0K
        Conditions:
          Last Transition Time:  2024-01-26T13:26:35Z
          Message:               Certificate request has been approved by cert-manager.io
          Reason:                cert-manager.io
          Status:                True
          Type:                  Approved
          Last Transition Time:  2024-01-26T13:26:35Z
          Message:               Signed
          Reason:                Issued
          Status:                True
          Type:                  Ready
      Events:
        Type    Reason           Age    From                                       Message
        ----    ------           ----   ----                                       -------
        Normal  cert-manager.io  2m20s  cert-manager-certificaterequests-approver  Certificate request has been approved by cert-manager.io
      CODE
       
  5. Describe the ingress to see that a certificate was created:

     $ kubectl -n pkirules describe ingress/hellowworld-ingress
    CODE
     
    • The output is similar to the following:

      Name:             hellowworld-ingress
      Labels:           <none>
      Namespace:        pkirules
      Address:          127.0.0.1
      Ingress Class:    public
      Default backend:  <default>
      TLS:
        test-cm-03.pkirules terminates test-cm-03.pkirules
      Rules:
        Host                 Path  Backends
        ----                 ----  --------
        test-cm-03.pkirules
                             /   helloworld:80 (<error: endpoints "helloworld" not found>)
      Annotations:           cert-manager.io/common-name: test-cm-03.pkirules
                             cert-manager.io/issuer: pkirules-tls
                             cert-manager.io/issuer-group: ejbca-issuer.keyfactor.com
                             cert-manager.io/issuer-kind: Issuer
                             cert-manager.io/private-key-algorithm: ECDSA
                             cert-manager.io/private-key-size: 256
                             cert-manager.io/subject-countries: SE
                             cert-manager.io/subject-organizations: Keyfactor Community
      Events:
        Type    Reason             Age                    From                       Message
        ----    ------             ----                   ----                       -------
        Normal  CreateCertificate  3m17s                  cert-manager-ingress-shim  Successfully created Certificate "test-cm-03.pkirules"
        Normal  Sync               2m19s (x2 over 3m17s)  nginx-ingress-controller   Scheduled for sync
      [user@microk8-01 cert-manager]$
      CODE
       

You now have deployed certificates in three different ways using the EJBCA cert-manager external issuer integration.

Next steps

In this tutorial, you learned how to configure EJBCA for the cert-manager integration and issue certificates from EJBCA natively through cert-manager.

For more tutorials for trying out and evaluating EJBCA, see Tutorials and Guides.