Skip to main content
Skip table of contents

Deploy EJBCA as CA with automation

ENTERPRISE

This outlines how to deploy a Certificate Authority (CA) using the EJBCA Enterprise configuration export/import tool EJBCA ConfigDump. The following sections provide examples of how to use Helm to create Certificate Authorities (CAs), configure roles, enable required protocols such as REST and OCSP, and customize ConfigDump-supported resources.

Prerequisites

Before you begin, you should be familiar with how to deploy EJBCA CA in Kubernetes.

EJBCA installation with ConfigDump import does not support replication during the installation stage. Instead, use helm install with ConfigDump and replicaCount: 1. After installation, perform a helm upgrade to the desired replicaCount.

Prepare database and credentials

  • Prepare a database in Kubernetes or externally.

  • Create secrets containing the username and password.

  • Configure these essential values in values.yaml:

    • The database URL

    • The database credential secrets

    • Ingress URL

Prepare configuration dump

ConfigDump objects used in the following examples were created using the EJBCA ConfigDump REST Interface. The provided samples will demonstrate how to initialize an EJBCA instance with:

  • Crypto Tokens: Two soft crypto tokens with authentication codes provided using Kubernetes secrets.

  • Certification Authorities (CAs): Two CAs created using supplied subjectDN, validity, etc.

  • End Entity Profile: An End Entity Profile for issuing server certificates with up to four DNS Names.

  • Roles and Role Members: Roles used for certificate authentication with CN (common name) SuperAdmin and AutomationAdmin.

  • Protocols: Configuration that enables REST, ACME and other protocols.

Separate confidential data and create Kubernetes secrets

Sensitive data in ConfigDump exports can be replaced with references to Kubernetes Secret keys.

For example, given a configuration dump snippet with an Authentication Code supperSecretPassword:

JSON
"crypto-tokens": {
  "ManagementCA": {
    "Object Type": "Crypto Token",
    "Authentication Code": "supperSecretPassword",
    ...
  }
}

You can first create a secret to store the Authentication Code using an arbitrary key, for example, AUTHENTICATION_CODE:

BASH
kubectl create secret generic configdump-secrets \
    --from-literal=AUTHENTICATION_CODE=supperSecretPassword

Then, reference this key in an inline or mounted ConfigDump file when deploying EJBCA:

JSON
"crypto-tokens": {
  "ManagementCA": {
    "Object Type": "Crypto Token",
    "Authentication Code": "${AUTHENTICATION_CODE}",
    ...
  }
}

Subsequent sections of this guide will use a Kubernetes secret with the following content:

BASH
kubectl create secret generic configdump-secrets \
    --from-literal=CA_TOKEN_PASSWORD=foo123 \
    --from-literal=PEER_TOKEN_PASSWORD=bar123

Prepare configuration dump as a Kubernetes ConfigMap

Prepare a Kubernetes ConfigMap with your EJBCA configuration files.

Example filename: ejbca-ca-init-configmap.yaml

YAML
apiVersion: v1
kind: ConfigMap
metadata:
  name: ejbca-ca-init-configmap
