Skip to content

v2.226

Latest

Choose a tag to compare

@github-actions github-actions released this 09 Sep 19:13

What's Changed

Added

  • An intermediate CA can be revoked from its parent. UCM had no CA revocation at all: only end-entity certificates could be revoked, and the documentation listed "take offline" or "delete" as the ways to retire a CA, so a compromised or decommissioned intermediate never reached the parent's CRL or OCSP responder. Revoke CA on an intermediate (POST /api/v2/cas/<id>/revoke, write:cas) takes the RFC 5280 reason codes and optional invalidity date already used for certificates; the serial is recorded in the parent's persistent revocation list, the parent's CRL is regenerated at once and its OCSP responder answers revoked with the reason. The revoked CA, and every CA below it, can no longer sign anything (issue form, CSRs, renewals, sub-CAs, ACME, EST, SCEP, WSTEP, TSA, OCSP responder certificates), while its own CRL keeps being served until the CA is deleted, and deleting it keeps the entry on the parent's CRL until the certificate's original expiry. Revocation is permanent, as for certificates. A root CA is not revocable (self-signed: relying parties remove it from their trust stores), nor is a CA whose issuer is not held in UCM: that one is revoked at its root, whose CRL UCM can already serve. The revocation record belongs to the parent and outlives the CA row: a revoked CA that is deleted and imported again comes back revoked, and the parent's OCSP responder and every signing path trust that record rather than the row's flag. When the parent cannot regenerate its CRL (offline or key-less parent) or has CDP disabled, the revocation is still recorded and the response says so, since the CRL currently served does not list the serial yet. A dedicated TSA signer issued under a revoked CA is refused as well. The CA list gains a Revoked status and filter, and the audit log records ca_revoked (#343, reported by @j2r2k2)

