EJBCA Deployment, Admin, Certificate Management, Integration, and Maintenance¶
Note
For detailed guidance on EJBCA functionality, administration, and configuration, see the official EJBCA documentation.
Deploy and Manage the EJBCA Application¶
This section describes the EJBCA application lifecycle on StarlingX, including application upload, configuration, deployment, updates, removal, and deletion.
Upload the EJBCA Application¶
Upload the application tarball to register it with the platform.
~(keystone_admin)]$ system application-upload /path/to/ejbca-<version>.tgz
For Distributed Cloud deployments, ensure that registry.central contains the required application images before you apply the application on subclouds. You can populate registry.central in one of the following ways:
Apply the application on the System Controller to automatically pull the required images into registry.central.
or
Upload the application on the System Controller with the –images option to import the required images into registry.central before deploying the application on subclouds.
~(keystone_admin)]$ system application-upload /path/to/ejbca-<version>.tgz --images
Apply the EJBCA Application¶
Before you apply the EJBCA application, configure the required Helm overrides.
Procedure
Set the EJBCA hostname (required). Specify the FQDN that users will use to access EJBCA externally:
~(keystone_admin)]$ system helm-override-update ejbca ejbca ejbca \ --set ejbca.hostname=<ejbca.example.com>
Note
In a lab environment where a DNS server is not available:
To access the EJBCA service by hostname from inside the StarlingX system, add a record to the DNS service to resolve the EJBCA hostname to the OAM floating IP address:
~(keystone_admin)]$ system service-parameter-add dns host-record \ <ejbca.example.com>=<ejbca.example.com>,<OAM_floating_IP>
To access the EJBCA service by hostname from outside the StarlingX system, add an entry to the
/etc/hostsfile on the machine from which the EJBCA access is initiated:<OAM_floating_IP> <ejbca.example.com>
(Optional) Specify the PostgreSQL storage class. By default, the application uses the cluster’s default StorageClass (for example,
ceph-rbdon systems with Ceph). If the cluster does not define a default StorageClass, specify one explicitly:~(keystone_admin)]$ system helm-override-update ejbca ejbca-pg-cluster ejbca \ --set postgresql.storageClass=<your-storage-class>
In a laboratory environment without Ceph, install and use a local-path provisioner:
~(keystone_admin)]$ kubectl apply -f https://raw.githubusercontent.com/rancher/local-path-provisioner/master/deploy/local-path-storage.yaml ~(keystone_admin)]$ kubectl get storageclass ~(keystone_admin)]$ system helm-override-update ejbca ejbca-pg-cluster ejbca \ --set postgresql.storageClass=local-path
Note
The platform rejects the apply operation if the specified storageClass override does not exist in the cluster.
If you do not specify a StorageClass and the cluster does not have a default StorageClass, the platform rejects the apply operation and prompts you to provide one.
If the cluster has a default StorageClass and you do not specify an override, the platform automatically uses the default StorageClass.
Apply the application:
~(keystone_admin)]$ system application-apply ejbca
If you do not set the hostname override, the platform rejects the apply with an error message:
Application-apply rejected: ejbca: required helm override 'ejbca.hostname' is not set. Set it before applying the app: system helm-override-update ejbca ejbca ejbca --set ejbca.hostname=<ejbca.example.com>
Verify the application status:
~(keystone_admin)]$ system application-show ejbca ~(keystone_admin)]$ kubectl get pods -n ejbca
Remove the EJBCA Application¶
Use this operation to stop the EJBCA application while preserving all application data. You can reapply the application at any time.
~(keystone_admin)]$ system application-remove ejbca
After you remove the application:
The ejbca namespace, PVCs, PostgreSQL cluster, secrets, certificates, keys, and configuration remain intact.
Cluster-scoped resources (CertificateRequestPolicy, ClusterRoles, ClusterRoleBindings) are also preserved.
The application returns to the
uploadedstate, ready to reapplied.
Delete the EJBCA Application¶
Use this operation to completely remove the EJBCA application and all its data from the platform.
Note
Unlike the remove operation, this operation is irreversible. Ensure you have a backup of CA keys, certificates, and PKI data before proceeding.
~(keystone_admin)]$ system application-delete ejbca
This operation:
Deletes the
ejbcanamespace, including PVCs, the database, and secrets.Removes cluster-scoped resources (CertificateRequestPolicy, ClusterRoles, ClusterRoleBindings).
Unregisters the application from the platform.
Update the EJBCA Application¶
Procedure
Update the application to a new version:
~(keystone_admin)]$ system application-update /path/to/ejbca-<new-version>.tgz
The update preserves all existing configuration and PKI data, including user helm overrides, and performs a rolling update of pods.
Monitor the update progress:
~(keystone_admin)]$ system application-show ejbca ~(keystone_admin)]$ kubectl rollout status deployment -n ejbca
Note
Use the application-update command for all application version changes.
The platform does not provide an application-upgrade command. Platform
upgrades can automatically update the application if the application
metadata specifies auto_update: true.
EJBCA CLI Operations¶
Use the EJBCA CLI (ejbca.sh) inside the EJBCA container to perform
administrative operations. The CLI communicates using internal EJB calls and
therefore does not require application-level authentication. However, you must
have cluster-admin privileges in Kubernetes to run kubectl exec commands.
This section covers common tasks such as managing certificate authorities, certificate profiles, and CMP aliases using the CLI.
Available Operations (Community Edition)¶
Many operations are available via the CLI, some of which can only be done using the CLI (or Admin GUI). The following table summarizes some of the EJBCA operations and indicates whether each operation can be performed using the CLI, Admin GUI, or both.
Operation |
CLI |
Admin GUI |
|---|---|---|
Import external CA certificates — |
Yes |
No |
Sign CSRs (without a pre-created end entity) — |
Yes |
No |
Set up superadmin authorization — |
Yes |
No |
Create Certificate Authorities — |
Yes |
Yes |
Edit certificate profiles — |
Yes |
Yes |
Create end entities — |
Yes |
Yes |
Configure CMP aliases — |
Yes |
Yes |
Create certificate profiles |
No |
Yes |
Create end entity profiles |
No |
Yes |
Access the CLI¶
Run the following command to open an interactive shell session inside the EJBCA container and access the CLI directly.
~(keystone_admin)]$ kubectl exec -it ejbca-0 -n ejbca -c ejbca -- /opt/keyfactor/bin/ejbca.sh
CLI Operation Examples¶
The following shows some examples of CLI operations that can only be done by CLI and the Admin GUI.
Note
In the following examples, replace the placeholder password changeit with a strong, unique password.
Create a CA¶
$ export NAMESPACE="ejbca"
$ export EJBCA_POD="ejbca-0"
$ export CONTAINER="ejbca"
$ export E="/opt/keyfactor/bin/ejbca.sh"
$ export CA_NAME="test-ca"
$ export CA_TOKEN_PASS="changeit"
~(keystone_admin)]$ kubectl exec -it ${EJBCA_POD} -n ${NAMESPACE} -c ${CONTAINER} -- $E ca init \
--caname ${CA_NAME} \
--dn "CN=${CA_NAME}" \
--tokenType soft \
--tokenPass ${CA_TOKEN_PASS} \
--keytype RSA \
--keyspec 4096 \
-v 3650 \
--policy null \
-s SHA256WithRSA \
--signedby 1
Note
Replace the placeholder password changeit with a strong, unique password.
Create a CMP Alias¶
Before you create a CMP alias, create the certificate profile and end entity
profile in the Admin GUI. To automate profile management across deployments,
use the CLI commands ca exportprofiles and ca importprofiles to export
and import profiles. You can also import profiles from a reference EJBCA
system.
Note
Replace the placeholder password changeit with a strong, unique password.
$ export CERT_PROFILE="test-cert-profile"
$ export EE_PROFILE="test-entity-profile"
$ export CMP_ALIAS="cmp-test-alias"
$ export CMP_HMAC_SECRET="changeit"
# Create the alias
~(keystone_admin)]$ kubectl exec ${EJBCA_POD} -c ${CONTAINER} -n ${NAMESPACE} -- $E config cmp addalias \
--alias ${CMP_ALIAS}
# Configure the alias parameters
$ for kv in \
"operationmode ra" \
"authenticationmodule HMAC" \
"authenticationparameters ${CMP_HMAC_SECRET}" \
"responseprotection pbe" \
"defaultca ${CA_NAME}" \
"ra.certificateprofile ${CERT_PROFILE}" \
"ra.endentityprofile ${EE_PROFILE}" \
"ra.namegenerationscheme DN" \
"ra.caname ${CA_NAME}"; do
~(keystone_admin)]$ kubectl exec ${EJBCA_POD} -c ${CONTAINER} -n ${NAMESPACE} -- \
$E config cmp updatealias \
--alias ${CMP_ALIAS} --key ${kv%% *} --value "${kv#* }"
done
# Verify the configuration
~(keystone_admin)]$ kubectl exec ${EJBCA_POD} -c ${CONTAINER} -n ${NAMESPACE} -- \
$E config cmp dumpalias --alias ${CMP_ALIAS}
Note
For the complete CLI command reference, see: https://docs.keyfactor.com/ejbca/latest/ejbca-operations/ejbca-cli-reference.
EJBCA Admin GUI Access and Operations¶
To access the EJBCA Admin GUI, you must import both the CA certificate and the superadmin client credential into your browser. The Admin GUI uses mTLS for authentication.
Prerequisites
Before accessing the Admin GUI:
Export the
system-local-ca.pemCA certificate from the platform. See Export the system-local-ca Certificate.Export the superadmin certificate and key, and create a PKCS#12 Certificate and Private Key Bundle file for browser import. See Export the Superadmin Credential.
Import the CA certificate and superadmin credential into your browser. See Enable mTLS Authentication.
Export the system-local-ca Certificate¶
Export the CA certificate from the platform to your local machine.
~(keystone_admin)]$ kubectl get secret system-local-ca -n cert-manager \
-o jsonpath='{.data.ca\.crt}' | base64 -d > system-local-ca.pem
Export the Superadmin Credential¶
Export the superadmin credential from the platform to your local machine.
$ source /etc/platform/openrc
# Extract the superadmin certificate and key
~(keystone_admin)]$ kubectl get secret ejbca-superadmin-cert -n ejbca \
-o jsonpath='{.data.tls\.crt}' | base64 -d > /tmp/sa.crt
~(keystone_admin)]$ kubectl get secret ejbca-superadmin-cert -n ejbca \
-o jsonpath='{.data.tls\.key}' | base64 -d > /tmp/sa.key
# Create a |P12| file to import into your browser
$ openssl pkcs12 -export \
-out /tmp/superadmin.p12 \
-inkey /tmp/sa.key \
-in /tmp/sa.crt \
-name SuperAdmin \
-passout pass:<p12-password>
Enable mTLS Authentication¶
Import the credentials you exported into your browser to enable mTLS authentication.
Import the CA certificate (
system-local-ca.pem):In Firefox, select Settings > Privacy & Security > Certificates > View Certificates > Authorities > Import.
In Chrome, select Settings > Privacy and Security > Security > Manage certificates > Authorities > Import.
Import the superadmin credential (
superadmin.p12):In Firefox, select Settings > Privacy & Security > Certificates > View Certificates > Your Certificates > Import.
In Chrome, select Settings > Privacy and Security > Security > Manage certificates > Your Certificates > Import.
When prompted, enter the PKCS#12 Certificate and Private Key Bundle password you set in the Export the Superadmin Credential procedure.
Access the Admin GUI¶
Navigate to the following URL to open the Admin GUI:
https://<ejbca-hostname>:7443/ejbca/adminweb/
When prompted, select the superadmin certificate for client authentication.
Common Admin GUI Operations¶
Use the Admin GUI to view and manage CAs, certificate profiles, end entity profiles, end entities, and certificates.
Operation |
Navigation |
|---|---|
View all CAs available on the platform, including the default
|
CA Functions > Certificate Authorities |
View certificate profiles that define constraints such as allowed key algorithms, key sizes, extensions, and validity periods. |
CA Functions > Certificate Profiles |
View end entity profiles that define enrollment parameters such as allowed DNs, SANs, and associated certificate profiles. |
|RA| Functions > End Entity Profiles |
View existing end entities and their associated certificates. |
RA Functions > Search End Entities, then select View End Entity or View Certificate |
Create certificate profiles and end entity profiles to define key algorithms, validity periods, allowed DNs, SANs, and other enrollment constraints. |
|
Create a CA and issue a certificate using a crypto token, key pairs, and the RA Web interface. |
Create Certificate Profiles and End Entity Profiles¶
Use certificate and end entity profiles to define enrollment constraints and parameters for certificate requests:
Create a certificate profile. Select CA Functions > Certificate Profiles > Add.
Configure the key algorithm, key size (for example, RSA 4096), validity period, and extensions.
Create an end entity profile. Select RA Functions > End Entity Profiles > Add.
Associate the profile with a certificate profile and default CA, then configure the Subject DN fields and Subject Alternative Names.
Create a CA and Issue a Certificate¶
Create a new certificate authority and issue a certificate using the Admin GUI.
Create a crypto token. Select CA Functions > Crypto Tokens > Create new (e.g.,
test-ca-tokenwith password).Generate the signing and encryption key pairs within the token.
Create a CA. Select CA Functions > Certificate Authorities > Add CA > Create.
Select the crypto token and signing key.
To issue a certificate, select RA Web > Make New Request.
Select end entity profile, certificate profile, and CA.
Fill in the subject DN and credentials.
Download PKCS#12 Certificate and Private Key Bundle or Download PEM.
Note
EJBCA creates a new end entity and its certificate.
Note
For detailed information about the Admin GUI, refer to the EJBCA documentation: https://docs.keyfactor.com/ejbca/latest/ejbca-operations/ejbca-ca-ui
EJBCA Certificate Operations Using CMP¶
CMP automates certificate lifecycle management. EJBCA uses CMP aliases to associate enrollment parameters with a specific CA, certificate profile, and end entity profile.
This section shows how to use OpenSSL’s CMP client to enroll, renew, revoke, and check the status of certificates through an EJBCA CMP endpoint.
CMP uses two independent authentication layers:
TLS layer — The
system-local-ca.pemfile acts as the TLS trust anchor that verifies the EJBCA HTTPS endpoint. For mTLS authentication with the EJBCA service, you must provide the Super Administrator client certificate and private key.CMP layer — Initial enrollment (
ir) and RA-mode renewal use an HMAC shared secret for authentication. Key update requests (kur) use signature-based authentication with an existing certificate and private key.
Prerequisites
Before you begin, ensure the following are available:
A CMP alias configured in EJBCA (see EJBCA CLI Operations).
A certificate profile and end entity profile associated with the alias.
The HMAC shared secret configured for the alias.
OpenSSL 3.0+ with CMP support.
The
system-local-ca.pemcertificate for TLS verification.The superadmin client certificate and key for mTLS authentication with the EJBCA service (the httpd proxy). See Export Superadmin Credentials.
Environment variables set for the EJBCA hostname, CMP alias, and credentials. See Environment Setup.
Export Superadmin Credentials¶
Export the superadmin certificate and key from the platform to your local machine:
~(keystone_admin)]$ kubectl get secret -n ejbca ejbca-superadmin-cert \
-o jsonpath='{.data.tls\.crt}' | base64 -d > superadmin.crt.pem
~(keystone_admin)]$ kubectl get secret -n ejbca ejbca-superadmin-cert \
-o jsonpath='{.data.tls\.key}' | base64 -d > superadmin.key.pem
Environment Setup¶
Set the following environment variables before running the commands in this topic:
$ export EJBCA_HOSTNAME="ejbca.example.com:7443"
$ export CMP_ALIAS="cmp-test-alias"
$ export CMP_HMAC_SECRET="changeit"
$ export CA_NAME="test-ca"
$ export SUPERADMIN_CERT="./superadmin.crt.pem"
$ export SUPERADMIN_KEY="./superadmin.key.pem"
Enroll a Certificate¶
Generate a key pair and CSR using the following commands, then enroll the
certificate through a CMP initial request (ir):
$ export CERT="${CA_NAME}-cert"
$ export CERT_CN="${CA_NAME}-cert"
$ export KEY_FILE="${CERT}.key.pem"
$ export CSR_FILE="${CERT}.csr.pem"
$ export CERT_FILE="${CERT}.cert.pem"
$ export CA_FILE="${CA_NAME}.cert.pem"
# Generate private key
$ openssl genrsa -out ${KEY_FILE} 4096
# Generate CSR with SAN
$ openssl req -new -key ${KEY_FILE} \
-subj "/CN=${CERT_CN}" \
-addext "subjectAltName=DNS:${CERT_CN}" \
-out "${CSR_FILE}"
# Enroll via CMP
$ openssl cmp -cmd ir \
-server ${EJBCA_HOSTNAME} \
-path /ejbca/publicweb/cmp/${CMP_ALIAS} \
-tls_used \
-tls_trusted ./system-local-ca.pem \
-tls_cert ${SUPERADMIN_CERT} \
-tls_key ${SUPERADMIN_KEY} \
-ref "${CMP_ALIAS}" \
-secret pass:${CMP_HMAC_SECRET} \
-subject "/CN=${CERT_CN}" \
-recipient "/CN=${CA_NAME}" \
-newkey "${KEY_FILE}" \
-csr "${CSR_FILE}" \
-certout "${CERT_FILE}" \
-cacertsout "${CA_FILE}"
Note
Both -csr and -newkey are required: the CSR provides subject and
extensions, while -newkey provides the private key for Proof of
Possession (POPO).
The -ref parameter is the CMP alias name (used as senderKID for HMAC
lookup). The -recipient specifies the DN of the issuing CA.
Renew a Certificate¶
To renew a certificate, generate a new key pair and CSR, and then submit a new
RA mode ir (initial request) using HMAC authentication. Use the same enrollment
procedure that you used for the initial certificate request. EJBCA issues a new
certificate for the same subject and does not require the existing certificate
or private key.
Note
A true CMP key update (kur) uses signature-based authentication with the
existing certificate and private key. You cannot authenticate a kur request
with HMAC. The ir-based renewal method shown here provides a simpler
alternative for RA mode deployments that use an HMAC shared secret.
# Generate new key and CSR
$ openssl genrsa -out ${CERT}-renewed.key.pem 4096
$ openssl req -new -key ${CERT}-renewed.key.pem \
-subj "/CN=${CERT_CN}" \
-addext "subjectAltName=DNS:${CERT_CN}" \
-out "${CERT}-renewed.csr.pem"
# Re-enroll via CMP ir (same as initial enrollment)
$ openssl cmp -cmd ir \
-server ${EJBCA_HOSTNAME} \
-path /ejbca/publicweb/cmp/${CMP_ALIAS} \
-tls_used \
-tls_trusted ./system-local-ca.pem \
-tls_cert ${SUPERADMIN_CERT} \
-tls_key ${SUPERADMIN_KEY} \
-ref "${CMP_ALIAS}" \
-secret pass:${CMP_HMAC_SECRET} \
-subject "/CN=${CERT_CN}" \
-recipient "/CN=${CA_NAME}" \
-newkey "${CERT}-renewed.key.pem" \
-csr "${CERT}-renewed.csr.pem" \
-certout "${CERT}-renewed.cert.pem" \
-cacertsout "${CA_FILE}"
Revoke a Certificate¶
To revoke a certificate, submit a CMP revocation request (rr) using the
${CERT_FILE} certificate file generated during enrollment.
$ openssl cmp -cmd rr \
-server ${EJBCA_HOSTNAME} \
-path /ejbca/publicweb/cmp/${CMP_ALIAS} \
-tls_used \
-tls_trusted ./system-local-ca.pem \
-tls_cert ${SUPERADMIN_CERT} \
-tls_key ${SUPERADMIN_KEY} \
-ref "${CMP_ALIAS}" \
-secret pass:${CMP_HMAC_SECRET} \
-recipient "/CN=${CA_NAME}" \
-oldcert "${CERT_FILE}" \
-revreason 0 \
-unprotected_errors
The supported revocation reasons are:
0 — unspecified
1 — keyCompromise
3 — affiliationChanged
4 — superseded
5 — cessationOfOperation
Note
Use the -unprotected_errors flag to display the actual error messages.
Without this flag, EJBCA may return signature-protected error responses that
you cannot verify without a trust anchor.
Check Certificate Status¶
To verify the status of an issued or revoked certificate, query the EJBCA OCSP responder:
$ openssl ocsp \
-issuer ${CA_FILE} \
-cert ${CERT_FILE} \
-url https://${EJBCA_HOSTNAME}/ejbca/publicweb/status/ocsp \
-CAfile ${CA_FILE} \
-verify_other ${CA_FILE}
Note
For the complete CMP protocol reference, see: https://docs.keyfactor.com/ejbca/latest/protocols/ejbca-cmp
EJBCA Certificate Operations Using REST API¶
EJBCA provides a REST API that allows you to enroll, renew, revoke, and manage certificates. To access the API, authenticate with a client certificate that has the required EJBCA administrator role permissions (for example, the Super Administrator certificate) over mTLS.
This section shows how to use the EJBCA REST API and curl to enroll, renew, revoke, and check the status of certificates.
Prerequisites
Before you begin, complete the following prerequisites:
Enable the REST protocol in EJBCA. In the EJBCA Admin GUI, navigate to System Configuration > Protocol Configuration > REST Certificate Management, and then select Enabled.
Export the Super Administrator certificate and private key from the cluster to your local machine. For instructions, see Export Superadmin Credentials.
Obtain the
system-local-ca.pemcertificate and use it as the TLS CA trust anchor.Set the required environment variables for the EJBCA hostname, REST base URL, and credentials. For details, see Setup the Environment Variables.
Note
The REST API endpoint /v1/endentity for creating end entities is
not available in EJBCA Community Edition. Use the CLI to create end
entities before enrolling certificates using the REST API.
Export Superadmin Credentials¶
Export the superadmin certificate and key from the cluster to your local machine:
~(keystone_admin)]$ kubectl get secret -n ejbca ejbca-superadmin-cert \
-o jsonpath='{.data.tls\.crt}' | base64 -d > superadmin.crt.pem
~(keystone_admin)]$ kubectl get secret -n ejbca ejbca-superadmin-cert \
-o jsonpath='{.data.tls\.key}' | base64 -d > superadmin.key.pem
Setup the Environment Variables¶
Define the environment variables that the examples in this topic use to connect to EJBCA and authenticate REST API requests:
$ export EJBCA_HOSTNAME="ejbca.example.com:7443"
$ export REST_BASE="https://${EJBCA_HOSTNAME}/ejbca/ejbca-rest-api"
$ export SUPERADMIN_CERT="./superadmin.crt.pem"
$ export SUPERADMIN_KEY="./superadmin.key.pem"
$ export CA_NAME="test-ca"
$ export CERT_PROFILE="test-cert-profile"
$ export EE_PROFILE="test-entity-profile"
Enroll a Certificate¶
Create the end entity using the CLI, then enroll the certificate using the REST API:
# Step 1: Create the end entity (CLI — required for CE)
$ export ENTITY="test-ca-cert01"
$ export ENTITY_PWD="changeit"
~(keystone_admin)]$ kubectl exec ejbca-0 -c ejbca -n ejbca -- /opt/keyfactor/bin/ejbca.sh ra addendentity \
--username ${ENTITY} \
--password ${ENTITY_PWD} \
--dn "CN=${ENTITY}" \
--caname ${CA_NAME} \
--type 1 \
# --token USERGENERATED: user-generated key pair
--token USERGENERATED \
--certprofile ${CERT_PROFILE} \
--eeprofile ${EE_PROFILE}
# Step 2: Generate key and CSR
$ export KEY_FILE="${ENTITY}.key.pem"
$ export CSR_FILE_DER="${ENTITY}.csr.der"
$ export CERT_FILE="${ENTITY}.cert.pem"
$ openssl genrsa -out ${KEY_FILE} 4096
$ openssl req -new -key ${KEY_FILE} \
-subj "/CN=${ENTITY}" \
-addext "subjectAltName=DNS:${ENTITY}" \
-outform |DER| -out ${CSR_FILE_DER}
# Step 3: Enroll via REST API (pkcs10enroll accepts a |P10| —
# the standard format for certificate signing requests)
$ CSR_B64=$(base64 -w0 ${CSR_FILE_DER})
$ curl \
--cacert ./system-local-ca.pem \
--cert ${SUPERADMIN_CERT} --key ${SUPERADMIN_KEY} \
-H "Content-Type: application/json" \
-H "Accept: application/json" \
-X POST "${REST_BASE}/v1/certificate/pkcs10enroll" \
-d "{
\"certificate_request\": \"${CSR_B64}\",
\"certificate_profile_name\": \"${CERT_PROFILE}\",
\"end_entity_profile_name\": \"${EE_PROFILE}\",
\"certificate_authority_name\": \"${CA_NAME}\",
\"username\": \"${ENTITY}\",
\"password\": \"${ENTITY_PWD}\",
\"include_chain\": true
}" | python3 -m json.tool
The response returns the certificate in base64-encoded DER format. Decode and display it using:
# Extract the certificate field from the JSON response, decode, and display
$ echo "<base64-certificate-from-response>" | base64 -d | \
openssl x509 -inform |DER| -text -noout
Note
Include the end_entity_profile_name field in every request. If you omit
it, EJBCA returns a 500 Internal Server Error with a NullPointerException.
Renew a Certificate¶
To renew a certificate, generate a new key pair and CSR, and then re-enroll
through the pkcs10enroll endpoint (the EJBCA REST endpoint for PKCS#10 Certificate Signing Request
enrollment). The REST API manages the end entity status automatically, so you
do not need to reset it to NEW.
# Generate new key and CSR
$ openssl genrsa -out ${ENTITY}-renewed.key.pem 4096
$ openssl req -new -key ${ENTITY}-renewed.key.pem \
-subj "/CN=${ENTITY}" \
-addext "subjectAltName=DNS:${ENTITY}" \
-outform |DER| -out ${ENTITY}-renewed.csr.der
# Re-enroll via REST API
$ CSR_B64=$(base64 -w0 ${ENTITY}-renewed.csr.der)
$ curl \
--cacert ./system-local-ca.pem \
--cert ${SUPERADMIN_CERT} --key ${SUPERADMIN_KEY} \
-H "Content-Type: application/json" \
-H "Accept: application/json" \
-X POST "${REST_BASE}/v1/certificate/pkcs10enroll" \
-d "{
\"certificate_request\": \"${CSR_B64}\",
\"certificate_profile_name\": \"${CERT_PROFILE}\",
\"end_entity_profile_name\": \"${EE_PROFILE}\",
\"certificate_authority_name\": \"${CA_NAME}\",
\"username\": \"${ENTITY}\",
\"password\": \"${ENTITY_PWD}\",
\"include_chain\": true
}" | python3 -m json.tool
Revoke a Certificate¶
To revoke a certificate, extract the serial number and issuer DN from the certificate file, then submit a REST API revocation request.
# Get certificate serial number and issuer DN
$ SERIAL=$(openssl x509 -in ${CERT_FILE} -noout -serial | cut -d= -f2)
$ ISSUER_DN=$(openssl x509 -in ${CERT_FILE} -noout -issuer | sed 's/issuer=//')
# URL-encode the issuer DN for use in the REST path
$ ISSUER_ENC=$(python3 -c "from urllib.parse import quote; print(quote('${ISSUER_DN}', safe=''))")
$ curl \
--cacert ./system-local-ca.pem \
--cert ${SUPERADMIN_CERT} --key ${SUPERADMIN_KEY} \
-H "Accept: application/json" \
-X PUT \
"${REST_BASE}/v1/certificate/${ISSUER_ENC}/${SERIAL}/revoke?reason=UNSPECIFIED" \
| python3 -m json.tool
The supported revocation reasons are:
UNSPECIFIED
KEY_COMPROMISE
CA_COMPROMISE
AFFILIATION_CHANGED
SUPERSEDED
CESSATION_OF_OPERATION
CERTIFICATE_HOLD
PRIVILEGES_WITHDRAWN
Check Certificate Status¶
To verify the status of an issued or revoked certificate, query the EJBCA REST API revocation status endpoint:
$ curl \
--cacert ./system-local-ca.pem \
--cert ${SUPERADMIN_CERT} --key ${SUPERADMIN_KEY} \
-H "Accept: application/json" \
"${REST_BASE}/v1/certificate/${ISSUER_ENC}/${SERIAL}/revocationstatus" \
| python3 -m json.tool
Note
For the complete REST API reference, see: https://docs.keyfactor.com/ejbca/latest/protocols/ejbca-rest-interface
EJBCA Integration with Kubernetes cert-manager¶
The ejbca-cert-manager-issuer integrates EJBCA with Kubernetes
cert-manager, enabling EJBCA to automatically issue and renew certificates
using standard cert-manager Certificate resources.
EJBCA cert-manager Resources¶
The app-ejbca deployment automatically installs the supporting resources
needed for cert-manager integration:
ejbca-cert-manager-issuer — the issuer controller
cert-manager-approver-policy — the policy controller
A CertificateRequestPolicy (
approve-ejbca-issuer) — approval policyClusterRoles and ClusterRoleBindings:
cert-manager-approver-policy— The base role/role binding for the approver-policy controller to evaluate CertificateRequests against policy rulescert-manager-approver-policy:ejbca— The EJBCA-specific role/role binding granting the controller permissions to read EJBCA CRDs (EJBCAIssuer, EJBCAClusterIssuer) during evaluationcert-manager-policy:ejbca— The EJBCA-specific role/role binding granting the requester cert-manager SA permission to “use” theapprove-ejbca-issuerpolicy
CA bundle secret (
ejbca-ca-bundle) — contains thesystem-local-cabundle for the issuer to verify the EJBCA HTTPS endpointejbca-superadmin-cert secret — contains the superadmin’s certificate and key that the issuer (and Admin GUI, CMP, REST API) uses for client authentication to the EJBCA service
Prerequisites
Before creating certificates, ensure the CA, certificate profile, and end entity profile exist in EJBCA. If they do not exist, create them using the CLI or Admin GUI. See EJBCA CLI Operations or EJBCA Admin GUI Access and Operations.
Create an EJBCA ClusterIssuer¶
To create a ClusterIssuer that connects to your EJBCA instance, complete the following steps:
Set environment variables:
$ export CA_NAME="test-ca" $ export CERT_PROFILE="test-cert-profile" $ export EE_PROFILE="test-entity-profile" $ export SVC_HOST="ejbca-httpd.ejbca.svc.cluster.local:443"
Create the ClusterIssuer resource:
$ cat > ejbca-clusterissuer.yaml << EOF apiVersion: ejbca-issuer.keyfactor.com/v1alpha1 kind: ClusterIssuer metadata: name: ejbca-issuer spec: # Must match the internal service hostname hostname: "ejbca-httpd.ejbca.svc.cluster.local:443" # CA configuration (must match |EJBCA| setup) certificateAuthorityName: "${CA_NAME}" certificateProfileName: "${CERT_PROFILE}" endEntityProfileName: "${EE_PROFILE}" # Client certificate for |mTLS| authentication ejbcaSecretName: "ejbca-superadmin-cert" # CA bundle to trust |EJBCA| HTTPS endpoint caBundleSecretName: "ejbca-ca-bundle" # End entity naming strategy endEntityName: "cn" EOF
Apply and verify:
~(keystone_admin)]$ kubectl apply -f ejbca-clusterissuer.yaml ~(keystone_admin)]$ kubectl get clusterissuers.ejbca-issuer.keyfactor.com
Issue a Certificate with EJBCA ClusterIssuer¶
To issue a certificate using the ClusterIssuer, do the following:
Create a cert-manager
Certificateresource:$ cat > test-certificate.yaml << EOF apiVersion: cert-manager.io/v1 kind: Certificate metadata: name: test-ejbca-cert namespace: default spec: secretName: test-ejbca-cert commonName: test.example.com dnsNames: - test.example.com privateKey: algorithm: RSA size: 4096 duration: 8760h # 1 year renewBefore: 720h # 30 days before expiry issuerRef: name: ejbca-issuer kind: ClusterIssuer group: ejbca-issuer.keyfactor.com EOF
Important
The
privateKey.sizemust match the allowed key lengths in the EJBCA certificate profile. If the profile only allows 4096-bit keys, requesting 2048-bit (cert-manager’s default) will fail with: “Illegal key length, not authorized by certificate profile: 2048”Apply the
Certificateresource and verify that it was issued and the certificate secret was created:~(keystone_admin)]$ kubectl apply -f test-certificate.yaml ~(keystone_admin)]$ kubectl get certificate test-ejbca-cert ~(keystone_admin)]$ kubectl get secret test-ejbca-cert
Renew a Certificate Using EJBCA ClusterIssuer¶
cert-manager handles renewal automatically based on the renewBefore
field. To manually trigger renewal and confirm the certificate was renewed:
~(keystone_admin)]$ kubectl cert-manager renew test-ejbca-cert
~(keystone_admin)]$ kubectl get certificaterequest -o wide
Back Up and Restore EJBCA Data¶
StarlingX provides Ansible playbooks for backing up and restoring the EJBCA application data, including all CA keys, certificates, profiles, and database content. The playbooks are located in:
/usr/share/ansible/stx-ansible/playbooks/
Backup EJBCA Data¶
Run the EJBCA backup playbook:
$ sudo ansible-playbook /usr/share/ansible/stx-ansible/playbooks/ejbca_backup.yml -e "initial_backup_dir=/opt/platform-backup"
The playbook creates a .tgz file in /opt/platform-backup. Use this
filename when running the restore playbook.
Restore EJBCA Data¶
Before running the restore playbook, ensure the backup .tgz file is present
in /opt/platform-backup.
$ sudo ansible-playbook /usr/share/ansible/stx-ansible/playbooks/ejbca_restore.yml -e "initial_backup_dir=/opt/platform-backup" -e "backup_filename=<filename>.tgz"
Replace <filename>.tgz with the backup filename from /opt/platform-backup.
After the restore process is completed, all EJBCA PKI data (CAs, keys, profiles, and certificates) is available, and the application is ready for use.
Note
A platform full restore can leave app-ejbca in a failed state after the
restore completes. If this occurs, wait until the storage resources are
ready and then reapply app-ejbca.
Automatic EJBCA Server Certificate Renewal¶
Overview¶
The EJBCA server certificate (ejbca-tls-cert) is issued by the
system-local-ca ClusterIssuer and managed by cert-manager.
cert-manager automatically renews the certificate 30 days before expiration
(renewBefore: 720h) and updates the associated Kubernetes secret.
After cert-manager renews the certificate and updates
the associated Kubernetes secret, the EJBCA pod must be restarted to reload the
updated TLS certificate used by the httpd sidecar. The Stakater Reloader
application (app-reloader) automates this process.
Deployed as a separate platform application, app-reloader detects updates
to the certificate secret and automatically restarts the EJBCA pod, allowing
the httpd sidecar to load the renewed certificate.
Prerequisites
Automatic pod restart requires the app-reloader platform application.
Upload and apply the app-reloader application:
~(keystone_admin)]$ system application-upload /path/to/reloader-<version>.tgz
~(keystone_admin)]$ system application-apply reloader
Verify that the application is running:
~(keystone_admin)]$ system application-show reloader
~(keystone_admin)]$ kubectl get pods -n reloader
Manually Reload the Renewed Certificate¶
Note
When app-reloader is installed, no manual intervention is required after certificate renewal.
If app-reloader is not deployed, cert-manager still renews the certificate
and updates the Kubernetes secret, but the EJBCA pod is not automatically
restarted. To load the renewed certificate, manually restart the pod:
~(keystone_admin)]$ kubectl rollout restart statefulset ejbca -n ejbca