EJBCA Sensor
Discover_EJBCA inventories a PrimeKey EJBCA certificate authority through its REST API. It catalogues the CAs themselves, the certificates they have issued, any SSH certificate authorities, and the key pairs held in EJBCA's crypto tokens — including keys that live in an attached HSM.
Overview and what gets scanned
The sensor sweeps an EJBCA instance in four passes.
| Pass | What it catalogues |
|---|---|
| CA certificates | Every CA registered in EJBCA — root and issuing. One certificate document and a companion public key document per CA. This pass also builds the issuer map the next one uses. |
| Issued certificates | Every end-entity certificate matching the configured CA and status filters. X.509 certificates become a certificate and a companion key; SSH certificates issued by EJBCA become a certificate carrying the SSH-specific fields. |
| SSH CA public keys | The public key of each CA that has SSH mode enabled. A CA without SSH mode is skipped. |
| Crypto token key pairs | Every key pair in every active crypto token — software tokens and HSM-backed tokens alike. Each key records whether it is secured by an HSM or in software, and HSM-backed keys record the PKCS#11 library and the slot label. |
Revocation is carried through. A revoked certificate is marked as such in the inventory, and its companion public key is recorded as compromised rather than active. The revocation reason and date are kept alongside it. An active certificate carries no revocation marker at all, rather than a negative one — so a filter for revoked material returns exactly the revoked material.
Issuers are resolved to real names. The issuer recorded on an end-entity certificate is the X.509 subject distinguished name of the signing CA's own certificate, cross-referenced from the first pass — not EJBCA's internal CA label. The two often differ, and the DN is what matches the certificate elsewhere in the inventory.
What it does not produce. Private key material never leaves EJBCA or its HSM — the sensor records that a key pair exists, what it is and where it is held. Internal key bindings (OCSP and CMP signer associations) are deliberately not catalogued: they point at keys the crypto token pass already found, and emitting them would create duplicates.
Prerequisites
Network access. Outbound HTTPS from the platform or the agent to the EJBCA instance, on whatever port its REST API listens on.
Authentication — mutual TLS only. EJBCA is a certificate authority, and this sensor will not talk to one over plain HTTP, with HTTP Basic authentication, or anonymously. A http:// URL is rejected when the configuration is validated rather than at scan time. You need a client certificate and its private key, issued by EJBCA and bound to an administrator role.
Required access rights in EJBCA. The client certificate's role needs read access to the REST resources the sensor uses: /v1/ca, certificate search, /v1/ssh/{ca}/pubkey and /v1/configdump/crypto-tokens. Create a dedicated read-only administrator role for this. The sensor issues no write of any kind, so a role with any write privilege is more than it needs.
Target-side prerequisites. The REST API must be enabled on the EJBCA instance, and the relevant protocols — REST Certificate Management, REST CA Management, REST Configdump — enabled in EJBCA's system configuration. Configdump in particular is often off by default, and the crypto token pass is the one that quietly returns nothing without it.
Execution models. Platform execution, remote execution on an agent and cloud execution. Off-grid bundles work provided the bundle runs where it can reach the EJBCA API.
Configuration fields
| Field | Type | Required | Description |
|---|---|---|---|
ExtName | string | Yes | Discover_EJBCA. Set for you by the form. |
host | string | Yes | The EJBCA base URL. Must be https://. |
auth_mode | string | Yes | certificate_inline or certificate_p12. |
client_cert_content | string | Conditional | PEM client certificate. Required for certificate_inline. |
client_key_content | string | Conditional | PEM private key for that certificate. Required for certificate_inline. |
client_p12_base64 | string | Conditional | Base64-encoded PKCS#12 bundle. Required for certificate_p12. |
client_p12_password | string | Conditional | Password for that bundle. |
verify_ssl | boolean | No | Whether to verify EJBCA's own server certificate. |
server_ca_content | string | No | PEM certificate of the CA that signed EJBCA's TLS certificate. |
ca_filter | list | No | CA names to restrict the scan to. Blank scans every CA. |
status_filter | list | No | Certificate statuses to sweep. Blank sweeps all supported statuses. |
scan_name | string | No | A label carried onto every document from this scan. |
Client credentials are pasted, not referenced by path. Both authentication modes take the material inline. There is no file path option, because the sensor may run on an agent that has no such file and no way to get one safely.
Server verification has three settings, and the middle one is the usual answer.
| Setting | When to use it |
|---|---|
verify_ssl: false | A lab instance with a self-signed certificate. Never in production. |
verify_ssl: true, no server_ca_content | EJBCA's TLS certificate is signed by a publicly trusted CA. |
verify_ssl: true with server_ca_content | EJBCA's TLS certificate is signed by your own internal CA. Paste that CA's certificate — not EJBCA's own server certificate. |
A minimal configuration:
ExtName: Discover_EJBCA
host: https://ejbca.corp.example.com:8443
auth_mode: certificate_inline
client_cert_content: |
-----BEGIN CERTIFICATE-----
...
-----END CERTIFICATE-----
client_key_content: |
-----BEGIN PRIVATE KEY-----
...
-----END PRIVATE KEY-----
verify_ssl: true
A realistic configuration against an internal CA, scoped to the issuing CAs that matter and to active and revoked certificates only:
ExtName: Discover_EJBCA
host: https://ejbca.corp.example.com:8443
auth_mode: certificate_p12
client_p12_base64: MIIKrQIBAzCCCm...
client_p12_password: "<bundle password>"
verify_ssl: true
server_ca_content: |
-----BEGIN CERTIFICATE-----
...
-----END CERTIFICATE-----
ca_filter:
- IssuingCA-Internal
- IssuingCA-Devices
status_filter:
- CERT_ACTIVE
- CERT_REVOKED
scan_name: ejbca-production
Scoping. ca_filter and status_filter are the two controls that decide how long a scan takes. An EJBCA instance that has issued hundreds of thousands of device certificates will take a long time to sweep in full, and sweeping archived certificates on every run rarely earns its cost. Start with the issuing CAs you report on and the active and revoked statuses; widen once you know the run time.
Execution modes
From the portal. Add the sensor to a discovery template, paste the client credentials, set the filters, assign the template to a task and run it.
On an agent. Appropriate where EJBCA sits in a segment the platform cannot reach — which, for a CA, it often does. Configuration is identical.
Through the API. Deploy the task carrying the sensor and read the ingestion counts back. See the Scan and Discovery API reference.
Off-grid. Supported, provided the bundle runs where it can reach the API. The client credentials travel in the bundle, so treat the bundle as sensitive material and remove it once the results are imported.
Known limitations
| Limitation | Effect |
|---|---|
| Archived certificates | Some EJBCA versions reject CERT_ARCHIVED as a search criterion. The sensor detects this and skips that status rather than failing the scan. |
| CAs without SSH mode | Some versions answer the SSH public key request with a server error rather than a not-found. The sensor logs it and moves on; it is not a scan failure. |
| Older API pagination | The v1 certificate search has no cursor, so only the first page is returned. The sensor warns when EJBCA signals that more results exist. Narrow the filters to stay within a page, or use an EJBCA version with the v2 search. |
| SSH certificates have no companion key | EJBCA stores SSH certificates in OpenSSH wire format rather than X.509, so no separate public key document is written for them. |
| Issuer omitted | Where the CA pass did not run, or the issuing CA's certificate was not found, the issuer is left off the document rather than filled with EJBCA's internal label. |
| No write operations | The sensor reads. It cannot issue, revoke or renew — those stay in EJBCA. |
Troubleshooting
Connection refused at configuration validation. The URL is http://. This is rejected deliberately: a certificate authority reachable over plain HTTP is a serious misconfiguration, and the sensor will not be the thing that normalises it.
TLS handshake fails. Either EJBCA does not trust your client certificate, or you do not trust EJBCA's. Test both directions with curl --cert client.pem --key client.key --cacert ca.pem https://<ejbca>/ejbca/ejbca-rest-api/v1/ca. A 200 here and a failure in the sensor means the material was pasted incompletely — check that the -----BEGIN and -----END lines and the newlines between them survived.
HTTP 403 from the API. The client certificate authenticated but its EJBCA role lacks the rules the sensor needs. Grant read access to the CA, certificate and configdump resources.
CAs and certificates found, no crypto token keys. The Configdump protocol is disabled on the EJBCA instance, or the role lacks access to it. Enable REST Configdump in EJBCA's system configuration. This is the most common partial-result case.
Far fewer certificates than expected. Check status_filter and ca_filter first — a filter left over from a scoped trial run is the usual cause. Then check the log for a pagination warning, which means the search returned one page of a larger set.
Revoked certificates show as active. The status filter excluded CERT_REVOKED, so the sensor never saw them in their revoked state and the inventory still holds what the previous scan found.
Getting support
Collect the platform version, the EJBCA version, the sensor configuration with the client credentials removed, the task and template names, and the discovery log extract. The curl test above, with its output, resolves most authentication cases before support is needed. Never include the client private key or the PKCS#12 password — naming which credential was used is enough.