data:
  after-deployed-pre.sh: |
    #!/bin/bash

    cd /opt/keyfactor 
    bin/ejbca.sh cryptotoken create --token CaToken001 --pin "$CA_TOKEN_PASSWORD" --autoactivate --type SoftCryptoToken

    bin/ejbca.sh cryptotoken generatekey --token CaToken001 --alias signkey001 --keyspec 2048
    bin/ejbca.sh cryptotoken generatekey --token CaToken001 --alias defaultkey001 --keyspec 2048 --key-usage SIGN_ENCRYPT
      
    bin/ejbca.sh cryptotoken generatekey --token CaToken001 --alias signkey002 --keyspec 2048
    bin/ejbca.sh cryptotoken generatekey --token CaToken001 --alias defaultkey002 --keyspec 2048 --key-usage SIGN_ENCRYPT
    bin/ejbca.sh cryptotoken generatekey --token CaToken001 --alias testkey --keyspec 2048
    echo "web.reqcert=false" >> /opt/keyfactor/ejbca/conf/web.properties

  configdump.json: |
    {
      "crypto-tokens": {
        "PeerToken": {
          "Object Type": "Crypto Token",
          "Version": 2,
          "Name": "PeerToken",
          "Used": true,
          "Key Pair Info": [],
          "Authentication Code": "${PEER_TOKEN_PASSWORD}",
          "Type": "SoftCryptoToken",
          "Active": true,
          "Auto Activation": true
        }
      },
      "certification-authorities": {
        "ManagementCA": {
          "Object Type": "Certification Authority",
          "Version": 2,
          "Name": "ManagementCA",
          "Type of CA": "X.509",
          "Serial Number Octet Size": 20,
          "Pre-produce OCSP Responses": false,
          "Microsoft CA Compatible Mode Used": false,
          "Store responses on-demand": false,
          "Pre-produce OCSP Responses Upon certificate issuance/revocation": false,
          "Certificate Profile": "ROOTCA",
          "Default Certificate Profile": "Not used",
          "Use Append-Only Table": false,
          "CA Token": {
            "Signature Algorithm": "SHA256WithRSA",
            "Encryption Algorithm": "SHA256WithRSA",
            "Crypto Token": "CaToken001",
            "Default Key": "defaultkey001",
            "Certificate Signing Key": "signkey001",
            "CRL Signing Key": "signkey001",
            "Key Encryption Key": "defaultkey001",
            "Test Key": "testkey",
            "Key Sequence Format": "Numeric",
            "Key Sequence": "00000"
          },
          "Enforce Unique Public Keys": false,
          "Enforce key renewal": false,
          "Enforce Unique DN": false,
          "User Storage": true,
          "Certificate Storage": true,
          "Accept Revocations for Non-Existing Entries": false,
          "Subject DN": "CN=ManagementCA,OU=SomeOrg",
          "Signed By": "Self Signed",
          "Validity": "20y",
          "Subject Alternative Name": "None",
          "Use UTF-8 in Policy Notice Text": true,
          "LDAP DN Order": true,
          "Authority Key Id Used": true,
          "CRL Number Used": true,
          "Partitioned CRL Used": false,
          "CRL Expiration Period": "1d",
          "CRL Issue Interval": "0m",
          "CRL Overlap Time": "10m",
          "Delta CRL Period": "0m",
          "Generate CRL Upon Revocation": false,
          "Allow Changing Revocation Reason": false,
          "Finish User": true,
          "CA Healthcheck Enabled": true,
          "Request Processor": null
        },
        "RootCA": {
          "Object Type": "Certification Authority",
          "Version": 2,
          "Name": "RootCA",
          "Type of CA": "X.509",
          "Serial Number Octet Size": 20,
          "Pre-produce OCSP Responses": false,
          "Microsoft CA Compatible Mode Used": false,
          "Store responses on-demand": false,
          "Pre-produce OCSP Responses Upon certificate issuance/revocation": false,
          "Certificate Profile": "ROOTCA",
          "Default Certificate Profile": "Not used",
          "Use Append-Only Table": false,
          "CA Token": {
            "Signature Algorithm": "SHA256WithRSA",
            "Encryption Algorithm": "SHA256WithRSA",
            "Crypto Token": "CaToken001",
            "Default Key": "defaultkey002",
            "Certificate Signing Key": "signkey002",
            "CRL Signing Key": "signkey002",
            "Key Encryption Key": "defaultkey002",
            "Test Key": "testkey",
            "Key Sequence Format": "Numeric",
            "Key Sequence": "00000"
          },
          "Enforce Unique Public Keys": false,
          "Enforce key renewal": false,
          "Enforce Unique DN": false,
          "User Storage": true,
          "Certificate Storage": true,
          "Accept Revocations for Non-Existing Entries": false,
          "Subject DN": "CN=RootCA,C=SE",
          "Signed By": "Self Signed",
          "Validity": "20y",
          "Subject Alternative Name": "None",
          "Use UTF-8 in Policy Notice Text": true,
          "LDAP DN Order": true,
          "Authority Key Id Used": true,
          "CRL Number Used": true,
          "Partitioned CRL Used": false,
          "CRL Expiration Period": "1d",
          "CRL Issue Interval": "0m",
          "CRL Overlap Time": "10m",
          "Delta CRL Period": "0m",
          "Generate CRL Upon Revocation": false,
          "Allow Changing Revocation Reason": false,
          "Finish User": true,
          "CA Healthcheck Enabled": true,
          "Request Processor": null
        }
      },
      "end-entity-profiles": {
        "eep001": {
          "Object Type": "End Entity Profile",
          "Version": 1,
          "Name": "ServerEndEntityProfile",
          "Description": "",
          "Default CA": "ManagementCA",
          "Available CAs": ["ManagementCA", "RootCA"],
          "Default Certificate Profile": "SERVER",
          "Available Certificate Profiles": ["SERVER"],
          "Default Token Type": "PEM File",
          "Available Token Types": [
            "User Generated",
            "PKCS12 File",
            "BCFKS File",
            "JKS File",
            "PEM File"
          ],
          "Subject DN": {
            "CN": [
              {
                "Required": true
              }
            ]
          },
          "Subject Alternative Name": {
            "DNSNAME": [
              {
                "Required": false
              },
              {
                "Required": false
              },
              {
                "Required": false
              },
              {
                "Required": false
              }
            ]
          }
        }
      },
      "available-protocols": {
        "available-protocol-configuration": {
          "Object Type": "Available Protocols",
          "Version": 1,
          "Name": "available-protocol-configuration",
          "ACME": true,
          "Certstore": true,
          "CMP": true,
          "CRLstore": true,
          "EST": true,
          "MSAE": true,
          "OCSP": true,
          "SCEP": true,
          "RA Web": true,
          "REST CA Management": true,
          "REST Certificate Management": true,
          "REST Coap Management": true,
          "REST Crypto Token Management": true,
          "REST End Entity Management": true,
          "REST End Entity Management V2": true,
          "REST Configdump": true,
          "REST Certificate Management V2": true,
          "REST SSH V1": true,
          "REST System V1": true,
          "Webdist": true,
          "Web Service": true,
          "ITS Certificate Management": false,
          "Custom header name for REST calls from browser": "X-Keyfactor-Requested-With"
        }
      },
      "admin-roles": {
        "Super Administrator Role": {
          "Object Type": "Role",
          "Version": 1,
          "Name": "Super Administrator Role",
          "Role Members": [
            {
              "Token Type": "CertificateAuthenticationToken",
              "Issuer": "ManagementCA",
              "Match With": "WITH_COMMONNAME",
              "Match Value": "AutomationAdmin"
            },
            {
              "Token Type": "CertificateAuthenticationToken",
              "Issuer": "ManagementCA",
              "Match With": "WITH_COMMONNAME",
              "Match Value": "SuperAdmin"
            },
            {
              "Token Type": "CliAuthenticationToken",
              "Issuer": null,
              "Match With": "USERNAME",
              "Match Value": "ejbca"
            },
            {
              "Token Type": "PublicAccessAuthenticationToken",
              "Issuer": null,
              "Match With": "TRANSPORT_CONFIDENTIAL",
              "Match Value": ""
            }
          ],
          "Namespace": "",
          "RA Style Id": 0,
          "Access Rules": {
            "/": "Allow"
          }
        }
      }
    }

