Skip to content

v2.194-rc1

Pre-release
Pre-release

Choose a tag to compare

@github-actions github-actions released this 17 Jul 11:21
· 490 commits to main since this release
πŸ“œ Recent release history (last 2 versions)

[2.193] - 2026-07-17

Changed

  • WinRM admin channel dependencies bundled β€” pywinrm and requests-ntlm are now part of the default requirements (pure-python wheels), so the Microsoft CA admin channel (revoke/unrevoke, CRL publish, inventory sync) works out of the box on Docker, DEB and RPM without a manual pip install β€” previously impossible in policy-restricted or air-gapped deployments. requests-kerberos stays optional (C-extension dependencies). (#159)

Added

  • ACME preferred certificate chain β€” per-account preferred_chain (trust-anchor CN, e.g. ISRG Root X1) selects an RFC 8555 Link: rel="alternate" chain during certificate download in the ACME client and proxy; matches last cert subject or issuer CN; alternate issuer chains are rebuilt with the primary leaf when intermediates differ; UI field on the multi-CA account manager. (#197)

Fixed

  • SoftHSM token persistence in Docker Compose β€” docker-compose.yml and docker-compose.simple.yml now mount ucm-hsm-tokens:/var/lib/softhsm/tokens like docker-compose.hsm.yml already did. Without it, the token auto-initialized by the entrypoint was lost on container re-creation, orphaning the SoftHSM-Default provider row and any keys stored under it. (#195)
  • PKCS#11 config key normalization (#198) β€” migration 057 rewrites legacy library_path/pin rows to module_path/user_pin; startup repair for existing SoftHSM-Default; runtime alias acceptance in PKCS11Provider. Extends #194.

Security

  • ACME proxy post-directory SSRF β€” upstream directory, nonce, and signed POST-as-GET calls now use DNS-pinned safe_request_get / safe_request_head / safe_request_post with validate_url_not_cloud_metadata(), matching the hardened ACME client path.

[2.192] - 2026-07-11

Security

  • /api/v2/auth/methods trusted-proxy gate β€” the unauthenticated auth-method discovery endpoint re-parsed reverse-proxy X-SSL-Client-* headers without checking is_request_from_trusted_proxy(), so a remote caller who knew an enrolled certificate serial could learn the mapped UCM username (mtls_user) without a session. The endpoint now applies the same trusted-proxy gate as login_mtls(). (GHSA-p4hj-mmxv-xh65)
  • Legacy settings webhook test DNS rebinding β€” POST /api/v2/settings/webhooks/<id>/test validated the URL once then called bare requests.post(), which re-resolved DNS and could reach cloud metadata or loopback despite the check. The test path now uses DNS-pinned safe_request_post(), matching the hardened /api/v2/webhooks delivery path. (GHSA-q7j8-h9jm-qxw8)
  • ACME multi-CA account directory SSRF β€” creating or registering an external ACME CA account accepted any https:// directory_url and fetched it with an unpinned HTTP client, allowing loopback/cloud-metadata targets despite the narrow SSRF guard used elsewhere. Account create/register now validates with validate_url_not_cloud_metadata() (RFC1918 internal CAs remain allowed) and directory fetch uses DNS-pinned safe_request_get() with the configured acme.client.verify_ssl setting preserved. (GHSA-5p92-5vpr-2x5w)
  • Smart import / OPNsense CA import permission gate β€” CA (and private-key) ingestion now requires write:cas, matching POST /api/v2/cas/import. Smart import gates on parsed CA presence in the content (cert-only imports still work with write:certificates alone). (GHSA-rgcp-9wxj-6896)
  • Smart import CA gate bypass for legacy CA certs without BasicConstraints β€” the write:cas gate classified CA material by BasicConstraints CA:true alone, so a legacy root that asserts keyCertSign in Key Usage but omits BasicConstraints was treated as a leaf and could be imported (and routed into the CA store) with write:certificates only. Import now treats a certificate as CA material when it has either BasicConstraints CA:true or keyCertSign, both for the permission gate and for CA-vs-leaf routing.
  • SAML IdP metadata fetch DNS rebinding β€” POST /api/v2/sso/saml/metadata/fetch now uses DNS-pinned safe_request_get() instead of a bare requests.get() after one-shot SSRF validation. (GHSA-9crx-4487-wvxc)
  • Global search user PII scope β€” GET /api/v2/search returns user email/role only when the caller holds read:users, aligning with /api/v2/users. (GHSA-4v84-cxgw-8g4g)
  • /api/v2/auth/methods username enumeration β€” pre-authentication responses no longer expose per-user mtls_certificates counts that leak valid usernames (distinct from GHSA-p4hj header-forgery). (GHSA-xxhm-683g-fjj5)
  • ACME proxy EAB gate on new-order β€” when acme_eab_required was enabled, POST /acme/proxy/new-order required both jwk and kid in the protected header, but RFC 8555 Β§6.2 makes them mutually exclusive, so every request was rejected (kid-authenticated orders failed with "Missing JWK"). The gate now requires kid (registered account) only.
  • ACME proxy concurrent cert/order mis-binding β€” get_certificate() picked the newest pending proxy order instead of matching the upstream certificate URL, so concurrent orders could return the wrong certificate. Certificate download now resolves the order via upstream certificate URL; finalize also binds the requester JWK thumbprint when stored on the order.
  • ACME client post-directory SSRF β€” after the initial directory fetch was pinned (GHSA-5p92), _get_nonce() and _post() still used unpinned session.head() / session.post() for URLs embedded in directory JSON, allowing DNS rebinding to loopback or cloud metadata. All ACME client outbound calls now validate with validate_url_not_cloud_metadata() and use DNS-pinned safe_request_head() / safe_request_post().

Added

  • Certificate list: filter by source β€” the Certificates page has a new Source filter (multi-select) alongside status and issuer, to narrow the list by issuance origin: Manual, Import, Local ACME, Let's Encrypt, SCEP, EST, and Microsoft AD CS. Backed by GET /api/v2/certificates?source=<...> (repeatable for multi-select); legacy rows with no recorded source are matched under "Manual".
  • Public endpoints GUI β€” admin, protocol HTTP, and ACME vhost β€” Settings β†’ General β†’ Endpoints publics to configure canonical admin URL (base_url), protocol HTTP base (protocol_base_url), and ACME public vhost with effective ports from HTTPS_PORT / HTTP_PROTOCOL_PORT. Includes dynamic CORS origins, Utiliser l'URL du navigateur, and VΓ©rifier DNS et TLS preflight (local, corporate/internal via UCM_CORPORATE_DNS_SERVERS, and public resolvers) plus TCP/TLS reachability checks. Host middleware soft-redirects IP/alias hosts to the canonical admin origin, serves ACME paths on the split vhost only, and rejects untrusted X-Forwarded-Host when ProxyFix is enabled. API: GET/PATCH/POST /api/v2/settings/public-endpoints. Docs: docs/testing/PUBLIC-ENDPOINTS.md. (#186)
  • Microsoft AD CS: CA control panel β€” approve/deny pending requests and CA health (admin channel) β€” the connection now surfaces a control panel (over the WinRM admin channel) to manage requests that are awaiting CA manager approval: list pending requests, approve them (certutil -resubmit, with the issued certificate imported into UCM automatically), or deny them (certutil -deny). It also shows a CA health snapshot β€” CA service status, CA certificate expiry, CRL next-update, and pending-request count β€” assembled from locale-neutral sources so it works regardless of the CA's display language. Pending listing and health need read:certificates; approve/deny need admin:system. Completes the CA management surface for #185; verified end-to-end against a Windows Server 2025 AD CS (approve β†’ issued β†’ imported, deny β†’ request marked denied on the CA). (#185)
  • Microsoft AD CS: CA inventory sync β€” import certificates issued directly on the CA (opt-in) β€” building on the WinRM admin channel, UCM can now import certificates that were issued on the Windows CA outside UCM (native tools, autoenrollment, or before UCM was deployed), so it can track the whole certificate lifecycle rather than only what it issued itself. The sync reads the CA database with certutil -view, imports certificates UCM doesn't already have (deduplicated by serial), and is incremental by request id (with a full-rescan option). A reconciliation view lists certificates present on the CA but not in UCM, and UCM certificates for that connection absent from the CA. Runs every 6 hours for opted-in connections plus an on-demand "Import from CA" action; import needs admin:system, reconciliation needs read:certificates. Completes the CA inventory sync requested in #185; verified end-to-end against a Windows Server 2025 AD CS. (#185)
  • Microsoft AD CS: WinRM admin channel β€” revoke, unrevoke and publish CRL on the CA (opt-in) β€” a Microsoft CA connection can now carry an optional WinRM administration channel so UCM performs real management operations on the Windows CA (which AD CS Web Enrollment cannot do). Revoking an MS-CA-issued certificate in UCM now propagates the revocation to the CA (certutil -revoke + CRL publish); lifting a certificateHold propagates the unrevoke; and a "Publish CRL" action forces the CA to issue a fresh CRL. Auth is NTLM or Kerberos over HTTP/HTTPS (Kerberos+HTTPS recommended); credentials default to the connection's own, with optional override fields for a dedicated least-privilege "Issue and Manage Certificates" account (required for mTLS-enrolled connections, which have no reusable WinRM credential). Serial numbers are validated as hex and no user-supplied string reaches the remote shell. pywinrm is an optional dependency (lazy-imported; the rest of UCM and installs without AD CS never require it). Management operations require admin:system. Verified end-to-end against a Windows Server 2025 AD CS (revocation in UCM confirmed as disposition "Revoked" in the CA database). (#185)
  • Microsoft AD CS: CRL-based revocation sync (opt-in) β€” a Microsoft CA connection can now periodically fetch the CA's CRL and mark certificates revoked on the CA as revoked in UCM (strictly one-way, CA β†’ UCM; certificates revoked locally in UCM are never un-revoked). The CRL URL is taken from the connection settings or auto-detected from the CRL Distribution Point of certificates issued by that CA, the CRL signature is verified against the CA certificate before anything is applied, and the revocation date/reason are taken from the CRL entry. Runs hourly for opted-in connections, plus a "Sync CRL now" button and POST /api/v2/microsoft-cas/<id>/sync-crl. First step of the CA inventory sync discussed in #185; verified end-to-end against a Windows Server 2025 AD CS (revocation done with certutil -revoke on the CA propagated to UCM by the scheduled sync). (#185)

Fixed

  • Microsoft AD CS: pending requests are now recognized on non-English CAs β€” the certsrv client only matches the English "Certificate Pending" enrollment page, so against a localized AD CS (e.g. a French-language CA) a genuinely pending request was misreported as denied β€” signing returned a 400 β€” and polling a still-pending request failed with a 500. UCM now classifies the AD CS response using the locale-independent HTML markers certsrv itself emits (the locInfoReqID element id, and the numeric request disposition code where 5 = under submission and 2 = denied) instead of the translated text, so submit returns a proper "pending" status and polling keeps returning "pending" until the CA manager acts. Verified end-to-end against a French Windows Server 2025 AD CS. (#159)
  • Renewing a certificate issued by a Microsoft AD CS connection now goes through the connector β€” renewal previously used the local re-sign path, which failed with "Issuing CA not found" (or "CA private key not available") because the issuing CA's key lives on the Windows CA. UCM now resubmits the certificate's original CSR (same key, subject and SANs) to the AD CS connection and template that issued it, and updates the certificate in place; if the CA holds the request for manager approval, the renewal is tracked like any pending MS CA request. EOBO-issued certificates require the same elevated permission to renew as to issue. Reported in #159. Verified end-to-end against a Windows Server 2025 AD CS.

Changed

  • Revoking a Microsoft-CA-issued certificate now states that the revocation is local to UCM β€” AD CS Web Enrollment has no revocation endpoint, so UCM cannot propagate the revocation to the Windows CA. The API response and the revoke confirmation dialog now say so explicitly (meta.msca_local_only for API consumers) and remind you to revoke the certificate on the CA itself. Reported in #159.

Full history: CHANGELOG.md


Installation

Docker (Recommended)

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

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

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

Debian/Ubuntu

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

Fedora/RHEL

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

Silent/Automated Install

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

Default Credentials

  • Username: admin
  • Password: changeme123

Change the password immediately after first login!

Documentation