📜 Recent release history (last 2 versions)
[2.234] - 2026-09-25
Added
- The certificate list has a sortable Created column, the date the entry was added to UCM (#368).
- Whatever is created from the interface opens straight away instead of being left to find in a list: an issued, signed or approved certificate, a new CA, a CSR, a trust store entry, an SSH CA or certificate, and the single object of a Smart Import (#368).
- Settings › Security offers Encrypt remaining keys while private key encryption is enabled and some keys are still stored unencrypted, where the only way from the screen before was to disable encryption and enable it again (#367, by @stefanelul2000).
- Certificate templates take a subject Email, which Issue Certificate fills in when the template is chosen; like an Email typed in the form, it also becomes a SAN on email and combined certificates (#373, by @seanpdiaz).
Fixed
- Certificates stored by the ACME client kept their private key unencrypted while private key encryption was enabled. The key is now encrypted like every other, and keys stored before are encrypted with Encrypt remaining keys (#367, by @stefanelul2000).
- Disabling private key encryption decrypted only CA and certificate keys before removing the master key, which left SSH CA keys, deployment target keys, ACME account and EAB keys, SCEP challenges and LDAP bind passwords unreadable. Every secret under the master key is now decrypted first, with nothing changed if one fails, and the encryption status, Encrypt remaining keys and the startup check for a missing master key cover them all.
- ACME EAB HMAC keys and ACME account keys stored in settings travelled in a backup as the source installation's ciphertext, which the target cannot read. They are now exported in the clear, protected by the archive, and restored under the master key.
- Disabling private key encryption while the
KEY_ENCRYPTION_KEYenvironment variable is set decrypted the keys and reported success, then reloaded the variable's key and left encryption on. It is now refused, and Settings › Security no longer offers it when the key comes from that variable. - A PostgreSQL installation stopped starting once pip installed SQLAlchemy 2.1, which resolves a
postgresql://URL to the psycopg 3 driver UCM does not ship. A PostgreSQL URL without a driver now uses psycopg2, and SQLAlchemy is held below 2.1. - Saving any settings section erased the automatic backup password, which the screen never gets back and sent empty. A blank password now keeps the stored one, Settings › Backup shows whether one is set, and an API client clears it with
"clear_backup_password": true(#367, by @stefanelul2000). - Importing a template lost its subject fields, key usage and extended key usage, and a round-trip dropped the AD-derived subject, autoenrollment, allowed AD group and pinned subject fields. All of them now survive export and import, and Templates › Import also takes a file holding several templates (#369, #371, by @seanpdiaz).
[2.233] - 2026-09-23
Added
- The Active Directory Connector takes several domain controllers, one per row, and lookups fail over between them, so one DC being down no longer stops certificate enrollment. Naming each DC by its own hostname is also what makes
Verify SSL Certificateusable on a multi-DC domain, where a domain controller certificate carries only its own host in the SAN (#363, by @stefanelul2000). - A scheduled health check binds to each of the connector's domain controllers on a configurable interval, so an unreachable one is skipped at enrollment time instead of being rediscovered by a request that waits out its connect timeout. The verdict shows on the settings row and against each DC in the dialog; it expires, and it can never rule out every DC (#363, by @stefanelul2000).
- Intune app registrations are defined once, under SCEP › Intune app registrations, and picked per SCEP profile: one tenant, client ID and secret shared by the profiles that validate with it, tested and rotated in one place. (#358)
- CRLs can be deployed over SSH/SFTP whenever they change, with durable per-target delivery, PEM parent-CRL bundles or a single DER CRL, on-demand deployment, and editable certificate and CRL bindings. Reload commands now belong to each binding so one SSH target can safely serve different services. Pending retries show their last error and a live countdown to the next attempt, refresh automatically while waiting, and bindings can be enabled or disabled from their edit dialog.
Changed
- The Active Directory Connector requires a bind DN and a bind password while it is enabled, in the settings form as well as in the API, and will not bind without both anywhere it binds: lookups, the scheduled health probe and either connection test. On upgrade, an enabled connector saved without a password stops answering lookups until credentials are entered in the settings dialog, and an API client must send both when it enables one (#363, by @stefanelul2000).
- A SCEP profile names its Intune app registration instead of carrying the credentials; migration 092 gives every existing Intune profile a registration named after it, shared by the profiles that used the same tenant, client ID and secret. A different secret for the same tenant keeps a registration of its own, reported in the log for a merge by hand; two registrations for one tenant and client ID cannot be created through the API. The pre-092 profile fields stay accepted for one release.
- Deployment target settings now contain only the reusable SSH/SFTP connection. Destination paths, file options and reload commands are configured on each certificate or CRL binding; migration 091 copies existing target reload commands to existing bindings.
Fixed
- The Certificates table and the certificate pickers named a certificate by its description, which hid its Common Name. The Common Name now comes first with the description alongside, in the list, its CSV export, the certificate pickers and the bound HTTPS certificate (#365, by @B0F1B0).
- The TLS certificate selector of the public ACME endpoint offered only the first 20 certificates, and the certificate picker never showed how many SANs a certificate carries. The selector now lists every certificate, and the picker counts the SANs of a certificate that has several.
- In the Docker image, SoftHSM kept its tokens outside the data volume unless a separate volume was mounted, so recreating the container lost every SoftHSM key. Tokens now live in the data volume, and those of a volume at
/var/lib/softhsm/tokensare carried over at the first start (seedocs/HSM_DOCKER.md). - Saving an HSM provider without retyping its PIN, password, client secret or token replaced the stored secret with an empty one. The stored secret is now kept unless a new one is typed.
- On DEB and RPM installs, the service could not write to the SoftHSM token directory, so creating a SoftHSM key failed with a read-only file system error. The unit now opens that directory to the service.
- A CSR, certificate or CRL signed by an EC key held in a PKCS#11 or Azure Key Vault HSM carried the raw
r || ssignature the HSM returns, so OpenSSL and every external signer rejected it. The signature is now DER-encoded as X.509 requires on every path, the generic key signing endpoint included, and a CA created or renewed on an HSM key keeps the digest matching its curve (#366). - The templates list called a template Certificate or CA from the letters "ca" in its name, so the seeded Email Certificate (S/MIME), Client Authentication and Smartcard Logon were each shown as a certificate authority. The column reads the
is_systemflag the API already returns and says System or Custom (#364, by @stefanelul2000). - The detail pane of a system template offered an Edit and a Delete the server answers 403 to. Both are greyed with the reason now, Duplicate and Export stay available, and a Show system toggle hides the built-in templates, remembered across visits and forced on while no custom template exists (#364, by @stefanelul2000).
Full history: CHANGELOG.md
Installation
Docker (Recommended)
# From Docker Hub
docker pull neyslim/ultimate-ca-manager:2.235-rc1
# Or from GitHub Container Registry
docker pull ghcr.io/neyslim/ultimate-ca-manager:2.235-rc1
# Run
docker run -d -p 8443:8443 \
-e SECRET_KEY=$(openssl rand -hex 32) \
--name ucm neyslim/ultimate-ca-manager:2.235-rc1Debian/Ubuntu
wget https://github.com/NeySlim/ultimate-ca-manager/releases/download/v2.235-rc1/ucm_2.235.rc1_all.deb
sudo dpkg -i ucm_2.235.rc1_all.deb
sudo apt-get install -fFedora/RHEL
wget https://github.com/NeySlim/ultimate-ca-manager/releases/download/v2.235-rc1/ucm-2.235.rc1-1.fc43.noarch.rpm
sudo dnf install ./ucm-2.235.rc1-1.fc43.noarch.rpmSilent/Automated Install
# Skip firewall prompts for CI/automation
sudo UCM_PORT=8443 UCM_FIREWALL=no dpkg -i ucm_2.235.rc1_all.debDefault Credentials
- Username:
admin - Password:
changeme123
Change the password immediately after first login!
Documentation
- Installation Guide
- API Documentation