Fixed

  • An active filter no longer stops applying after an action performed from a certificate's detail window. Revoking, renewing or deleting a certificate there reloads the list, and that reload used the filters as they were when the page was opened, so a filter chosen afterwards was dropped from the query: the filter chip stayed on screen while the list showed every certificate. The reload now uses the filters currently set, on the certificates page and on the SSH certificates page, which filter the same way. The Orphan filter also works on the first load, where it previously did nothing until the certificate authorities had been fetched once (#345, reported by @kiar1404-de)
  • The OCSP responder answered unknown for the certificate of an intermediate CA. The status lookup only searched the end-entity certificates issued by the CA named in the request, while the certificate of a sub-CA is stored with the CA itself, so a client validating a chain got no answer for the intermediate. The responder now recognises the certificates of the CAs signed by the requested issuer and answers good while they are valid, revoked once the sub-CA is revoked (#344, reported by @j2r2k2)

📜 Recent release history (last 2 versions)

[2.225] - 2026-09-09

Added

  • A CSR generated in UCM can be completed by a certificate issued elsewhere. The workflow for a public or third-party CA (generate the CSR in UCM, download it, have it signed, import the certificate) ended with a certificate record that had no private key: the import matched existing records on subject and issuer, which a CSR record never has, so the certificate was stored as a separate keyless entry and could not be exported with its key. The import (Certificates page and Smart Import) now recognises a certificate whose public key is that of a pending CSR, completes that CSR record and keeps its private key, so the certificate exports with the key like any other; the match is made on the key pair, so it holds when the CA rewrites the subject. A key that arrives alongside the certificate is attached when the CSR was uploaded without one. The CSR page also gained Download Private Key on a pending CSR that holds its key (GET /api/v2/csrs/<id>/export?format=key, or POST with a password for encrypted PKCS#8), gated like every direct key export by the admin-only read:private_keys permission and recorded in the audit log (#341, reported by @kiar1404-de)

Fixed

  • A certificate issued from a CSR generated in UCM no longer appears as "CSR for " in the certificates list. The generator described the request that way and signing kept the description, which the list shows as the certificate's name. A generated CSR is now described by its CN, and signing or completing a CSR created before this release drops the old prefix (#342, reported by @kiar1404-de)

[2.224] - 2026-09-08

Added

  • UCM_TRUSTED_PROXIES accepts CIDR networks, not only exact IP addresses. Behind an ingress controller or another proxy whose source address is not fixed, every allowed peer had to be listed individually; an entry such as 10.42.0.0/16 now trusts any peer inside that range, and a peer that arrives as an IPv4-mapped IPv6 address (::ffff:10.42.0.5, as a dual-stack listener reports IPv4 clients) is matched against IPv4 entries and networks as well. An entry that is neither a valid address nor a valid network is ignored with a warning in the log instead of being kept as a literal string that can never match, so a typo cannot silently narrow the trusted set. The Helm chart gained proxy.behindProxy (sets UCM_BEHIND_PROXY) and proxy.trustedProxies (sets UCM_TRUSTED_PROXIES), neither of which it templated before, so a chart deployment behind an Ingress can honour X-Forwarded-* and proxy-injected client-certificate headers without a hand-written extraEnv entry (discussion #337, requested by @szechyjs, contributed by @Hemsby)
  • The certificate template editor can build a Windows smartcard logon template. The Extended Key Usage list gained msSmartcardLogin (Microsoft Smartcard Logon, 1.3.6.1.4.1.311.20.2.2) and the SAN types gained upn, both of which the template API and the issuance path already accepted but which the editor's fixed checkbox lists did not offer, so a reusable Smartcard Logon profile could not be clicked together even though the Issue Certificate form could produce one. A built-in Smartcard Logon system template ships alongside the others (clientAuth + msSmartcardLogin, UPN SAN). The SAN type checkboxes now use the same localized labels as the issue form rather than a bare upper-cased token (discussion #336, requested by @szechyjs, contributed by @Hemsby)

Fixed

  • With UCM_BEHIND_PROXY=1, X-Forwarded-* and X-Real-IP headers are now honoured only when the request's immediate peer is in UCM_TRUSTED_PROXIES; from any other peer they are dropped before the proxy handling runs, with a warning in the log naming the peer. Previously enabling proxy support trusted those headers from every peer, so a client able to reach the backend directly, such as another pod in the same cluster, could choose its apparent IP, rotate past the per-IP rate limits and pollute the audit trail. Upgrade note: a reverse proxy running on another host must be listed in UCM_TRUSTED_PROXIES (IP or CIDR network), as the documentation already required; unset, the variable trusts loopback only, and a proxy that is not listed now sees its own address logged and rate-limited instead of its clients' (discussion #337, follow-up to #339)
  • Helm chart: appVersion now tracks the release the chart ships with. It had stayed at 2.170 while the image tag defaults to appVersion, so a chart install without an explicit image.tag deployed that old version
  • The public port of the admin and protocol URLs can now differ from the port UCM listens on. Settings > General accepted http://pki.example.com:80 as Protocol Base URL but dropped the :80 as a default port when saving, then applied the HTTP protocol port (8080 by default, and the field refuses a port below 1024) to every CDP, OCSP and AIA URL it advertised, so a reverse proxy publishing those endpoints on port 80 could not be described; the same happened to https://admin.example.com:443 and the HTTPS listen port for the admin canonical URL. An explicitly typed port is now kept as typed and honoured in the advertised URLs, while a URL without a port keeps taking the listen port as before (discussion #337, reported by @szechyjs)
  • ACME: a reused authorization now records the challenge that was performed, at the time it was performed. When an order reused a valid authorization of the same account, the built-in server created the new authorization with all three challenge types (dns-01, http-01, tls-alpn-01) marked valid and dated to the reuse, so a renewal appeared validated by methods that were never attempted, on an instance with no DNS provider. The reused authorization now carries only the challenge(s) the client completed, with their original validated timestamp; its expiry stays that of the original validation, since reuse does not extend a proof of control. The Orders tab of an ACME account derived an order's method from the first challenge row, which is always dns-01, and so reported DNS-01 for the renewal and for a rejected order alike; it now names the validated challenge(s), the challenge the client attempted when validation failed, and N/A for an order whose challenges were never answered; on a multi-identifier order the choice is made per identifier and merged, so a name proved by dns-01 next to one that failed http-01 lists both. Authorizations reused before this fix keep the three validated rows they were given and are listed with all three methods (#338, reported by @JoseGoncalves)

Full history: CHANGELOG.md


Installation

Docker (Recommended)

# From Docker Hub
docker pull neyslim/ultimate-ca-manager:2.226

# Or from GitHub Container Registry
docker pull ghcr.io/neyslim/ultimate-ca-manager:2.226

# Run
docker run -d -p 8443:8443 \
  -e SECRET_KEY=$(openssl rand -hex 32) \
  --name ucm neyslim/ultimate-ca-manager:2.226

Debian/Ubuntu

wget https://github.com/NeySlim/ultimate-ca-manager/releases/download/v2.226/ucm_2.226_all.deb
sudo dpkg -i ucm_2.226_all.deb
sudo apt-get install -f

Fedora/RHEL

wget https://github.com/NeySlim/ultimate-ca-manager/releases/download/v2.226/ucm-2.226-1.fc43.noarch.rpm
sudo dnf install ./ucm-2.226-1.fc43.noarch.rpm

Silent/Automated Install

# Skip firewall prompts for CI/automation
sudo UCM_PORT=8443 UCM_FIREWALL=no dpkg -i ucm_2.226_all.deb

Default Credentials

  • Username: admin
  • Password: changeme123

Change the password immediately after first login!

Documentation