Create the ConfigMap:

BASH
kubectl apply -f ejbca-ca-init-configmap.yaml

Configure Deployment

The following shows an example Helm chart values file modified to deploy the EJBCA CA.

Example filename: ejbca-ca-values.yaml

YAML
ejbca:
  env:
    DATABASE_JDBC_URL: "jdbc:mariadb://mariadb:3306/ejbca?characterEncoding=utf8"
    DATABASE_USER: ejbca
  envRaw:
    - name: DATABASE_PASSWORD
      valueFrom:
        secretKeyRef:
          name: mariadb-passwords
          key: mariadb-password
  envFrom:
    - secretRef:
        name: configdump-secrets
  configdumpImport:
    enabled: true
    initialize: true
    configMapName: ejbca-ca-init-configmap
    configMapKey: configdump.json
  volumes:
    - name: after-deployed-pre
      configMap:
        name: ejbca-ca-init-configmap
        defaultMode: 0777
        items:
          - key: "after-deployed-pre.sh"
            path: "after-deployed-pre.sh"
  # Extra volume mounts to be added to the deployment
  volumeMounts:
    - name: after-deployed-pre
      mountPath: /opt/keyfactor/bin/internal/after-deployed-pre.sh
      subPath: after-deployed-pre.sh

ingress:
  enabled: true
  hosts:
    - host: "ejbca.example.com"
      paths:
        - path: /
          pathType: Prefix

#imagePullSecrets:
#  - name: keyfactor-registry

Install EJBCA

Deploy EJBCA to a Kubernetes cluster using the previously prepared Helm chart values file:

CODE
helm install ejbca-ca -f ejbca-ca-values.yaml \
    oci://repo.keyfactor.com/charts/ejbca --version <version>

Secure EJBCA

Once EJBCA is deployed, enroll a Super Administrator certificate, create a TLS server certificate, and configure EJBCA to use them with client certificate authentication.

Issue SuperAdmin certificate

To issue a certificate for the SuperAdmin:

  1. In EJBCA, click RA Web to access the EJBCA RA user interface.

  2. Select Enroll > Make New Request and specify the following:

    • For Certificate Type, i applicable, select EMPTY.

    • For Certificate subtype, select ENDUSER.

    • For CA, select ManagementCA.

    • For Key-pair generation, select By the CA.

    • For Key algorithm, select for example, RSA-2048.

    • For the Required Subject DN Attributes, Common Name (CN), specify SuperAdmin.

    • For Provide User Credentials, enter a username and password.

  3. Click Download PKCS#12 to download the certificate.

Your certificate is saved as a SuperAdmin.p12 file.

Configure TLS and client certificate authentication

Steps describing how to secure access to EJBCA using a TLS server certificate with client certificate authentication are outlined on the Deploy CA in Kubernetes page.

To configure EJBCA, do the following:

  1. Access EJBCA Admin Web by navigating your browser to the host configured in ejbca-ca-values.yaml.

  2. On the CA Structure & CRLs page, click Download PEM file to download the ManagementCA.cacert.pem file.

  3. Proceed to the Deploy CA in Kubernetes page and follow the guide starting from section Enroll server TLS certificate.

JavaScript errors detected

Please note, these errors can depend on your browser setup.

If this problem persists, please contact our support.