Skip to content

Release Notes Archive

NeySlim edited this page Oct 14, 2026 · 2 revisions

Release Notes Archive

Release notes for older versions, kept on one page. Current and recent releases are described in the GitHub Releases and the CHANGELOG.

Contents

Highlights v2.179 to v2.214

v2.214

Cumulative highlights of the 2.209 → 2.214 releases:

  • Externally-signed CAs (v2.214) — a new CA creation mode for the offline-root / online-issuing-CA pattern: UCM generates the key pair (local or HSM) and a CA-type CSR, the external root signs it, and uploading the certificate activates the CA after strict checks (public key must match the stored private key, CA constraints enforced, automatic chain linking). Renewal re-issues a CSR from the same key. See CA Management.
  • Certificate lifecycle correctness (v2.214) — renewal is now in-place (id/refid/created_at stable, renewed_at/renewed_times history, superseded serials published on CRL/OCSP until their original expiry); revocations are persisted independently of certificate records and survive deletion; a valid, non-revoked certificate can no longer be deleted — revoke first (409 otherwise). Contributed by @gb-123-git & PMGA Tech LLP.
  • ACME proxy hardening (v2.213) — new-order requires a kid (RFC 8555 §6.2) with orders bound to RFC 7638 thumbprints, positive owner matching on every proxied resource, exact upstream authorization matching, fail-closed challenge resolution, and upstream directory/nonce caching. ⚠️ Pending pre-2.213 jwk-signed proxy orders must be re-created (see the upgrade note in the CHANGELOG).
  • Operations — discovery scans are bounded and restart-safe (v2.213); certificate/CSR bulk-action lists paginate, search and filter server-side (v2.213); API keys gained a proper revoke/delete lifecycle with "Last used" (v2.212); certificates have a mutable display name independent from the CN (v2.211).
  • ACME — http-01 validation follows redirects (RFC 8555 §8.3, v2.212); bare private TLDs (local, internal) can be registered as local domains (v2.212); multiple ACME accounts per upstream directory URL and a Tencent DNSPod DNS provider (v2.210).
  • Fixes — SSH certificates got the same deletion guard (v2.213); Azure Key Vault HSM key generation works again (v2.213); DEB/RPM upgrades keep manually installed Kerberos extras (v2.211); deleting certificates/CAs removes their on-disk files (v2.212).

v2.208

Cumulative highlights of the 2.204 → 2.208 releases:

  • Native Windows autoenrollment (MS-XCEP + MS-WSTEP, v2.207) — UCM serves the AD CS enrollment protocols: XCEP policy discovery and WSTEP issuance/renewal with three authentication bindings (WS-Security UsernameToken, client-certificate renewal, Kerberos/SPNEGO), an AD Connector to derive subjects for GPO's empty CSRs, and per-template autoenrollment flags (autoenroll_enabled, AD-derived subjects, AD-group Enroll ACL). v2.208 adds per-template pinned subject fields (C/ST/L/O/OU) and the KB5014754 SID security extension for strong certificate mapping. See Windows Autoenrollment.
  • Community security audit (v2.204) — direct private-key export moved behind the admin-only read:private_keys scope; ACME finalize validates every SAN and the CSR subject against the order (no smuggled emails/UPNs/extra CNs); the RSA ≥ 2048 / P-256+ key floor and EKU capping enforced on every issuance path; sub-CA creation gated on write:cas with pathLen clamping; opt-in UCM_REQUIRE_DB_ENCRYPTION_KEY / UCM_REQUIRE_KEY_ENCRYPTION; API keys capped to their owner's current permissions.
  • SCEP profiles (v2.204) — multiple named enrollment endpoints (/scep/<profile>/pkiclient.exe), each bound to its own CA, template, encrypted challenge and approval policy.
  • ACME improvements — per-EAB domain restrictions (v2.204), Custom Command DNS provider for DNS-01 (v2.205), dns-persist-01 persistent DNS validation (v2.205), proxy resource-ownership enforcement (v2.205), optional pruning of replaced proxy certificates (v2.206).
  • Ops & PKI — delegated OCSP responder certificates renew automatically (v2.204), CRL validity up to 5 years for offline CAs (v2.206), certificates record how they diverged from their template with a Template filter (v2.205), reverse-proxy trust decisions keyed on the real TCP peer (v2.205).
  • WebSocket security overhaul (v2.207) — authenticated handshakes (fail-closed), server-managed permission-scoped rooms, periodic re-authentication, rate-limited subscriptions.

v2.200

  • ACME client protocol coverage — upstream revocation through the proxy, ARI consumption (RFC 9773), TLS-ALPN-01 challenges (RFC 8737) and IP identifiers (RFC 8738).
  • ACME server conformance (RFC 8555) — registered error types, full order/authorization state machine, subproblem documents, contact validation, EAB protected.url verification.
  • Protocol hardening per RFC — SCEP GetCert/GetCRL + signed GetNextCACert (RFC 8894), OCSP multi-certificate requests and cache invalidation on revocation (RFC 6960), EST strict content types (RFC 7030), TSA reqPolicy validation (RFC 3161), CT pre-certificate submission with embedded SCTs (RFC 6962), CAA accounturi/validationmethods enforcement (RFC 8657).
  • Security — OIDC id_token verification against provider JWKS (fail-closed; configure the issuer in Settings → SSO before upgrading OIDC providers), ACME POST-as-GET enforced, name constraints enforced on every issuance path, delegated-authority EKUs restricted for protocol enrollees.

v2.186

  • ACME proxy fixed on fresh installs — /acme/proxy/directory and /new-nonce no longer 500 before any external CA account exists (lazy upstream account resolution; key-bearing operations still surface the configuration error).
  • Saner ACME timings — the manual DNS-01 verify is capped at 30s (the background auto-poll keeps the full dns_propagation_timeout), and per-domain authorization polling is throttled to respect CA rate limits.
  • Contact-less proxy registration — upstream account registration works again without a public contact email (RFC 8555 makes contact optional); preflight cleanup and key-reuse renewal fallback fixes.

v2.185

  • Multi-CA ACME proxy endpoints (#170) — each external CA account can expose its own proxy path at /acme/proxy/<slug>/directory (Let's Encrypt staging, production, ZeroSSL, … in parallel), alongside the legacy default endpoint. See ACME Support → Per-CA proxy endpoints.
  • Typed SAN validation on certificate issuance (#169) — SAN entries are validated per type (DNS/IP/Email/URI/UPN) with cross-type hints; RSA 3072 and NIST P-384/P-521 join the Issue Certificate selector.
  • DNS-01 propagation fixes (#171) — multi-string TXT records (Quad9) are joined before matching, dns_propagation_timeout=0 really skips the pre-check, and per-resolver diagnostics are clearly informational.

v2.184

  • Configurable RFC 5280 CA profile (#160) — Create CA exposes signature digest and Key Usage / EKU with Let's Encrypt-style defaults; intermediate notAfter is clamped to the parent CA expiry.
  • ACME key source & staging preflight (#161, #162) — reuse the same private key across renewals (DANE/TLSA), finalize with an external CSR (key never enters UCM), and dry-run requests against staging before touching production rate limits. See ACME Support.
  • Security fixes (#163) — API keys can no longer carry permissions their creator lacks; mTLS enrollment ignores client-cert headers from untrusted peers.

v2.183

  • Configurable HSTS (#154) — enable/disable, includeSubDomains and max-age from Settings → Security or UCM_HSTS_* env overrides. See Security.
  • mTLS PKCS#12 export (#156) and SSH setup script hostname validation (#157).

v2.182 / v2.181 / v2.180

  • Multi-CA ACME client (#147, #149, #150) — manage several external ACME CA accounts (per-account EAB, default selection, per-CA timing), pick the CA per request, orders pinned to their CA so renewals stay on the same authority; custom directory + EAB honored for issuance; robust DNS-01 TXT verification via authoritative nameservers; auto-renewal expiry fix. See ACME Support → External CA Accounts.

v2.179

  • Dashboard scroll fix (#144) — on narrow desktop viewports (where the sidebar pushes the grid below the large breakpoint) the lower dashboard widgets were clipped and unreachable; the grid now scrolls vertically when it overflows.
  • Lint toast cascade fix (#145) — a failed certificate lint no longer spawns an unbounded stack of error toasts; notification callbacks are now stable and concurrent lint calls are guarded.
  • Diagnostic log bundle — admin-only one-click download (Settings → About → Diagnostic) of ucm.log + error.log + access.log + systemd journal + a secret-free system diagnostic as a ZIP, with Bearer tokens, passwords, API tokens, JWTs and PEM private keys redacted. See Monitoring → Diagnostic Log Bundle.
  • See Release Notes v2.179.

v2.179

Release Date: June 27, 2026

Overview

UCM v2.179 is a focused maintenance release: two user-reported UI bugs are fixed and a downloadable diagnostic log bundle makes support tickets easier to file.

Fixed

Dashboard could not be scrolled on smaller desktop viewports (#144)

On laptops where the sidebar narrowed the dashboard grid below the large breakpoint, the grid rendered a non-scrollable multi-row layout clipped inside a fixed-height container. The lower widgets (Recent Activity, System Health, ACME Accounts, Trust Store Expiry) were unreachable. The grid container now scrolls vertically when the layout overflows instead of being clipped.

Certificate linting spawned a cascade of error toasts (#145)

The conformance-lint modal (CertificateLintModal) retriggered its own fetch in a loop whenever a lint call failed, because the toast-dispatch callbacks it depended on were recreated on every render — so a failed lint surfaced as an unbounded stack of "Could not lint certificate" toasts. Toast / notification callbacks are now stable, and the modal guards against concurrent lint calls, so a failed lint surfaces a single error.

Added

Downloadable diagnostic log bundle

A new Settings → About → Diagnostic section exposes an admin-only button that downloads a ZIP of the most relevant logs (ucm.log, error.log, access.log, the last lines of the systemd journal when available) plus a short secret-free system diagnostic (version, DB backend, migration number, services status).

Sensitive tokens are redacted before packaging:

  • Authorization: Bearer ... / bare Bearer ... tokens
  • password=..., secret=..., pass=..., passwd=... assignments
  • token=..., api_key=..., access_token=..., refresh_token=...
  • JWT-like strings (three base64 segments)
  • whole PEM private-key blocks

Each log file is capped (2 MB for app/error logs, 1 MB for access log), so the bundle stays lightweight and the most recent activity is always present. The download is audited as log_bundle_downloaded. See Monitoring → Diagnostic Log Bundle.

Upgrade Notes

  • No action required. No schema migration in this release.
  • On Docker the container logs go to stdout/journald rather than /var/log/ucm/* files, so the bundle contains only system.txt; use docker logs for full container logs.
  • On systemd hosts where the ucm user is not in the systemd-journal group, the journal is omitted (file logs are still included).

Validation

Smoke-tested on the Debian package, RPM package and Docker image (SQLite and PostgreSQL); all three distro targets passed the 13/13 API smoke and 12/12 real-UI use-case suites. The three fixes of the release were individually re-validated on each target. See the v2.179 release.


v2.174

Release Date: June 17, 2026

Overview

UCM v2.174 is a focused fix release: it makes webhook delivery exactly-once and refreshes two dependencies flagged by security scanning.

Fixed

Duplicate webhook notifications (#139)

certificate.expiring (and other events) could be delivered twice with an identical payload, while the delivery log showed a single event. Two independent causes were fixed:

  • Atomic delivery claim — each queued webhook delivery is now claimed with a conditional, single-row update before it is sent, so it is delivered exactly once even if delivery passes run concurrently.
  • Single-process scheduler — under Gunicorn (with gevent/preload) the background scheduler could run in more than one process (the scheduler greenlet was inherited by a forked worker), causing every scheduled task to run in each process. The scheduler now runs its loop in a single process (pidfile lock plus a guard that makes an inherited/forked loop exit).

Verified end-to-end: with two concurrent schedulers, each delivery results in exactly one POST.

Security

  • cryptography updated to 48.0.1 — GHSA-537c-gmf6-5ccf (vulnerable OpenSSL bundled in the wheels).
  • ws forced to 8.21.0 — CVE-2026-48779 (WebSocket memory-exhaustion DoS); pulled in transitively via the realtime client.

Upgrade Notes

  • No action required. The webhook delivery queue and scheduled tasks are unchanged in behaviour other than no longer duplicating.

Validation

Smoke-tested on the Debian/RPM packages and the Docker image (SQLite and PostgreSQL); the single-scheduler behaviour was confirmed on the DEB and RPM builds (one scheduler tick per task, no duplicates).


v2.173

Release Date: June 17, 2026

Overview

UCM v2.173 reworks how SSO accounts are identified and overhauls the Backups page. It supersedes the v2.172 SSO behaviour: instead of refusing an SSO login whose email already exists, UCM now identifies SSO accounts by the identity provider's stable identifier and lets local and SSO accounts coexist.

Changed

SSO identity by stable identifier (#136, #138)

SSO accounts are now matched on the IdP's immutable identifier, never on email or username:

  • OIDC → the sub claim
  • SAML → the persistent NameID (transient NameIDs are ignored)
  • LDAP → entryUUID / objectGUID — configurable per provider via Stable ID attribute, auto-detected by default, falling back to the DN

The identifier is bound to the account on first login, so a user is recognised across username and email changes in the directory, and the email is never used as an authentication key (removing the "account pre-hijacking" risk).

Consequences:

  • An SSO login whose email also belongs to a local account now provisions a separate SSO account — no Internal Server Error, no forced reconciliation. Email is unique only among local accounts.
  • An administrator can still merge a person's local and SSO accounts via Users → Link to SSO; linking no longer renames the local username, and the next matching login is adopted by email (then bound to the stable id). Unlink SSO reverts to a local account.

See SSO Authentication → Identity matching & shared emails. Migration 045.

Backups page

  • The Available Backups list is paginated, searchable and sortable, with multi-select bulk delete.
  • A summary header shows backup count, total size and free disk (with a warning when disk usage is high).
  • Retention is always visible (no longer hidden behind the automatic-backup toggle) and a Clean up now action applies it on demand.

Fixed

  • Backups could fill the disk — pre-migration database snapshots are capped to the most recent few, and backup retention now runs as its own daily scheduled task (previously it only ran after a scheduled backup, so manual backups accumulated indefinitely).

Upgrade Notes

  • No action required. Migrations run automatically at startup and are dual-backend (SQLite + PostgreSQL).
  • Existing SSO accounts are bound to their stable identifier on their next login. Existing local↔SSO email collisions can be reconciled at any time with Link to SSO (optional).

Validation

Verified end-to-end against real identity providers (LDAP, OIDC and SAML) and smoke-tested on the Debian/RPM packages and the Docker image (SQLite and PostgreSQL).


v2.172

Release Date: June 16, 2026

Overview

UCM v2.172 is a focused maintenance release that hardens single sign-on user provisioning and makes key-recovery dual control configurable from the UI. Both items come from field reports (#136, #137).

Fixed

SSO login with an email that already exists (#136)

An SSO (LDAP / OAuth2 / SAML) login whose email already belonged to an existing account previously caused an Internal Server Error (a users.email uniqueness violation). UCM now handles the conflict deliberately and securely:

  • The login is refused with a clear message instead of erroring out, and the conflict is recorded in the audit log.
  • UCM does not auto-create a duplicate account and does not silently merge accounts on a matching email — silent email merging is the "account pre-hijacking" attack class.
  • An administrator resolves it explicitly via Users → Link to SSO: pick the provider and (optionally) the SSO username. The next matching SSO login then adopts the existing account — role, mTLS certificates, group memberships and history are preserved.
  • Unlink SSO converts a linked account back to local; a password change is forced if it never had one.

The one-account-per-email guarantee is preserved. New admin actions link-sso / unlink-sso (audited, write:users).

See SSO Authentication → Account linking.

Key-recovery dual control is now configurable (#137)

Four-eyes control for private-key recovery could not be changed from the UI, and setting it in the service environment had no effect. Now:

  • Settings → Security → Key Recovery has a Dual control (four-eyes) toggle (admin only).
  • The KEY_RECOVERY_DUAL_CONTROL environment variable overrides the stored setting (an explicit false / 0 / no disables it). While set, the toggle is shown read-only.
  • Resolution order: environment variable → Settings toggle → default (on).

See Key Recovery → Dual control.

Upgrade Notes

  • No action required. The database migrations run automatically at startup and are reversible-safe across SQLite and PostgreSQL (the users.email uniqueness constraint is preserved).
  • Existing local and SSO accounts are unaffected; email conflicts that previously failed silently can now be reconciled with Link to SSO.

Validation

Smoke-tested on the published Docker image (SQLite and PostgreSQL) plus the Debian and RPM packages before release.


v2.170

Release Date: June 13, 2026

Overview

UCM v2.170 is a major technical release focused on standards conformance and observability. It adds certificate conformance linting, ACME Renewal Information (ARI), an opt-in Prometheus metrics endpoint, per-webhook delivery history with retry, an admin scheduler view, and functional scheduled backups — plus a round of UI layout fixes and an internal notifications refactor.

New Features

Certificate Conformance Linting

A per-certificate Lint action checks a certificate against X.509 standards and shows structured findings. Informative only — it never blocks issuance.

  • Profiles: RFC 5280 (always relevant) and CA/Browser Forum Baseline Requirements (public TLS server certs).
  • Severities: fatal / error / warning / notice / info.
  • Engine: pkilint (pure-Python, optional dependency) plus zlint when its binary is present. Degrades gracefully when no linter is installed.

See Certificate Operations → Conformance Linting.

ACME Renewal Information (ARI, RFC 9773)

The local ACME server now advertises a renewalInfo resource so clients learn the ideal moment to renew each certificate and spread renewals over time. Revoked certificates return a window in the past so compliant clients renew immediately. The endpoint is an unauthenticated GET /acme/renewalInfo/<certID>.

See ACME Support → Renewal Information.

Prometheus Metrics

An opt-in, bearer-gated /metrics endpoint in the Prometheus exposition format, configurable from Settings → General → Prometheus metrics (generate / rotate / disable the token). Exposes certificate, CA, scheduler, webhook and ACME counters.

See Monitoring → Prometheus Metrics.

Webhook Delivery History

Webhook deliveries now run from a durable async queue with exponential backoff (up to 5 attempts), and each endpoint keeps a delivery history (status, attempts, last HTTP code/error) with a manual retry button.

See Notifications → Delivery, retries and logs.

Scheduler Admin View

Settings → System → Scheduler lists UCM's background tasks with their status, last run, duration and failure count, and lets an admin Run now on demand.

Scheduled Backups

Built-in automatic, encrypted database backups on a configurable cadence (daily / weekly / monthly) with retention, run from the background scheduler. See Backup & Restore → Built-in Scheduled Backups.

Improvements

  • Notifications event bus — email and WebSocket notifications are now fanned out through a single in-process event bus, removing duplicated call-sites.
  • In-app help — contextual help panels and guides now document all of the above, in every supported language.

Bug Fixes

  • Pagination — list pages that paginated client-side (Users, Templates, SCEP, SSH CAs, CRL/OCSP, CSRs, ACME accounts, Discovery) now page through their rows correctly instead of rendering the full list on one page.
  • Layout — list tables and toolbars no longer overflow into a horizontal scrollbar in split view, modals no longer show a double scrollbar, and the CA "columns" view wraps to fill the width instead of scrolling sideways.
  • Lifecycle events — issuing, renewing or revoking a certificate (or creating/updating a CA) no longer risks an intermittent error when a webhook endpoint is configured, which could previously surface as a 500.

Database

  • Migration 041 — new webhook_deliveries table backing the durable delivery queue. Dual-backend (SQLite + PostgreSQL), applied automatically on upgrade.

Upgrade Notes

  • Drop-in replacement for v2.169. The webhook_deliveries migration applies automatically.
  • Certificate linting requires the optional pkilint package on the server; the DEB/RPM/Docker builds include it. Without it, the Lint panel reports the linter as unavailable.
  • RC validated 6/6 on DEB + RPM + Docker × SQLite + PostgreSQL.

v2.159

Release Date: June 3, 2026

Overview

UCM v2.159 introduces CA-Template Pinning, a new feature that allows administrators to pin specific templates to Certificate Authorities for quick access during certificate issuance. This release also includes important security updates and bug fixes.

New Features

CA-Template Pinning (#118)

Pin templates to specific CAs for streamlined certificate workflows:

  • Quick Access: Pinned templates appear at the top of the template dropdown when issuing certificates
  • Visual Indicators: Pinned templates display with a pushpin icon
  • Flexible Management: Pin/unpin templates directly from the CA floating window
  • Show All Option: Toggle to view all available templates when needed

Use Cases:

  • Pin frequently used templates to production CAs
  • Separate development and production template sets
  • Reduce template selection errors by limiting visible options

How to Use:

  1. Open a CA's floating detail window
  2. Click the Manage Pins button in the action bar
  3. Select templates to pin from the modal
  4. When issuing certificates from that CA, pinned templates appear first

Migration 037: ca_template_pins Table

New database table to store CA-template pinning relationships:

  • Tracks which templates are pinned to which CAs
  • Supports both SQLite and PostgreSQL backends
  • Automatically applied during upgrade

Bug Fixes

  • FloatingDetailWindow Props: Fixed canWrite and canDelete props not being passed to DetailContent, preventing action buttons from displaying
  • Action Buttons Visibility: Fixed issue where Export, Manage Pins, Take Offline, and Delete buttons were not visible in CA floating windows
  • Icon Consistency: Replaced emoji with PushPin icon from phosphor-icons for better theme compatibility
  • i18n Interpolation: Fixed "Show all X templates" button to correctly display template count

Security Updates

Frontend Dependencies

Updated critical frontend dependencies to address security vulnerabilities:

  • engine.io-client: Fixed moderate severity vulnerability
  • picomatch: Fixed high severity vulnerability
  • brace-expansion: Fixed moderate severity vulnerability
  • @vitest/coverage-v8: Fixed critical severity vulnerability

All vulnerabilities were automatically resolved using npm audit fix.

Testing

Cross-Distro Validation

Validated on 6 configurations (3 distros × 2 backends):

Platform Backend Status
Debian (DEB package) SQLite ✅ All tests passed
Debian (DEB package) PostgreSQL ✅ All tests passed
Fedora (RPM package) SQLite ✅ All tests passed
Fedora (RPM package) PostgreSQL ✅ All tests passed
Docker image SQLite ✅ All tests passed
Docker image PostgreSQL ✅ All tests passed

Test Coverage

  • Smoke Tests: 13/13 passed across all platforms
  • Use Case Tests: 11-12/12 passed (UC9 fails on empty databases as expected)
  • Migration Tests: All 37 migrations validated on both backends

Installation

Debian/Ubuntu (DEB)

wget https://github.com/NeySlim/ultimate-ca-manager/releases/download/v2.159/ucm_2.159_all.deb
sudo dpkg -i ucm_2.159_all.deb
sudo systemctl restart ucm

Fedora/RHEL (RPM)

wget https://github.com/NeySlim/ultimate-ca-manager/releases/download/v2.159/ucm-2.159-1.fc43.noarch.rpm
sudo dnf install ucm-2.159-1.fc43.noarch.rpm
sudo systemctl restart ucm

Docker

docker pull ghcr.io/neyslim/ultimate-ca-manager:2.159
docker run -d -p 8443:8443 ghcr.io/neyslim/ultimate-ca-manager:2.159

Upgrade Notes

From v2.158 or Earlier

  • Migration 037 will automatically create the ca_template_pins table
  • No manual intervention required
  • Existing templates and CAs remain unchanged
  • No template pins are created by default (pin templates manually as needed)

Database Compatibility

  • ✅ SQLite: Fully supported
  • ✅ PostgreSQL: Fully supported
  • Migration tested on both backends

Documentation Updates

  • Certificate Templates: Added section on Template Pinning
  • API Documentation: Updated with new pinning endpoints
  • CA Management: Documented Manage Pins button in floating window

🐳 Docker

Official Docker image available:

  • ghcr.io/neyslim/ultimate-ca-manager:2.159
  • Multi-architecture support (amd64, arm64)

Links


← Release Notes v2.155 | Home


v2.155

Stable release (2026-05-10). Auto-renewal UI, PostgreSQL migration recovery, LAN-friendly rate limiting, and master-key backup safeguards.

Smoke-tested 6/6 on SQLite and PostgreSQL across Debian (DEB), RHEL/Fedora (RPM), and Docker.

For the previous releases see Release Notes v2.154 and the full CHANGELOG.


Highlights

  • Auto-renewal settings UI — configure global renewal threshold, retry policy, scheduler interval, and per-CA overrides from Settings.
  • Master-key backup — one-time download of master key with confirmation modal. Docker declares /etc/ucm as VOLUME for persistence.
  • PostgreSQL migration recovery — migrations 029–034 were silently skipped on PostgreSQL. Migration 035 reconciles the schema.
  • LAN rate-limit bypass — RFC1918/loopback IPs bypass rate limiting by default (UCM is LAN-deployed).

Auto-Renewal Settings

Dedicated section in Settings page to configure automatic certificate renewal:

Setting Description
auto_renewal_enabled Global on/off toggle
auto_renewal_days Renew certificates N days before expiry
auto_renewal_sources Whitelist sources: scep, acme, est, manual, webui, api
auto_renewal_notify_emails Email addresses for renewal notifications
auto_renewal_notify_on_renewal Notify on successful renewal
auto_renewal_notify_on_failure Notify on renewal failure

API endpoints

GET  /api/v2/settings/auto-renewal       — Get current settings
PATCH /api/v2/settings/auto-renewal      — Update settings
POST /api/v2/settings/auto-renewal/run   — Trigger manual renewal run (requires admin:settings)

Master-Key Backup

New endpoints

GET /api/v2/system/security/master-key/download  — Download master key as attachment (admin:system, audited)

POST /api/v2/system/security/enable-encryption now returns the master key inline (one-time) with backup_required: true.

Frontend

  • "Back Up Master Key" action in Settings → Security when key is file-sourced
  • Confirmation modal forces download + acknowledgment before dismissal
  • Returns 409 when key is supplied via environment variable (operator must back up out-of-band)

Docker

  • Dockerfile declares VOLUME ["/etc/ucm", "/opt/ucm/data"]
  • /etc/ucm holds master.key — the symmetric key for all encrypted private keys in DB
  • If container is recreated without this volume bind-mounted, ALL encrypted keys become unrecoverable

PostgreSQL Migration Recovery (#115)

Problem

Migrations 029, 031, 032, 033, 034 were missing pg_compatible = True and were silently marked "applied" on PostgreSQL without executing, leaving the schema out of sync with the models.

Fix

  • All migrations 029–034 now have pg_compatible = True and proper dual-backend logic
  • New migration 035_reconcile_pg_schema.py reconciles any PG instances that booted on a SQLite-only release
  • Migration runner now FAILS HARD on missing pg_compatible for migrations ≥ 020

Affected migrations

# Description
029 Encrypt ACME account keys
031 ACME client accounts table
032 CA HSM key unique (no-op, healed by 035)
033 ACME authz order_id nullable
034 CA offline columns

Rate Limiter — LAN Bypass

Changes

  • RFC1918, loopback and link-local IPs bypass rate limiting by default (RATE_LIMIT_TRUST_LAN=true)
  • Standard tier raised from 300/min → 600/min and 60 burst → 100 burst
  • Auth tier: 30 rpm / 10 burst
  • Configurable via RATE_LIMIT_TRUST_LAN, RATE_LIMIT_STANDARD_RPM, RATE_LIMIT_STANDARD_BURST in /etc/ucm/ucm.env

Rationale

UCM is a LAN-deployed PKI. Private subnets are the primary use case, not an attack vector. The previous limits caused false positives on busy on-prem deployments.


Schema changes

Migration 035_reconcile_pg_schema.py (reconciles 029–034 on PostgreSQL). No new columns.


Upgrade

Drop-in replacement for v2.154. One migration (035) runs automatically at first boot.

  • Docker Hub: docker pull neyslim/ultimate-ca-manager:2.155
  • DEB: wget https://github.com/NeySlim/ultimate-ca-manager/releases/download/v2.155/ucm_2.155_all.deb
  • RPM: wget https://github.com/NeySlim/ultimate-ca-manager/releases/download/v2.155/ucm-2.155-1.fc43.noarch.rpm

v2.154

Stable release (2026-05-10). Fixes OPNsense 26.1.x certificate import.

Smoke-tested 6/6 on SQLite and PostgreSQL across Debian (DEB), RHEL/Fedora (RPM), and Docker.

For the previous releases see Release Notes v2.153 and the full CHANGELOG.


Highlights

  • OPNsense import fixed — three bugs prevented the API-based import path from working against OPNsense 26.1.x.

Fixed — OPNsense Import

Bugs fixed

  1. Frontend service did not unwrap success_response.data, so the items list was empty after Connect and the Import Selected button never rendered.
  2. Backend stored OPNsense uuid as UCM refid, breaking the caref linkage between certificates and their CA (OPNsense uses the 13-char refid as cross-reference, not the 36-char uuid).
  3. Imported private keys were stored raw instead of going through store_pem_bytes(), bypassing encryption-at-rest.

What changed

  • Importer performs a 2-pass import (CAs before certificates)
  • Resolves caref against in-flight CAs
  • Extracts SAN/SKI/AKI/serial from imported certs
  • Falls back to crt_payload/prv_payload when crt/prv are absent
  • Treats an empty selection as "import all"
  • Added regression test test_opnsense_import.py covering refid storage, caref linkage, and encrypted private-key round-trip

Upgrade

Drop-in replacement for v2.153. No new migration.

  • Docker Hub: docker pull neyslim/ultimate-ca-manager:2.154
  • DEB: wget https://github.com/NeySlim/ultimate-ca-manager/releases/download/v2.154/ucm_2.154_all.deb
  • RPM: wget https://github.com/NeySlim/ultimate-ca-manager/releases/download/v2.154/ucm-2.154-1.fc43.noarch.rpm

v2.153

Stable release (2026-05-10). CA offline mode — take a root or intermediate CA offline to block signing while keeping the public certificate usable for chain validation, CDP and OCSP.

Smoke-tested 6/6 on SQLite and PostgreSQL across Debian (DEB), RHEL/Fedora (RPM), and Docker.

For the previous releases see Release Notes v2.152 and the full CHANGELOG.


Highlights

  • CA offline mode — two modes (password-protected and file-exported) to safely decommission CA private keys while retaining the public cert.
  • Signing gate — all signing paths (CSR, CA child, CRL, OCSP) block when CA is offline.
  • Write-protected flag — only dedicated take-offline / restore endpoints can flip the offline flag.
  • Migration 034_add_ca_offline.py adds offline, offline_reason, offline_mode columns.

CA Offline Mode

What it does

Takes a CA "offline" — the private key is either re-wrapped with a user-supplied password or exported and removed from the database. The public certificate remains usable for:

  • Chain validation
  • CDP (CRL Distribution Point)
  • OCSP responder

All signing operations are blocked:

  • CSR signing
  • CA child signing
  • CRL generation
  • OCSP signing

Two modes

Mode Key handling Restore requires
Password-protected Key re-wrapped with PKCS#8 password on top of master-key encryption Password only
File-exported Key returned as password-encrypted PKCS#8 PEM, removed from DB Re-upload PEM file + password

API endpoints

POST /api/v2/cas/<id>/take-offline   — Take CA offline
POST /api/v2/cas/<id>/restore        — Restore CA online

Frontend

  • TakeOfflineModal and RestoreModal components
  • Offline-aware StatusBadge + dedicated OfflineBadge across all CA views
  • Action buttons in CADetailsPanel and floating detail window

Audit actions

ca.offline.password_protected, ca.offline.file_exported, ca.restore.password_protected, ca.restore.file_exported

Schema changes

Migration 034_add_ca_offline.py:

  • certificate_authorities.offline (BOOLEAN)
  • certificate_authorities.offline_reason (TEXT)
  • certificate_authorities.offline_mode (TEXT)

Upgrade

Drop-in replacement for v2.152. One migration (034) runs automatically at first boot.

  • Docker Hub: docker pull neyslim/ultimate-ca-manager:2.153
  • DEB: wget https://github.com/NeySlim/ultimate-ca-manager/releases/download/v2.153/ucm_2.153_all.deb
  • RPM: wget https://github.com/NeySlim/ultimate-ca-manager/releases/download/v2.153/ucm-2.153-1.fc43.noarch.rpm

v2.152

Stable release (2026-05-08). Security and RFC-compliance hardening pass across all PKI protocols (OCSP, CRL, ACME, EST, SCEP, TSA) and resource APIs (CAs, certs, CSRs, templates, RBAC, HSM, MSCA, SSO, webhooks, discovery, audit, reports, SSH, trust store).

Smoke-tested 6/6 on SQLite and PostgreSQL across Debian (DEB), RHEL/Fedora (RPM), and Docker. 33 migrations from-scratch on PostgreSQL verified.

For the previous releases see Release Notes v2.144 and the full CHANGELOG.


Highlights

  • 6 RFC-compliance fixes across OCSP (6960), CRL/profile (5280), ACME (8555/8737), TSA (3161/5035), EST (7030), SCEP (8894).
  • 20+ resource APIs hardened with input whitelists, validity caps, encrypted-at-rest secrets, FK-guarded deletes, and proof-of-possession checks.
  • 6 ACME server bypasses closed (account binding, order ownership, authz state machine, finalize URL, key change, deactivation).
  • Silent regression fixed: CA and certificate import paths now encrypt private keys at rest.
  • No breaking config changes, no manual operator action required.
  • One new schema migration: 033_acme_authz_order_id_nullable.py (ACME pre-authorisation per §7.4.1).

RFC compliance

Protocol RFC Fix
OCSP 6960 Mixed-format serial lookup, cache invalidation on revoke, correct keyHash, nonce bypasses cache, delegated responder must carry id-pkix-ocsp-nocheck
CRL 5280 Mixed-format serials, no silent truncation of serials >159 bits, auto-regen of expired CRL on CDP fetch
Cert profile 5280 5 issues fixed in CA/CSR signing paths (SKI/AKI format, BasicConstraints, EKU consistency, KU bit ordering, validity bounds)
ACME 8555 / 8737 EAB JWK match via thumbprint, JWS algorithm allowlist (asymmetric only), wildcard restricted to DNS-01, ALPN extension marked critical, case-insensitive domains; pre-authz §7.4.1 (migration 033)
TSA 3161 / 5035 signing-certificate-v2 mandatory, body cap 64 KiB, correct PKIStatus separation
EST 7030 serverkeygen encrypts the generated key under the client mTLS pubkey, not the issued cert
SCEP 8894 Renewal rejected when signer cert expired or not yet valid

Resource API hardening

  • CAs / Certs / CSRs — whitelisted key params, validity capped at 3650 days, URL validation (CRL DP / AIA / OCSP / IDP), HSM key lock on bind, EC curve whitelist, CSR proof-of-possession (is_signature_valid).
  • Templates — cap validity_days, whitelist key_type/digest, fix import NULL.
  • RBAC — reserved role names rejected (admin/operator/viewer), permission whitelist with wildcard, system roles immutable.
  • SSO — PKCE (S256) + nonce on OIDC auth flow.
  • HSM — provider secrets encrypted at rest, sign payload cap 1 MiB, FK-guarded deletes; runtime pip install opt-in via UCM_ALLOW_RUNTIME_PIP=1 (default deny).
  • Microsoft CA — fail-closed encryption, EOBO admin gate, audit, size caps.
  • Webhooks — secret encrypted at rest, event allowlist, reserved headers locked, ≤64 events per webhook.
  • Discovery — port validation, IPv6 subnet cap (≤1024), update_profile gated.
  • Audit — trusted-proxy XFF, post-cleanup integrity check.
  • Reports / SSH / Trust store — param caps, principal/extension caps, PEM size cap (256 KB), sync limit 1–1000.
  • EAB — HMAC keys encrypted at rest.
  • Users — self-change requires current password, ≥1 active admin invariant enforced.
  • Decoder tools — tools/decode-csr and tools/decode-cert capped at 256 KiB → 413.

Fixed (other)

  • Imports — CA / certificate import paths now encrypt private keys (silent regression — the previous lifecycle-mixin bypass stored base64-plain).

Tests

  • 1676 backend tests + 461 frontend tests pass.
  • 2 encryption tests made hermetic to host master.key (monkeypatch MASTER_KEY_PATH).
  • RC validated 6/6 across DEB+RPM+Docker on both SQLite and PostgreSQL.

Upgrade

Drop-in replacement for v2.151. One migration (033) runs automatically at first boot.

  • Docker Hub: docker pull neyslim/ultimate-ca-manager:2.152
  • DEB: wget https://github.com/NeySlim/ultimate-ca-manager/releases/download/v2.152/ucm_2.152_all.deb
  • RPM: wget https://github.com/NeySlim/ultimate-ca-manager/releases/download/v2.152/ucm-2.152-1.fc43.noarch.rpm

v2.144

Stable release (2026-05-03). Backend hardening, internal-helper consolidation, and release tooling improvements. No breaking changes, no schema migration.

For the previous release see Release Notes v2.143 and the full CHANGELOG.


[2.144] - 2026-05-03

Added

  • utils/key_codec.py — load_pem_bytes(prv, *, context) / store_pem_bytes(pem) helpers consolidate the previously duplicated base64.b64decode(decrypt_private_key(model.prv)) pattern across 26 sites in api/v2/* and services/*. Errors now surface a caller-supplied context ("CA 42", "certificate 17") instead of an opaque binascii.Error when a stored .prv is malformed or was encrypted with a different KEY_ENCRYPTION_KEY. See Developer Patterns → key_codec.
  • utils/db_transaction.commit_or_rollback() — boolean-returning service-layer counterpart to safe_commit() (Flask-response-returning). Replaces 10 bare db.session.commit() calls in auth/unified.py, services/mtls_auth_service.py, services/webauthn_service.py that previously could leak partial transactions on integrity errors.
  • security/encryption.encrypt_text() / decrypt_text() — text-oriented helpers (PEM, JSON blobs, plain strings) sharing the same wire format as encrypt_string() but with an unambiguous input contract. The mixed encrypt() (expects base64) vs encrypt_string() (expects text) split caused #105.
  • Generic release tooling — scripts/smoke_release.py (auth/CDP/OCSP/EST/health probe), scripts/release_publish.sh (tag + GitHub release publish), scripts/wiki_release_notes.py (changelog → wiki page generator). Lab-specific hostnames removed; everything is parameterised via --target LABEL=URL or UCM_BASE env var.
  • CI workflows — .github/workflows/tests.yml runs the backend suite against both SQLite and PostgreSQL on every push (closes the gap that let #103 ship). .github/workflows/release-smoke.yml runs smoke_release.py against the published artefacts after every v* tag.
  • Pytest postgres marker — opt-in marker for tests that require a live PostgreSQL backend; skipped by default locally, always run in CI.

Fixed

  • Silent except Exception: pass blocks in critical auth/security paths now log with exc_info=True. Specifically: auth/unified.py (4 sites: lockout config read, account-locked notification, login/logout WebSocket broadcasts, SMTP probe), api/v2/auth.py (7 sites: password policy import, password reset audit, etc.), security/csrf.py (CSRF token extraction failures), security/encryption.py, config/https_manager.py, services/audit/core.py, services/email_service.py, services/syslog_service.py, utils/backup_codes.py. These were not bugs in themselves but made post-mortem debugging of auth failures effectively impossible.
  • Latent #105-class regressions — 4 additional sites that round-tripped PEM through encrypt()/decrypt() were migrated to encrypt_text()/decrypt_text().
  • 10 bare db.session.commit() sites in auth/mTLS/WebAuthn paths now wrap in commit_or_rollback() and rollback cleanly on IntegrityError.

Changed

  • 26-site refactor to utils/key_codec.load_pem_bytes(). Behaviour-preserving (asserted by TestEquivalenceWithLegacyPattern); reduces import footprint (single utils.key_codec import vs base64 + security.encryption).

Tests

  • tests/test_key_codec.py (8 tests) — round-trip with/without KEY_ENCRYPTION_KEY, error messages with caller context, byte-for-byte equivalence with the legacy inline pattern.
  • tests/test_db_transaction.py (5 tests) — commit_or_rollback() returns False + rolls back on IntegrityError, returns True on success, no double-rollback when called twice.
  • tests/test_pem_encryption_helpers.py, tests/test_acme_proxy_key_encrypted.py, tests/test_key_encryption_pem_passthrough.py, tests/test_migration_runner_pg.py — regression coverage for #103/#104/#105 to prevent re-introduction.

Internal

  • Backend suite: 1645 passed / 1 skipped (was 1632 / 1 in v2.143).
  • Frontend suite: 461 passed.
  • RC validation: smoke matrix 3/3 PASS + use-case suite 30/30 PASS (10 UC × DEB/RPM/Docker) on v2.144-rc1 before promotion.

Upgrade notes

  • Docker (SQLite) — docker pull neyslim/ultimate-ca-manager:2.144 (or :latest).
  • Docker (PostgreSQL) — same image. Set DATABASE_URL=postgresql://user:pass@host:5432/dbname in the environment.
  • DEB — wget https://github.com/NeySlim/ultimate-ca-manager/releases/download/v2.144/ucm_2.144_all.deb && sudo dpkg -i ucm_2.144_all.deb.
  • RPM — wget https://github.com/NeySlim/ultimate-ca-manager/releases/download/v2.144/ucm-2.144-1.fc43.noarch.rpm && sudo dnf install ./ucm-2.144-1.fc43.noarch.rpm.

Operator-visible behaviour changes

  1. None. v2.144 is a hardening + refactor release. No API contract changes, no UI changes, no schema migration. Drop-in replacement for v2.143.
  2. Improved error messages when a stored private key cannot be decrypted: instead of binascii.Error: Invalid base64-encoded string, you will now see Failed to decode private key for <CA 42>: <reason>. If you see one of these after upgrade, the root cause is almost always a KEY_ENCRYPTION_KEY change between deployments — restore the original key.
  3. Logs become more verbose for previously-silent failures (auth lockouts, SMTP probes, WebSocket broadcasts, audit log writes). If you were filtering on error.log quiet, expect a small uptick. The added lines are exc_info=True tracebacks that were previously discarded.

No database schema migration is introduced by v2.144.


v2.143

Stable hotfix release (2026-05-03). Two fixes targeting PostgreSQL deployments and ACME proxy key storage.

For the previous release see Release Notes v2.141 → v2.142 and the full CHANGELOG.


[2.143] - 2026-05-03

Fixed

  • PostgreSQL migration runner crashed on startup (#103, #104). When a pending migration written for the legacy Engine interface was applied, _run_pending_pg() blew up. It now opens a single transactional Connection via engine.begin() and passes it to mod.upgrade(conn), matching the SQLite path and the migration module signatures. Without this fix, fresh PostgreSQL deployments couldn't boot past first start, and existing PG instances couldn't apply any future migration. SQLite deployments were not affected.
  • ACME proxy account private key was stored in plaintext in system_config (#105). It is now encrypted at rest with the application key via encrypt_private_key() / decrypt_private_key(). Existing plaintext keys are migrated transparently on first read — no manual action required.
  • KeyEncryption.decrypt() no longer raises binascii.Error on PEM-formatted input that was never encrypted in the first place. The probe now isolates base64 detection from Fernet decryption, so legacy plaintext keys round-trip cleanly through the new ACME proxy decrypt path.

Changed

  • Cross-target release validation now covers PostgreSQL in addition to SQLite for every supported package (DEB, RPM, Docker). The PostgreSQL backend is now part of the mandatory pre-release smoke matrix because the #103 regression only manifested on PostgreSQL and would have shipped silently against a SQLite-only matrix.

Upgrade notes

  • Docker (SQLite) — docker pull neyslim/ultimate-ca-manager:2.143 (or :latest).
  • Docker (PostgreSQL) — same image. Set DATABASE_URL=postgresql://user:pass@host:5432/dbname in the environment.
  • DEB — wget https://github.com/NeySlim/ultimate-ca-manager/releases/download/v2.143/ucm_2.143_all.deb && sudo dpkg -i ucm_2.143_all.deb.
  • RPM — wget https://github.com/NeySlim/ultimate-ca-manager/releases/download/v2.143/ucm-2.143-1.fc43.noarch.rpm && sudo dnf install ./ucm-2.143-1.fc43.noarch.rpm.

Operator-visible behaviour changes

  1. PostgreSQL deployments on v2.142 — strongly recommended to upgrade. The next migration shipped after v2.142 would have failed to apply on PG; v2.143 unblocks future migrations on PG instances.
  2. ACME proxy key migration — on first read after upgrade, an existing plaintext ACME proxy account key is re-encrypted at rest. The migration is one-way and transparent; nothing to do on the operator side.

No database schema migration is introduced by v2.143 itself.


v2.141-v2.142

Consolidated release notes for stable releases v2.141 (2026-04-29) and v2.142 (2026-05-02).

For older versions see Release Notes v2.128 → v2.140 and the full CHANGELOG.


[2.142] - 2026-05-02

Major security hardening sweep (16 fix(security): commits) plus a large modular refactor of backend services and frontend pages. No breaking API changes. Two operator-visible behaviour changes:

  • HSM dependency installer now returns 403 unless UCM_ALLOW_RUNTIME_PIP=1 is set in the environment.
  • Filesystem session directory is enforced at 0o700 at boot — a loose-permissions directory makes the application refuse to start.

Security

EST / SCEP / mTLS
  • EST /cacerts, /simpleenroll, /simplereenroll, /serverkeygen, /csrattrs now enforce est_enabled on every request and short-circuit with 503 EST disabled instead of falling through to the SPA. The /serverkeygen body is also size-capped and stricter about content negotiation. See EST Protocol.
  • EST and SCEP mTLS client certificates are only honoured when the request comes from a trusted reverse proxy (security.trusted_proxies). Direct hits without TLS termination by UCM no longer accept proxy-injected client cert headers. See EST Protocol, SCEP Server.
  • mTLS login route gated behind the same trusted-proxy check. Header-based mTLS is rejected unless the request originates from a trusted proxy. See mTLS Authentication.
  • SCEP CSRs no longer copy arbitrary KU/EKU bits — only a whitelist (digitalSignature, keyEncipherment, serverAuth, clientAuth) is honoured.
  • SCEP RFC 8894 P0/P1/P2 hardening — stricter PKCS#7 parsing, transaction-ID validation, signed/encrypted response envelope checks; iOS/macOS enrollment fixes (#102).
Authentication & secrets
  • 2FA backup codes are now hashed at rest (Argon2id) and consumed atomically; plaintext codes are returned only at generation time and never stored. See WebAuthn Support.
  • Approval quorum is race-safe and idempotent. Concurrent approvals on the same request can no longer over-approve; double-submits are deduplicated. See Approval Workflows.
  • ACME account private keys encrypted at rest with the application key. See ACME Support.
  • Password change endpoint ignores client-supplied force_change (only operators can clear that flag).
  • CSRF token entropy increased; password hash algorithm tightened; database migration identifiers validated against an allow-list.
Network / SSRF
  • Outbound webhooks revalidate the resolved IP at delivery time (DNS-rebinding window closed) and reject cloud-metadata IPs (169.254.169.254, GCP / Azure / Alibaba equivalents) and loopback. RFC1918 / .lan / .local targets remain allowed by design (UCM is on-prem). See Notifications.
  • SSO / IdP, ACME proxy and webhook URL fields all share the same SSRF helper (validate_url_not_cloud_metadata) — cloud metadata is blocked everywhere.
  • ProxyFix is opt-in via security.trusted_proxies — prevents unauthenticated X-Forwarded-For spoofing on direct deployments.
  • EST audit lines use the trusted-proxy-aware client IP instead of the raw socket address. See Audit Logs.
DoS / resource caps
  • On-demand CRL generation is serialised per-CA with a per-CA lock and 503 Retry-After: 5 under contention — closes a CPU/IO DoS vector when many clients hit /cdp/<ca>.crl simultaneously. See CRL CDP.
  • CSV bulk user-import capped at 5 MB / 10 000 rows with 413 Payload Too Large on overflow. See User Management.
  • Filesystem session directory created/enforced at mode 0o700 and the application refuses to boot if it has group/world-readable bits. See Installation Guide.
Operational opt-in
  • Runtime HSM pip install disabled by default — POST /api/v2/hsm/install-dependencies returns 403 with a hint to set UCM_ALLOW_RUNTIME_PIP=1 or install the dependency via the system package manager (apt install python3-pkcs11, dnf install python3-PyKCS11, etc.). See HSM Support.

Added

  • utils/trusted_proxy.py — shared is_request_from_trusted_proxy() / client_ip() / reject_untrusted_proxy_headers() helpers used by EST, SCEP, mTLS login and audit logging.
  • utils/ssrf_protection.py — single source of truth for validate_url_not_cloud_metadata and validate_host_not_cloud_metadata, used by webhooks, SSO, ACME proxy, OPNsense import.
  • utils/safe_commit.py, utils/require_json_body, utils/parse_request_pagination, utils/safe_call, utils/audit_event — small composable helpers applied across api/v2/* to remove boilerplate and silence intermittent rollback bugs.
  • useCRUDPage frontend hook covering 4 list / create / edit pages.

Changed

  • Massive backend modularisation. system.py (1556 l), certificates.py (2220 l), cas.py (1245 l), ssh_cas.py (1607 l), database_admin (817 l), discovery_service, pdf_generator, scep_service (981 l), acme_service (1456 l → 7 mixins ≤ 350 l), trust_store (1487 l), ca_service (788 l), restore_mixin, notification_service, audit_service, crl_service, ssh_cert_service, msca_service, account.py, acme.py, tools.py, acme_client.py, users.py, settings.py, opnsense_import and models/__init__.py were split into focused submodules. Behaviour is unchanged; module size, test isolation and review surface improve.
  • Frontend modularisation. CAsPage, CertificatesPage, DiscoveryPage, ACMEPage, SettingsPage and SsoProviderForm split into per-section sub-components under pages/<feature>/.
  • All api/v2/* db.session.commit() calls now go through safe_commit() — consistent rollback + error logging on every write path.

Fixed

  • PKCS12 / PFX export now honours the include_chain flag (#100). Previously the CA chain was always included, regardless of the request.
  • Dashboard chart cards no longer overflow the grid and System Health gained an internal scrollbar (#99).
  • iOS / macOS SCEP enrollment regressions (#102).

Internal

  • ~20 test files de-duplicated against conftest.py; pre-commit gate runs i18n sync + 461 frontend + 1613 backend tests on every commit.
  • RC validated end-to-end on Debian (DEB), Fedora (RPM) and Docker: smoke API 8/8 and Playwright use-cases 10/10 on all three targets.

[2.141] - 2026-04-29

Fixed

  • Admin lockout prevented on database backend switch (#96). Switching the database backend (SQLite ↔ PostgreSQL) no longer locks the admin out. Boolean and JSON columns are now coerced correctly when migrating rows from SQLite to PostgreSQL, the migration runs per-table in its own transaction so a single bad row no longer aborts the whole switch, and the active admin session survives the cutover. See Database Backend.
  • PostgreSQL backups via pg_dump. The Docker image now ships postgresql-client, so PostgreSQL-backed instances can produce native pg_dump backups during backend migrations and scheduled backups. See Backup & Restore.

Changed

  • In-app help covers v2.128 → v2.140 features in English plus all 8 translated languages (fr, de, es, it, ja, pt, uk, zh).
  • README features and roadmap refreshed for v2.128 → v2.140.

Internal

  • CI: backend test collection no longer fails on missing SECRET_KEY / JWT_SECRET_KEY — workflow now exports test-mode env vars before pytest runs.

Upgrade notes

  • Docker — docker pull neyslim/ultimate-ca-manager:2.142 (or :latest).
  • DEB — wget https://github.com/NeySlim/ultimate-ca-manager/releases/download/v2.142/ucm_2.142_all.deb && sudo dpkg -i ucm_2.142_all.deb.
  • RPM — wget https://github.com/NeySlim/ultimate-ca-manager/releases/download/v2.142/ucm-2.142-1.fc43.noarch.rpm && sudo dnf install ./ucm-2.142-1.fc43.noarch.rpm.

Operator-visible behaviour changes

  1. HSM dependency installer — if you were relying on the in-app Install dependencies button on the HSM settings page, set UCM_ALLOW_RUNTIME_PIP=1 in the service environment or install the package via your system package manager. Recommended path on production: install via APT/DNF and leave the env var unset.
  2. Session directory perms — UCM refuses to start if its session directory (typically /var/lib/ucm/sessions/ or /opt/ucm/data/sessions/ for source installs) has group/world-readable bits. The package post-install scripts already set this correctly. Manual installs should run chmod 0700 <session-dir>.
  3. mTLS / EST / SCEP behind reverse proxy — if you terminate TLS on a reverse proxy and rely on X-SSL-Client-* (or equivalent) headers, declare the proxy CIDR(s) under security.trusted_proxies in System Config. Direct deployments (UCM terminates TLS itself) need no change.
  4. PKCS12 export include_chain — automation that always received the chain regardless of the flag may now receive a leaf-only PKCS12 if it explicitly sends include_chain=false.

No database migration is required beyond the standard auto-migration on first boot.


v2.128-to-v2.140

Consolidated release notes for all stable releases between v2.128 (2026-04-21) and v2.140 (2026-04-27).

For older versions see the individual release pages and the full CHANGELOG.


[2.140] - 2026-04-27

Fixed

  • Certificate SAN database columns now derived from the final SAN list (#94). When a CN is auto-promoted to an rfc822Name SAN at issuance, the san_email / san_dns / san_ip / san_uri columns are now written from the canonical SAN list instead of the raw form payload, so DB queries match the X.509 extension. Migration 027_backfill_san_email re-parses existing certificate PEMs and backfills any rows that were out of sync (idempotent on SQLite and PostgreSQL). Thanks @Hemsby.
  • Certificate and CA files written to disk on creation (#95). Added SQLAlchemy after_insert listeners on the Certificate and CA models that immediately materialize .crt / .key files under data/certs/ and data/cas/ for every creation path (UI, CSR signing, ACME, SCEP, import). The startup file-regeneration scan is kept as a safety net. File-write errors are logged but never abort the database transaction. Thanks @Hemsby.

[2.139] - 2026-04-27

Added

  • ACME External Account Binding (EAB) — RFC 8555 §7.3.4. Full EAB credentials manager (backend models, API, UI under ACME → EAB Credentials). Operators can issue, list, rotate and revoke kid / hmac pairs; clients (cert-manager, certbot, acme.sh) bind their account on newAccount via JWS over the MAC key. Brings UCM in line with public ACME CAs (Let's Encrypt EAB, ZeroSSL, Google Trust Services).
  • ACME custom DNS resolvers for DNS-01 validation. Per-account override of system resolvers when validating _acme-challenge TXT records. Useful for split-horizon DNS, internal authoritatives, or when public resolvers cache stale records during automated renewals.
  • ACME on internal / private IPs — gated by acme.allow_private_ips SystemConfig (default true). HTTP-01 and TLS-ALPN-01 validation now works out of the box for RFC1918, loopback, .lan / .local / .corp targets — UCM's primary deployment model. Cloud metadata IPs (169.254.169.254) remain blocked unconditionally.
  • Kubernetes & cert-manager integration. Reference manifests under examples/kubernetes/cert-manager/ (HTTP-01 ClusterIssuer, DNS-01 ClusterIssuer with EAB, sample Certificate, EAB Secret template, README). Full integration guide on the wiki and on https://ucm.tools/docs.

Changed

  • ACME audit & RBAC hardening. Challenge state transitions now produce audit records on terminal states (valid / invalid) instead of every poll, eliminating audit log noise. account.key_change (RFC 8555 §7.3.5) is audited. delete:acme permission added to the operator role to match write:acme.
  • ACME backup/restore parity. acme_eab_credentials is now exported and restored alongside acme_accounts; full account fields (contact, status, terms-of-service, external-account-binding metadata) are now round-tripped end-to-end.

Fixed

  • backend/services/ssh_cas.py — converted f-strings containing escape sequences to raw f-strings to silence Python SyntaxWarning: invalid escape sequence on 3.12+.

[2.138] - 2026-04-25

Fixed

  • CAs page silently dropped CAs beyond the first 20 (#89) — GET /api/v2/cas defaulted to per_page=20 even when no pagination parameters were supplied, so a fresh import of 24 CAs only displayed 20 in Certificate Authorities. The endpoint now returns the full set when no pagination is requested, and continues to honour page / per_page when they are explicitly provided.
  • API key creation UX & no-expiration support (#90) — three regressions in Account → API Keys:
    • Newly issued keys are now shown in a dedicated modal with the full key in a <code> block, an explicit copy button, and a warning that the key won't be shown again. The previous toast disappeared too quickly and its copy button copied the literal string undefined.
    • The list view's per-key "copy" affordance now renders the real key prefix (e.g. ucm_ak_AbC1) instead of undefined…. Backed by a new key_prefix column persisted at creation time. Migration 026_add_api_key_prefix adds the column on SQLite and PostgreSQL; legacy keys without a stored prefix render an "unavailable (legacy key)" placeholder.
    • Leaving the expiration field empty now creates a key that never expires, matching the field's helper text. The backend distinguishes "field absent" (keeps the historical 365-day default for API/CLI compatibility) from explicit null / 0 / "" (no expiration). Validation rejects negative or non-integer values with HTTP 400.

[2.137] - 2026-04-24

Fixed

  • Datetime serialisation now consistently UTC across the API (#87) — every datetime.isoformat() returned by the backend now carries an explicit Z suffix via the new utc_isoformat() helper. Frontend components (audit log viewer, dashboards, certificate detail) consistently render in the user's local timezone without ambiguity. Backend-wide sweep: 84 auto-fixed call sites + 9 manual fixes; full backend test suite (1558 tests) green.
  • Windows SSH Host/User CA setup script — clearer diagnostics on Add-WindowsCapability failure (#75). When OpenSSH Server install fails on a domain-joined / WSUS-managed machine (typical errors 0x8024500c WU_E_PT_WMT_MISSING, 0x800f0954, WU connectivity codes), the script now prints a labelled diagnostic block: classifies the error, reports the detected UseWUServer / WUServer group-policy values, and lists three policy-compliant remediation paths (WSUS approval / FoD-from-WU policy / offline FoD ISO / manual install via Optional Features). The script never modifies WSUS or update policy itself — it explains the problem so the Windows / AD team can fix it.

[2.136] - 2026-04-24

Fixed

  • Smart Import duplicate detection (#85) — duplicate detection across Smart Import, Auto-Renewal, and mTLS enrollment previously matched only on serial_number. Per RFC 5280, serials are only unique per-issuer, so two unrelated certs from different CAs that happened to share a serial were flagged as duplicates (or worse, the wrong cert was returned).
    • New helper find_existing_cert_by_identity() uses an indexed (serial_number, issuer DN) pre-filter (RFC 5280) and confirms with the SHA-256 fingerprint of the DER bytes — globally unique, immune to PEM reformatting, 0% false positives.
    • Applied to: services/smart_import/validator._check_duplicate_cert(), services/smart_import/importer (CA + leaf cert paths), api/v2/users mTLS import, api/v2/mtls mTLS enrollment.
    • Auto-renewal lookup now also scopes by caref to disambiguate identical serials issued by different CAs.

[2.135] - 2026-04-23

Fixed

  • Database Stats panel on PostgreSQL (#83) — Settings → Database previously showed - for size and Never for Last Optimized on PostgreSQL deployments, and the panel never refreshed after Optimize / Integrity Check.
    • get_db_stats() now queries pg_database_size(current_database()) on PostgreSQL (was using os.path.getsize on the SQLite file path → always 0 → frontend rendered -).
    • Last Optimized and Last Integrity Check timestamps are persisted via SystemConfig (db_last_optimized, db_last_integrity_check) and surfaced from get_db_stats() (was hardcoded Never with a TODO).
    • SettingsPage now re-runs loadDbStats() after Optimize and Integrity Check succeed.
  • Certificate Activity chart on PostgreSQL (#84) — the dashboard chart always rendered all-zero bars on PostgreSQL.
    • Replaced SQLite-only boolean comparisons (revoked = 0, is_active = 1, ocsp_enabled = 1, cdp_enabled = 1, active = 1) with IS NOT TRUE / = true, which work on both SQLite and PostgreSQL.
    • Replaced SQLite-only datetime('now', '+30 days') in the auto-renewal status query with Python-computed bounds passed as parameters.
    • Without these fixes, the shared try block in get_certificate_trend() raised operator does not exist: boolean = integer on PostgreSQL and the except handler returned an empty trend for all three series.

[2.134] - 2026-04-23

Added

  • SMTP OAuth2 (XOAUTH2) for Gmail, Outlook.com & Microsoft 365 (#67) — modern OAuth2 authentication for outbound mail, replacing legacy app-password flows that Microsoft and Google are deprecating.
    • Three provider presets (Gmail / Outlook.com / Microsoft 365) auto-fill SMTP host, port, scopes and authorization endpoints. A "Custom OAuth2" option remains for power users who need to register their own Entra/Workspace app.
    • Outlook.com personal accounts use a simplified flow that does not require tenant ID / client secret — the user just authorizes UCM with their Microsoft account.
    • Microsoft 365 (Entra) flow keeps the full tenant-id / client-id / client-secret form for org admins.
    • Per-provider helpers display the exact redirect URI to register, and the UI surfaces clear guidance when a refresh token is missing or unverified.
    • Tokens are stored encrypted; refresh is automatic on send.
  • Friendlier Windows SSH CA setup (#75) — the PowerShell script generated by /ssh/setup no longer closes the prompt before the user can read the output, and ships with a self-elevating one-liner that downloads the script, opens an elevated -NoExit PowerShell, and bypasses ExecutionPolicy for that single run. Works around hosts where .ps1 files are blocked by policy.

Fixed

  • Database maintenance & integrity check on PostgreSQL (#82) — Optimize Database and Check Integrity previously assumed SQLite and failed on PostgreSQL deployments.
    • optimize_db() now branches on the configured backend: SQLite runs VACUUM + ANALYZE via the standard session, PostgreSQL runs VACUUM ANALYZE on a dedicated AUTOCOMMIT connection (PG forbids VACUUM inside a transaction).
    • check_integrity() runs PRAGMA integrity_check / foreign_key_check on SQLite, and a connectivity + information_schema.tables probe on PostgreSQL.
    • Frontend handleIntegrityCheck was reading the response payload at the wrong nesting level, so the success toast never fired even on SQLite — now reads response.data.passed consistently with the rest of the API surface.
    • Both endpoints continue to use the standard success_response envelope.

[2.133] - 2026-04-23

Fixed

  • SSO Default Role overrides UCM-managed roles on every login (#81) — until v2.132, _resolve_role was called inside auto_update_users for existing users and always fell back to default_role when no role_mapping matched. The result: any role change made in the UCM UI (e.g. promoting a user to admin) was silently reverted to the provider's default_role on the next SSO login. Two semantically separate concerns — userinfo sync (email/full name) and role sync — were also conflated under a single toggle.
    • auto_update_users now controls userinfo only (email, full name) and never touches the role.
    • default_role is now strictly a creation-time value.
    • Role re-sync at login is opt-in via a new sync_role_on_login flag (default false). When enabled, the role is updated only if role_mapping resolves the user's external groups to a UCM role; if no mapping matches, the stored role is preserved (no default_role fallback for existing users).
    • New backend helper _resolve_role_from_mapping() returns None when no mapping match is found, making the existing-user code path explicit.
    • DB migration 023_sso_sync_role_on_login adds the new column to pro_sso_providers (SQLite + PostgreSQL).
    • SSO settings UI gains a "Sync role from SSO on each login" toggle on LDAP, OAuth2 and SAML provider forms, with explanatory help text.
    • Help content updated (in-app help + 9 i18n locales).
    • Backend tests added covering the four behaviours: existing user role preserved, mapped sync, no-match no-op, userinfo without role, creation uses default_role.

Added

  • User authentication source tracking — every user record now exposes its origin (local / ldap / oauth2 / saml) plus the originating SSO provider when applicable. New auth_source and sso_provider_id columns on the users table, populated automatically when SSO provisions an account, and backfilled for existing SSO users by migration 024_user_auth_source (SQLite + PostgreSQL) and an in-place fallback in _get_or_create_sso_user. The Users & Groups page gains a colour-coded Source column showing both the auth method and the provider name (e.g. LDAP · Corporate AD).
  • Wiki: dedicated SSO-Authentication page covering LDAP / OAuth2 / SAML setup, role mapping, sync_role_on_login, auth_source tracking, and audit events.

[2.132] - 2026-04-23

Fixed

  • HSM provider dropdown empty in Create CA wizard (#80) — CAsPage filtered HSM providers on is_active && is_connected, fields that don't exist on the /api/v2/hsm/providers response. The dropdown was therefore always empty, displaying "No connected HSM provider" even when an HSM was correctly configured and successfully tested. Now uses the actual enabled field returned by the backend (computed as status === 'connected'). Test fixture in CertificatesForms.test.jsx updated to match the real API contract.

[2.131] - 2026-04-22

Fixed

  • PostgreSQL backend on DEB/RPM (#78) — psycopg2-binary is now declared in backend/requirements.txt so the runtime install pulls the driver automatically. Test connection and Switch to PostgreSQL no longer fail with No module named 'psycopg2' on a fresh DEB/RPM install.
  • SSO callback crash on role auto-update (#79) — the audit log call after a role change in api/v2/sso.py used keyword arguments not accepted by AuditService.log_action() (status='success') and passed the username as a positional resource_type. Rewritten with the correct kwargs (action='role_change', resource_type='user', resource_name=<username>, username=<username>, success=True). SSO logins that change a user's role no longer raise TypeError.
  • PostgreSQL URL examples harmonized — in-app help, guides and admin docs now show postgresql://user:pass@host:5432/ucm (consistent with the UI placeholder) instead of mixing in postgresql+psycopg2://. Both forms remain accepted by the backend validator.

Also in this release (carried over from cancelled v2.131-rc)

  • HSM warning is now provider-aware — the "SoftHSM not detected" banner only shows when SoftHSM is actually the configured provider. Users running OpenBao or a vendor PKCS#11 module no longer see a misleading warning.

[2.130] - 2026-04-22

Added

  • HSM-backed Certificate Authorities (#77.3) — the CA's private signing key can now be generated or stored inside an HSM and never leaves it. The Create CA wizard exposes a Key Storage toggle (Local / HSM); in HSM mode you can generate a new key in the HSM (RSA-2048/3072/4096, EC-P256/P384/P521) or pick an existing unused signing key. All certificate issuance, CRL generation and OCSP responses for the CA are signed by the HSM. PKCS#12, JKS and raw-key export endpoints return HTTP 409 for HSM-backed CAs. CA list and detail views show an "HSM" badge. In-app help and wiki updated in all 9 UI languages.

Security

  • python-dotenv upgraded to 1.2.2 to pick up the latest CVE patches.

Notes

  • HSM-backed CAs are backed by the existing HSM provider plumbing (PKCS#11, AWS CloudHSM, Azure Key Vault, GCP KMS, OpenBao/Vault Transit). Only OpenBao is exercised in CI; the other providers share the same code path but are not yet end-to-end tested.
  • In-place migration of existing local CAs to HSM and HSM key rotation for existing HSM CAs are intentionally out of scope and tracked as separate follow-up items.

[2.129] - 2026-04-21

Security

  • ACME client and proxy now offer user-controlled SSL verification — both the ACME client (upstream CA directory) and the ACME proxy (target ACME server) expose verify_ssl / proxy_verify_ssl toggles persisted via /api/v2/acme/client/settings. Default is on; the UI shows a warning banner when disabled. The proxy "Test connection" endpoint now uses the persisted flag (no per-request override) and rejects cloud metadata IPs and loopback targets.
  • Outbound HTTP sessions now verify TLS by default — utils.safe_requests.create_session() defaults to verify_ssl=True. Callers must opt out explicitly when targeting an internal endpoint with a self-signed certificate.
  • CSRF exemptions narrowed for SSO and mTLS — previously any /api/v2/sso/* or /api/v2/mtls/* route was CSRF-exempt. Exemptions are now restricted to the specific public callback/handshake subpaths; admin-write endpoints under those prefixes are now CSRF-protected.
  • WebSocket admin endpoints require admin:system permission — /api/v2/websocket/clients and /api/v2/websocket/broadcast now require admin scope instead of any authenticated session.
  • Forgot-password endpoint is now rate-limited to mitigate enumeration and brute-force.
  • API keys linked to deactivated users are now rejected — auth/unified.py checks the is_active flag in addition to the key's own validity.

Fixed

  • Service no longer starts silently when database migrations fail — run_all_migrations() failures now block startup with a clear error instead of leaving the app half-initialized.
  • Database migration runner uses DATABASE_URL as single source of truth — eliminates the SQLite path mismatch that could arise when DATABASE_URL and DATABASE_PATH disagreed.
  • Database migration target check is now fail-closed — if the emptiness check on the target database raises, migration aborts instead of continuing. The _migrations bookkeeping table DDL is now PostgreSQL-compatible (SERIAL/IDENTITY instead of SQLite INTEGER PRIMARY KEY).
  • Audit logs for background tasks no longer appear as anonymous — actions performed without a Flask request context (CRL auto-regeneration, ACME auto-approve, scheduler tasks, startup work) are now correctly labelled system, scheduler, or acme. anonymous is reserved for genuinely unauthenticated HTTP requests.

[2.128.1] - 2026-04-21

Fixed

  • Service fails to start after upgrading to v2.128 on SQLite installs — the new v2.128 database migrations did not apply on upgrade and the service stayed in a failed state. Fresh installs were not affected.

[2.128] - 2026-04-21

Added

  • Custom Extended Key Usage (EKU) OIDs when issuing certificates and signing CSRs (RFC 5280 §4.2.1.12) — the Issue Certificate form and the Sign CSR modal now expose an "Extra EKUs" multi-select that combines a dropdown of well-known EKUs (Microsoft RDP 1.3.6.1.4.1.311.54.1.2, smartcard logon 1.3.6.1.4.1.311.20.2.2, document signing, IPsec, Kerberos PKINIT, etc. — 18 catalog entries via the new GET /api/v2/eku/known endpoint) with a free-text input that accepts any well-formed dotted OID. The cert_type's default EKUs (e.g. serverAuth for server certs) remain locked-in as chips and the extras are merged on top — never replaced. Backend validation (utils/eku_validation.py) enforces a 16-OID cap, the ^[0-2](?:\.(?:0|[1-9]\d*)){1,15}$ OID regex, and explicitly rejects anyExtendedKeyUsage (2.5.29.37.0). For CSR signing, if the CSR already carries an EKU extension it is rebuilt with the merged set. Fixes #76.
  • Active filter state persisted across reloads — applying a filter on Certificates, CAs, Audit Logs, Templates, Policies, TrustStore, HSM, RBAC, SSH Certificates, SSH CAs, Users/Groups, or User Certificates now saves the live selection to localStorage (one key per filter, e.g. ucm-filter-certs-status). Reloading the page or navigating away and back instantly restores the same filter, with no flash of unfiltered data — the new usePersistedState hook reads the value synchronously in the React state initializer. Clearing a filter through the UI also removes the corresponding localStorage entry, so empty state stays clean. Works alongside the existing named filter presets (which keep using a separate …-presets key). Fixes #57.
  • Windows quick-install script for SSH CA trust — the SSH CA setup script endpoint now accepts a ?platform=windows query parameter and returns a PowerShell (.ps1) script that configures the Windows OpenSSH Server to trust the CA (writes the public key to %ProgramData%\ssh, locks down ACLs, adds TrustedUserCAKeys/HostCertificate directives to sshd_config, validates with sshd -T, and restarts the sshd service). Supports both user and host CAs, includes a -DryRun switch, and works on the public unauthenticated /ssh/setup/<refid> endpoint too. The SSH CA detail panel now shows two download buttons (Linux/macOS .sh + Windows .ps1) and two Quick Install one-liners (curl … | bash for Linux/macOS, iwr … | iex for Windows). Fixes #75.
  • User UI preferences persisted server-side — language, theme family, and theme mode are now saved per-user in the database (users.preferences JSON column) instead of only in the browser's localStorage. New endpoints GET/PUT /api/v2/account/preferences (whitelist-validated, admin or self) store the preferences, and /api/v2/auth/verify returns them so they are applied on every page load. Logging in from a fresh browser, a different device, or after clearing site data now restores the user's chosen language and theme instead of falling back to the browser locale and default theme. Migration 022 adds the column on both SQLite and PostgreSQL. Fixes #73.
  • ACME proxy orders linked to local accounts — proxy order rows now record which local AcmeAccount initiated them (FK account_id resolved from the client JWK thumbprint). The proxy order list now displays the account email/short id beside each order, and the account detail "Orders" tab now merges local + proxy orders with a "Proxy" badge so operators can see all activity per account in one place. Migration 021 backfills account_id for existing proxy orders by joining on acme_accounts.jwk_thumbprint. Fixes #71.

Fixed

  • ACME renewal storm with Let's Encrypt — AcmeClientOrder.expires_at was being set from the ACME order resource's expires field (RFC 8555 §7.1.3, ~7 days for LE) instead of the issued certificate's notAfter (typically 90 days). The renewal scheduler then re-issued the same certificate every tick, hitting the LE production rate limits. finalize_order now stores the leaf certificate's notAfter, and migration 020 backfills expires_at for all already-issued orders. Fixes #74.

Changed

  • No more compilation toolchain required at install time — gcc and python3-dev (DEB) / python3-devel (RPM) have been removed from package dependencies. Previously they were needed to build the twofish C extension pulled in transitively by pyjks (Java KeyStore export). Investigation confirmed twofish is only used by pyjks for the BKS UBER keystore format, which UCM never produces — UCM only exports JKS. pyjks is now installed via pip install --no-deps pyjks==20.0.0 in the postinst scripts (with its actual runtime deps javaobj-py3 + pycryptodomex listed in requirements.txt), keeping the install pure-wheel and ~30 MB lighter on RPM systems.

See also: Home · ACME Support · Database Backend · HSM Support · SSO Authentication · Kubernetes / cert-manager


v2.75

Release Date: 2026-03-15
Previous Version: v2.69
Download: GitHub Releases


Highlights

  • 🔒 Delta CRL Support (RFC 5280 §5.2.4) — Incremental CRL updates with DeltaCRLIndicator, FreshestCRL, dedicated CDP endpoint, and scheduler
  • 🛡️ Comprehensive Security Audit — 76 findings across 6 phases, 38 fixed (3 CRITICAL, 6 HIGH, 29 MEDIUM)
  • 📄 PDF Report Templates — Generate professional PDF reports with custom builder and scheduling
  • 🔐 PKI Protocol Hardening — ACME JWS bypass closure, EST timing-safe auth, SCEP decrypt fix, crypto validation
  • 📊 Market Comparison Roadmap — Gap analysis vs EJBCA, Vault PKI, step-ca; 9-item roadmap added

Added

Delta CRL (RFC 5280 §5.2.4)

  • Delta CRL generation — Contains only revocations since the last base CRL, reducing download size
  • DeltaCRLIndicator extension (CRITICAL) per RFC 5280 — references the base CRL number
  • FreshestCRL extension on base CRLs — points clients to the delta CRL distribution point
  • Dedicated CDP endpoint: GET /cdp/{ca_id}-delta.crl for public delta CRL access
  • API endpoints: get delta CRL, force regeneration, configure enabled/interval
  • Scheduler auto-generation — configurable interval (1–168 hours, default 4h)
  • Frontend management — Toggle column in CRL/OCSP table, detail panel with stats and interval selector
  • Security hardening — Unique index on CRL numbers, rollback on failure, is_delta filter on base CRL queries
  • Cache headers — Cache-Control and Last-Modified on all CDP routes

PDF Report Templates

  • Grid card layout for PDF report templates (Executive, Compliance, Inventory)
  • Custom report builder with section selection
  • Purple icon differentiation for PDF vs raw reports
  • Schedule PDF report generation with email delivery

Roadmap

  • Added 9-item roadmap from market comparison gap analysis to README
  • Items: Delta CRL ✅, Key Archival, CMP, TSA, SSH Certificates, K8s/Helm, Code Signing, HA/Clustering, PQC

Fixed

Security (76 findings, 38 fixed)

CRITICAL (3):

  • Removed RSA-512/1024 key generation (minimum now RSA-2048)
  • Closed ACME JWS signature bypass via alg:none
  • Fixed XXE protection in certificate parsing

HIGH (6):

  • CSR signature verification before signing
  • Certificate validity clamping to CA expiry
  • EST reenroll subject-matching enforcement
  • SCEP decrypt cipher fix
  • RBAC operator permission trimming (38→23 permissions)
  • SSRF protection on OCSP/CRL URLs

MEDIUM (29):

  • Generic error messages (no str(e) leaks)
  • Timing-safe authentication on EST/SCEP
  • Atomic ACME nonce generation
  • Content-Disposition filename sanitization
  • Discovery scan rate limiting
  • Role escalation prevention
  • ARIA overlay accessibility
  • Dashboard valid certificate count
  • Pie chart backend data
  • i18n completeness across 9 locales
  • And more...

Protocol Hardening

  • ACME: Key-change authorization, JWS algorithm validation
  • EST: Timing-safe password comparison, reenroll subject check, serverkeygen fail-safe
  • SCEP: Decrypt AES-256 fix, serial number format fix, challenge password timing-safe
  • CRL: Base CRL queries now properly exclude delta CRLs

Frontend Quality

  • Barrel export for auth-methods service
  • Theme-safe color classes
  • Reports page centered layout matching Settings pattern
  • SAN field normalization (string + array)

Dependencies

  • Bumped black 26.1.0 → 26.3.1 (CVE-2026-32274)

API Changes

New Endpoints

Method Endpoint Permission Description
GET /api/v2/crl/{ca_id}/delta read:crl Get latest delta CRL
POST /api/v2/crl/{ca_id}/delta/regenerate write:crl Force delta CRL generation
POST /api/v2/crl/{ca_id}/delta-config write:crl Configure delta CRL settings

New CDP Route

Method URL Auth Description
GET /cdp/{ca_id}-delta.crl None Public delta CRL download (DER)

Modified Endpoints

  • GET /api/v2/crl — Now returns base CRL with attached delta_crl object when available
  • GET /api/v2/crl/{ca_id} — Explicitly returns base CRL (excludes delta)
  • GET /cdp/{ca_id}.crl — Now includes Cache-Control and Last-Modified headers

Database Changes

  • Migration 004: Adds delta CRL support
    • crl_metadata: is_delta (boolean), base_crl_number (integer)
    • certificate_authorities: delta_crl_enabled (boolean), delta_crl_interval (integer, default 4)
    • Unique index on (ca_id, crl_number) for race condition prevention
  • Auto-applied on startup — no manual steps

Upgrade Notes

  • No breaking API changes
  • Database migration auto-applied on restart
  • New features available immediately after upgrade
  • Clear browser cache after upgrade for updated frontend
  • Existing CRLs remain unchanged; delta CRL must be explicitly enabled per CA

← Back to Wiki Home | View on GitHub


v2.69

Release Date: 2025-07-22
Previous Version: v2.68
Download: GitHub Releases


Highlights

  • 📊 Executive PDF Report — Downloadable multi-section PDF with cover page, risk assessment, compliance status, and charts
  • ⏰ Full Report Scheduler — 6 schedulable report types with daily/weekly/monthly frequency and email delivery
  • 🎨 Reports Page Redesign — Modern list-based layout with stat cards, inline schedule status, and mobile support
  • 🛡️ Security Hardening — Input validation improvements, email signature fix, info disclosure removal
  • ♿ Accessibility — type="button" on 18 buttons, aria-label on 9 icon-only buttons
  • ⚡ Performance — Component memoization, N+1 query fix, database-level GROUP BY

Added

Executive PDF Report

  • Multi-section executive report generated with fpdf2 and matplotlib
  • Includes cover page, table of contents, executive summary, risk assessment, certificate inventory, compliance status, lifecycle analysis, CA infrastructure overview, and recommendations
  • Charts rendered server-side with matplotlib (certificate status distribution, expiry timeline)
  • Download via Reports → Executive PDF button or GET /api/v2/reports/executive-pdf
  • Permission: read:audit + export:audit

Report Scheduler

  • 6 schedulable report types: expiring certificates, revoked certificates, CA hierarchy, audit summary, compliance status, certificate inventory
  • Configurable frequency: daily, weekly (day of week), monthly (day of month 1–28)
  • Configurable time in HH:MM format (24-hour)
  • Email delivery to up to 50 recipients per report type
  • Format selection: CSV, JSON, or PDF (executive report)
  • Schedule management via GET/PUT /api/v2/reports/schedule
  • Test email endpoint: POST /api/v2/reports/send-test

Reports Page Redesign

  • Modern list-based layout replacing the previous card grid
  • Stat cards showing report counts and schedule overview at a glance
  • Inline schedule status — see enabled/disabled, frequency, and next run for each report type
  • Fully mobile-responsive design with adaptive layout

Fixed

Security Hardening

  • Strengthened input validation across report generation endpoints
  • Fixed email signature handling for scheduled report delivery
  • Removed information disclosure from error responses in report endpoints

Accessibility

  • Added type="button" to 18 non-submit buttons to prevent accidental form submissions
  • Added aria-label to 9 icon-only buttons for screen reader support

Performance

  • Memoized expensive React components on the Reports page
  • Fixed N+1 query in report data aggregation
  • Replaced application-level grouping with database-level GROUP BY for report statistics

Upgrade Notes

  • No breaking API changes
  • Database migration adds report schedule tables (auto-applied on startup)
  • New Python dependencies: fpdf2, matplotlib (included in packages)
  • No manual steps required — upgrade and restart
  • Frontend assets are rebuilt — clear browser cache after upgrade

← Back to Wiki Home | View on GitHub


v2.68

Release Date: 2025-07-20
Previous Version: v2.52
Download: GitHub Releases


Highlights

  • 🔐 ACME Wildcard CSR Fix — Corrected wildcard certificate handling in ACME CSR generation
  • 📋 Certificate Import Metadata — Imported certificates now preserve original metadata
  • 🎨 Discord UI Fixes — 4 visual fixes for the Discord theme variant

Fixed

  • ACME wildcard CSR — Fixed CSR generation for wildcard domains (*.example.com)
  • Certificate import metadata — Imported certificates now retain source metadata fields
  • Discord theme — 4 UI fixes for visual consistency in the Discord color variant

Upgrade Notes

  • No breaking changes
  • No manual steps required

← Back to Wiki Home | View on GitHub


v2.52

Release Date: 2025-07-14
Previous Version: v2.51
Download: GitHub Releases


Highlights

  • 🔍 Certificate Discovery — Network scanner to find, track, and manage TLS certificates across your infrastructure
  • 🛡️ Security Hardening — 15 findings resolved: SSRF protection, brute-force lockouts, audit logging, encrypted secrets
  • 🔒 Error Response Sanitization — ~150 API error responses no longer expose internal details

Added — Certificate Discovery

  • Network Certificate Scanner — Scan hosts, IPs, and CIDR subnets for TLS certificates
  • Quick Scan — Instant scan without saving a profile; enter targets and ports inline
  • Scan Profiles — Save and manage reusable scan configurations with targets, ports, worker count
  • Discovered Certificates Inventory — Track all found certs with managed/unmanaged/error/expired status
  • Scan History — Browse past scan runs with duration, found/new/changed/error counts
  • CSV & JSON Export — Export discovered certificates with all metadata
  • SNI Probing — Multi-hostname TLS handshake (PTR, target, bare IP) for maximum coverage
  • SAN Extraction — Extracts all Subject Alternative Names from discovered certificates
  • Bulk DNS Resolution — Parallel PTR lookups for IP-based targets
  • WebSocket Progress — Real-time scan progress updates in the UI
  • Split-View Layout — Table + detail panel side-by-side for discovered certs, profiles, and history
  • Clickable Stats — Click stat cards to filter the table (managed, unmanaged, expired, errors)
  • Error Visibility — Scan errors shown in results with troubleshooting hints

Added — Security Hardening

  • SSRF Protection — Blocks scanning of loopback, link-local, multicast, and reserved IPs
  • DNS Rebinding Protection — PTR hostname validated with forward DNS resolution
  • 2FA Brute-Force Protection — 5 attempt limit with 15-minute lockout for TOTP verification
  • WebAuthn Brute-Force Protection — Same lockout pattern for FIDO2/WebAuthn verification
  • User Enumeration Prevention — Generic error messages for WebAuthn credential lookup
  • SSO Audit Logging — OAuth2 and SAML login success/failure events logged to audit trail
  • LDAP Audit Logging — LDAP authentication attempts logged with success/failure
  • LDAP Password Encryption — LDAP bind passwords encrypted at rest with master key
  • mTLS Trusted Proxies — UCM_TRUSTED_PROXIES env var limits which reverse proxies can inject client certs
  • SSO Rate Limiting — OAuth2 callback and LDAP login endpoints rate-limited
  • Discovery Input Validation — Target format regex, port range validation (1–65535), field length limits

Changed

  • Error Responses — ~150 API error responses no longer expose internal details (str(e) → generic messages)
  • UI Density — Discovery page uses modern split-view layout consistent with other pages

Security

  • 15 security findings identified and resolved (2 CRITICAL, 6 HIGH, 5 MEDIUM, 2 LOW)
  • All findings verified with functional tests (SSRF blocked, XSS rejected, invalid ports sanitized)

v2.51 Changes (included)

  • EST Management Page — Config, stats, and endpoint info
  • Certificate Unhold — New endpoint to release held certificates
  • System Status Badges — Enriched badges for ACME, SCEP, EST, OCSP, CRL, Auto-Renewal, SMTP, Webhooks
  • WebSocket Real-Time Updates — Live push notifications for certificate events
  • Accordion Sidebar — Collapsible navigation with grouped menu sections
  • CSR Generation Form — Generate certificate signing requests from the UI
  • Enhanced Certificate Issuance — Improved certificate issuance form with better validation
  • Global UI Density — Harmonized spacing and layout across all pages

Upgrade Notes

  • No breaking API changes
  • Database migration adds discovery tables (auto-applied on startup)
  • New environment variable: UCM_TRUSTED_PROXIES (optional, for mTLS reverse proxy setups)
  • Frontend assets are rebuilt — clear browser cache after upgrade
  • LDAP bind passwords will be automatically encrypted on first startup after upgrade

← Back to Wiki Home | View on GitHub


v2.50

Release Date: 2026-02-22
Previous Version: v2.49
Download: GitHub Releases


Highlights

  • 🔐 Login Architecture Redesign — Complete rewrite of the authentication flow
  • 🔑 mTLS Auto-Login — Zero-interaction certificate-based authentication
  • 🛡️ 6 mTLS Bug Fixes — Comprehensive fixes for mutual TLS authentication

Added

  • Login state machine — Complete rewrite with proper states: init → username → auth → 2fa/ldap. Each auth method is standalone with clean transitions
  • mTLS auto-login — Client certificate authentication now happens entirely during the TLS handshake via middleware. No explicit POST needed — browser presents cert → session created → auto-redirect to dashboard (zero user interaction)
  • AuthContext session check on all routes — Removed the /login skip guard. checkSession() now always calls /auth/verify on mount, enabling mTLS auto-login discovery
  • sessionChecked state — New boolean in AuthContext prevents flash of login form during session verification
  • Enhanced /auth/methods endpoint — Now returns mtls_status (auto_logged_in, present_not_enrolled, not_present), mtls_user, and sso_providers in a single call

Changed

  • mTLS middleware — Clean rewrite with _extract_certificate() helper (DRY), g.mtls_cert_info for cross-endpoint reuse, proper stale session handling
  • LoginPage — Removed cascade login logic. Each auth method is standalone with proper state transitions. WebAuthn auto-prompts after username entry if keys detected
  • App.jsx /login route — Shows PageLoader while session is being checked, then redirects if already authenticated

Fixed

  • mTLS peercert injection — Custom Gunicorn worker (MTLSWebSocketHandler) now correctly extracts peercert DER bytes into WSGI environ
  • OpenSSL 3.x CA names — Added ctypes integration in gunicorn_config.py to send client CA names in CertificateRequest (required for browser cert dialog)
  • Timezone-aware datetime comparison — Fixed crash in mtls_auth_service.py when comparing naive vs aware datetimes
  • Serial number format mismatch — Normalized hex/decimal serial matching in mtls_auth_service.py with fingerprint fallback
  • Scheduler SSL errors at startup — Added 30-second grace period before first scheduled task execution
  • Stale sessions blocking mTLS — Middleware now validates existing sessions before skipping certificate processing
  • checkSession() false positive — Now properly checks userData.authenticated before setting isAuthenticated=true

Technical Details

Login Flow Architecture

Browser connects → TLS handshake
  ├─ Client cert presented? → mTLS middleware auto-login → session created
  └─ No cert → continue to LoginPage

LoginPage state machine:
  init → (detect methods) → username → (enter username) → auth
    ├─ WebAuthn available? → auto-prompt hardware key
    ├─ Password → enter password → (2FA required?) → 2fa
    └─ LDAP provider selected → ldap credentials

Auth Detection Response

GET /api/v2/auth/methods
{
  "data": {
    "password": true,
    "webauthn": true,
    "mtls": true,
    "mtls_status": "auto_logged_in",
    "mtls_user": "admin",
    "sso_providers": [],
    "api_keys": true
  }
}

Upgrade Notes

  • No breaking API changes
  • No database migration required
  • Frontend assets are rebuilt — clear browser cache if login page looks stale
  • If using mTLS: users will now be auto-logged in when presenting a valid enrolled certificate

Test Results

Suite Result
Frontend (Vitest) 450 passed
Backend (pytest) 1364 passed
i18n sync ✅ All 9 locales in sync

← Back to Wiki Home | View on GitHub


v2.1.0

Release Date: July 2025
Type: Major Feature Release

Highlights

Architecture Refactor

  • Consolidated API routes: removed features/ module, all routes under api/v2/ (34 blueprints)
  • Consolidated models: removed models/features/, moved to models/
  • Removed Pro/Community distinction: all features are core
  • JWT removal: session cookies + API keys only (reduced attack surface)

PKI Chain Intelligence

  • AKI/SKI Chain Matching - Cryptographic chain validation replacing DN-based matching
  • Chain Repair Scheduler - Hourly backfill, re-chain, and deduplication task
  • Chain Repair Widget - Visual progress on CAs page with manual run
  • Smart Import Dedup - Prevent duplicate CAs via SKI matching

Floating Detail Windows

  • Click any table row to open a draggable, resizable detail window
  • Embedded content with action bar: Export (PEM, DER, PKCS#12, chain), Renew, Revoke, Delete
  • Window manager in footer: stack/tile, same-window, close-on-navigate
  • Deep-link support for certificates, CAs, and trust store items

Trust Store Enhancements

  • Chain validation with visual status (complete/partial/incomplete)
  • Export bundle (PEM), expiration alerts widget
  • Add certificates from managed CAs (backend + UI)
  • Auto-add issuer to trust store from certificate details

Operations Center

  • Unified Import, Export, and Bulk Actions under a single sidebar page
  • Smart Import with automatic format detection + OPNsense sync
  • Export action cards per resource type with PEM and P7B download
  • Bulk Actions with resource type chips, inline search, status/CA filters

Service Reconnection

  • 30s countdown before reconnection attempts
  • Health endpoint includes WebSocket readiness status (/api/v2/health)
  • Automatic redirect to login page after service restart
  • Browser cache invalidation on reconnect

In-App Help System

  • Floating contextual help panel on every page
  • Draggable, resizable, with mobile bottom-sheet mode
  • Tips, warnings, and related page links

UI/UX Redesign

  • Dashboard: redesigned header with logo, diversified widget colors, donut chart with gradient/shadow effects
  • Dashboard mobile: compact header with watermark logo, no redundancy with navbar
  • New logo: shield outline, larger on dashboard, smaller in sidebar
  • Themes simplified: 3 themes (Gray, Purple, Sunset)
  • Tables: proportional column sizing, actions moved to detail windows
  • Status footer bar with window management controls
  • Mobile navbar: user dropdown menu with account, settings, language selector, logout
  • Mobile nav grid: short i18n labels for compact 5-column layout
  • Reconnect overlay with circular countdown ring

Internationalization

  • 9 languages: EN, FR, DE, ES, IT, PT, UK, ZH, JA
  • 2273+ translation keys per language, 0 missing
  • Short mobile labels: 16 *Short keys per language for compact navigation
  • New namespaces: reconnect.*, table.*, windows.*

Export System

  • Unified ExportModal with tabbed interface (PEM, DER, PKCS#12, Chain PEM)
  • RBAC permission guards on private key access
  • Certificate, CA, and Trust Store export from detail windows and floating windows

Dashboard Charts

  • Certificate Activity chart with Issued/Expired/Revoked series
  • Day selector (7d/15d/30d) with optimized grouped SQL queries
  • Status distribution pie chart
  • Draggable grid layout with persistent positions

SSO Redesign

  • SSO settings restructured with collapsible sections per provider type
  • LDAP: Connection → User Search → Groups & Role Mapping → Provisioning
  • OAuth2: Provider Preset (Azure/Google/GitHub) → Connection → Attribute Mapping → Provisioning
  • SAML: Identity Provider → SP Endpoints → Attribute Mapping → Provisioning
  • Test Connection and Test Mapping buttons for LDAP validation
  • OAuth2 presets auto-fill URLs for Microsoft Entra, Google, GitHub
  • 1 provider per type limit with 3-card layout: LDAP, OAuth2, SAML
  • Login page: SSO buttons shown first with "or sign in locally" separator
  • Fix: LDAP group filter with special characters in user DN

Role System

  • 4 system roles: Admin, Operator, Auditor (new), Viewer (renamed from User)
  • Auditor: read-only access to all operational data except settings/users
  • Viewer: restricted to certificates, CAs, CSRs, templates, truststore
  • Orange badge for auditor role across all UI views
  • Migration 036 auto-renames existing roles for seamless upgrade

Reports & Governance

  • Scheduled compliance reports with certificate inventory
  • Certificate policies with key usage and validity constraints
  • Approval workflows for certificate issuance

Security & Code Quality

  • Default admin password changeme123 with force password change on first login
  • cryptography upgraded to 46.0.5 (CVE-2026-26007)
  • RBAC with custom roles and granular permissions (read/write/delete/admin per resource)
  • Auto-update DEB postinst fix: updater systemd units
  • ESLint (frontend) + Ruff (backend) linters added to CI pipeline
  • 17 bugs found and fixed by linters
  • Login method persistence across sessions
  • SAML SP certificate selector for multi-cert environments
  • LDAP directory presets (Active Directory, OpenLDAP, FreeIPA)
  • CSRF token fix for multi-method login (password + SSO)

Other Features

  • Backup v2.0 - Complete backup/restore for all database tables
  • File Regeneration - Startup service regenerates missing cert/key files from database
  • Human-Readable File Names - {cn-slug}-{refid}.ext instead of UUID-only
  • SoftHSM Integration - Automatic SoftHSM2 setup across DEB, RPM, Docker
  • Webhooks - Management in Settings for CRUD, test, and event filtering
  • ACME Multi-CA - Let's Encrypt, ZeroSSL, Buypass, custom ACME servers
  • Template Duplication - Clone endpoint: POST /templates/{id}/duplicate
  • Settings About - Version, system info, uptime, memory, links

Bug Fixes

  • Health endpoint consolidated under /api/v2/health (backward-compatible)
  • ACME account delete: cascade cleanup (challenges→authorizations→orders)
  • FloatingHelpPanel: missing SOFT_MAX_W constant
  • Dashboard charts: fixed width/height(-1) errors with absolute positioning
  • Dashboard donut: fixed gradient IDs using translated names (SVG invalid refs)
  • Dashboard: react-grid-layout v2.2.2 API compatibility
  • OPNsense: wrapped password inputs in form element (DOM warning)
  • Toast notifications: stack vertically
  • Radix Select: filter empty value options
  • Truststore delete: returns 200 instead of broken 204
  • CRL: returns null data instead of 404 when not yet generated
  • UTC timezone handling: API timestamps include 'Z' suffix
  • Reports page: fixed infinite loop caused by unstable useCallback deps
  • Z-index hierarchy: confirm/prompt dialogs now render above floating windows
  • Table refresh: data reloads after floating window actions (revoke/renew/delete)
  • Chart labels: readable X-axis with dynamic interval, solid line styles
  • Force password change: fixed flag not being set in database_health.py admin creation
  • LDAP group filter: escape special characters in user DN for group membership queries

Screenshots

Page Screenshot
Dashboard Dashboard
Certificate Detail Certificate Detail
CA Detail CA Detail
SSO Settings SSO Settings
RBAC Roles RBAC
Policies Policies
Reports Reports
Operations Operations
Trust Store Trust Store
Settings Settings

Breaking Changes

  • Operations page replaces the old Import/Export page
  • Themes reduced from 6 to 3 color schemes
  • JWT authentication removed (session cookies + API keys only)

Upgrade Notes

  • Existing installations: database migrations run automatically at startup
  • Migration 036 renames the "User" role to "Viewer" and creates the "Auditor" role automatically
  • The default password change only affects new installations
  • All existing user passwords remain unchanged
  • Health endpoint available at both /api/v2/health and /api/health
  • SSO configurations are preserved; the new collapsible layout activates on first load

v2.0.3

Release Date: February 10, 2026
Type: Patch Release (Bug Fixes)


🐛 Bug Fixes

CA Creation Fix (#18)

  • Fixed a crash when creating a Certificate Authority on fresh Docker installations
  • The validityYears and keySize fields could be sent as null from the frontend, causing a Python TypeError
  • Now gracefully defaults to 10 years and 4096 bits when values are null

DN Field Validation

  • Country code auto-uppercase: Entering fr now automatically converts to FR across all endpoints (CAs, Certificates, CSRs)
  • CSR validation: Added missing Distinguished Name field validation to the CSR creation endpoint (was previously unchecked)

🐳 Docker Improvements (#17)

Unified Data Path

  • All Docker data now stored in /opt/ucm/data — same path as DEB/RPM installations
  • Previously, Docker used /app/backend/data while packages used /opt/ucm/data, causing confusion with volume mounts

Migration Support

  • Automatic detection and migration of data from the old path (/app/backend/data) on container upgrade
  • No data loss — existing databases, certificates, and CA files are preserved

Simplified Volume Mount

# Before (confusing - which path?)
-v ucm-data:/app/backend/data    # ❌ Old Docker path

# Now (unified across all installations)
-v ucm-data:/opt/ucm/data        # ✅ Same everywhere

🔧 Auto-Update Fix

  • Fixed No module named 'services.audit' error when using the built-in update feature
  • The audit logging import was referencing a non-existent module

📝 Documentation

  • Updated all installation guides with correct Docker volume paths
  • Updated docker-compose examples
  • Updated version references across all documentation

📦 Installation

Docker

docker pull ghcr.io/neyslim/ultimate-ca-manager:2.0.3

Debian/Ubuntu

wget https://github.com/NeySlim/ultimate-ca-manager/releases/download/v2.0.3/ucm_2.0.3_all.deb
sudo dpkg -i ucm_2.0.3_all.deb

RHEL/Fedora/Rocky

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

⬆️ Upgrade

From v2.0.0

Simply install the new package — it's a drop-in replacement.

Docker users

docker pull ghcr.io/neyslim/ultimate-ca-manager:2.0.3
docker stop ucm && docker rm ucm
docker run -d --name ucm -p 8443:8443 -v ucm-data:/opt/ucm/data ghcr.io/neyslim/ultimate-ca-manager:2.0.3

Note: If upgrading from v2.0.0 Docker, your data in /app/backend/data will be automatically migrated to /opt/ucm/data.


Full Changelog: v2.0.0...v2.0.3


v2.0.0

Release Date: February 7, 2026

This is a major release with a completely redesigned frontend and significant backend improvements.


🎨 Complete UI Redesign

New Frontend Stack

  • React 18 with Vite for fast builds
  • Radix UI for accessible components
  • Custom CSS with theme variables
  • Split-View Layout with responsive design

New Features

  • 12 Theme Variants - 6 color themes (Gray, Ocean, Purple, Forest, Sunset, Cyber) × Light/Dark modes
  • User Groups - Organize users with permission-based groups
  • Certificate Templates - Predefined certificate configurations
  • Smart Import - Intelligent parser for certs, keys, CSRs
  • Certificate Tools - SSL checker, CSR decoder, certificate decoder, key matcher, format converter
  • Command Palette - Ctrl+K global search with quick actions
  • Trust Store - Manage trusted CA certificates
  • ACME Management - Account tracking, order history, challenge status
  • Audit Logs - Full action logging with filtering, export, and integrity verification
  • Dashboard Charts - Certificate trend (7 days), status distribution pie chart
  • Activity Feed - Real-time recent actions display

UI Improvements

  • Responsive Design - Mobile-first with adaptive layouts
  • Mobile Navigation - Grid menu with swipe support
  • Keyboard Navigation - Full keyboard accessibility
  • Real-time Updates - WebSocket-based live refresh
  • Inter + JetBrains Mono fonts
  • Contextual Help - Help modals on every page

🔐 Security Enhancements (v2.0.0-beta2)

  • Password Show/Hide Toggle - All password fields now have visibility toggle
  • Password Strength Indicator - Visual strength meter with 5 levels
  • Forgot Password Flow - Email-based password reset with secure tokens
  • Force Password Change - Admin can require password change on next login
  • Session Timeout Warning - 5-minute warning before session expires

🔧 Backend Improvements

  • API v2 - RESTful JSON API under /api/v2/
  • Unified Paths - Same structure for DEB/RPM/Docker (/opt/ucm/)
  • Auto-migration - Seamless v1.8.x → v2.0.0 upgrade with backup
  • CRL Auto-regeneration - Background scheduler for CRL refresh
  • Health Check API - System monitoring endpoints
  • WebSocket Support - Real-time event notifications

📦 Installation

Docker (Recommended)

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

# From GitHub Container Registry
docker pull ghcr.io/neyslim/ultimate-ca-manager:2.0.0

# Run
docker run -d -p 8443:8443 \
  -v ucm-data:/opt/ucm/data \
  --name ucm neyslim/ultimate-ca-manager:2.0.0

Debian/Ubuntu

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

Fedora/RHEL

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

⬆️ Upgrading from v1.8.x

Data is automatically migrated when upgrading. A backup is created in /opt/ucm/data/backups/.

  1. Stop the old service
  2. Install the new package
  3. Start the service - migration runs automatically
  4. Access the new UI at https://your-server:8443

🔐 Default Credentials

  • Username: admin
  • Password: Check /etc/ucm/ucm.env after install

⚠️ Change the password immediately after first login!


v2.0.0-beta1

Release Date: February 6, 2026

⚠️ Beta Release - This is a major release with significant changes. Please report any issues on GitHub.

🎨 Complete UI Redesign

UCM v2.0.0 features a completely redesigned user interface built with modern technologies:

  • React 18 with Vite for fast development and optimized builds
  • Radix UI for accessible, high-quality components
  • Tailwind CSS for consistent styling
  • Split-View Layout with sidebar, explorer panel, and detail views
  • Responsive Design that works on mobile, tablet, and desktop

✨ New Features

12 Theme Variants

  • 6 color themes: Gray, Blue Ocean, Purple Night, Green Forest, Orange Sunset, Cyber Pink
  • Light and Dark modes for each
  • "Follow System" option for automatic switching

User Groups

  • Create groups to organize users
  • Assign permissions to groups
  • Manage group membership

Certificate Templates

  • Predefined certificate configurations
  • Server, Client, Code Signing templates
  • Custom templates with key usage settings

Certificate Tools

  • SSL Checker - Check remote server certificates
  • CSR Decoder - Decode and analyze CSRs
  • Certificate Decoder - View certificate details
  • Key Matcher - Verify key/cert/CSR match
  • Format Converter - Convert between PEM, DER, PKCS12, PKCS7

Smart Import

  • Intelligent parser for certificates, keys, and CSRs
  • Auto-detect content type from pasted data
  • Batch import support

Command Palette (Ctrl+K)

  • Quick navigation to any page
  • Search certificates, CAs, users
  • Quick actions (create cert, create CA, etc.)

Trust Store

  • Manage trusted CA certificates
  • Import external CA chains
  • Verify trust relationships

Enhanced Dashboard

  • Real-time statistics
  • Certificate trend chart (7 days)
  • Status distribution pie chart
  • Recent activity feed with live updates
  • System health monitoring

Audit Logs

  • Complete action logging
  • Filter by action type, user, date range
  • Export to CSV
  • Integrity verification (hash chain)

ACME Management

  • Account list and details
  • Order history with status tracking
  • Challenge status monitoring
  • Certificate issuance history

📦 Installation

Debian/Ubuntu

wget https://github.com/NeySlim/ultimate-ca-manager/releases/download/v2.0.0-beta1/ucm_2.0.0.beta1_all.deb
sudo apt install -y python3-venv python3-pip
sudo dpkg -i ucm_2.0.0.beta1_all.deb

RHEL/Rocky/Fedora

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

Docker (Coming Soon)

docker run -d --name ucm -p 8443:8443 ghcr.io/neyslim/ultimate-ca-manager:2.0.0-beta1

⬆️ Upgrading from v1.8.x

Upgrades are automatic! When you install the new package:

  1. Existing data is backed up to /opt/ucm/data/backups/
  2. Database schema is migrated automatically
  3. Configuration is preserved
  4. Service restarts with new version

What Gets Migrated

  • ✅ All certificates and CAs
  • ✅ User accounts and settings
  • ✅ ACME accounts and orders
  • ✅ Audit logs
  • ✅ System configuration

🔧 Path Changes

v2.0.0 harmonizes installation paths across DEB and RPM:

Component v1.8.x v2.0.0
Application Various /opt/ucm/
Data /opt/ucm/backend/data/ /opt/ucm/data/
Config /etc/ucm/config.json /etc/ucm/ucm.env
Logs /var/log/ucm/ /var/log/ucm/

🐛 Known Issues

  • Docker image not yet published to GHCR (coming soon)
  • Some theme transitions may flicker on slow devices

📚 Documentation

🙏 Feedback

This is a beta release. We appreciate your feedback!


v1.8.2

Release Date: January 10, 2026
Status: ✅ STABLE - Production Ready
Download: GitHub Releases


🐛 Critical Bug Fix

Nginx Dependency Made Optional

Problem: Previous versions (v1.8.3 and v1.8.1) forced nginx installation due to a bug in the GitHub Actions workflow, even though UCM includes a built-in HTTPS server.

Root Cause: The build workflow generated its own package control file with nginx hardcoded in Depends:, ignoring the repository's correct configuration.

Solution:

  • Fixed .github/workflows/build-deb.yml to match repository configuration
  • Depends: python3, python3-pip, python3-venv, systemd (essentials only)
  • Recommends: python3-flask-caching, python3-redis (performance)
  • Suggests: nginx, apache2, certbot, python3-gunicorn (optional)

📦 Installation

Debian/Ubuntu

wget https://github.com/NeySlim/ultimate-ca-manager/releases/download/v1.8.2/ucm_1.8.2_all.deb
sudo dpkg -i ucm_1.8.2_all.deb
# ✅ No nginx installation required!

Docker

docker pull ghcr.io/neyslim/ultimate-ca-manager:1.8.2
# or
docker pull ghcr.io/neyslim/ultimate-ca-manager:latest

RPM (⚠️ UNTESTED)

wget https://github.com/NeySlim/ultimate-ca-manager/releases/download/v1.8.2/ucm-1.8.2-1.el9.noarch.rpm
sudo dnf install ucm-1.8.2-1.el9.noarch.rpm

🚀 Deployment Options

UCM is flexible - choose what works for you:

1. Standalone (No Reverse Proxy)

Perfect for testing, homelab, small deployments.

# UCM runs on built-in HTTPS server (port 8443)
sudo systemctl start ucm

Access: https://your-server:8443

2. With Reverse Proxy (Production)

Recommended for production environments.

# Install UCM
sudo dpkg -i ucm_1.8.2_all.deb

# Install nginx (optional)
sudo apt install nginx

# Configure nginx as reverse proxy
# See: Nginx Configuration Guide

Benefits:

  • Load balancing
  • SSL/TLS termination
  • Serve multiple applications
  • Caching and compression

3. Docker

Perfect for containers and orchestration.

docker run -d \
  --name ucm \
  -p 8443:8443 \
  -v ucm-data:/app/backend/data \
  ghcr.io/neyslim/ultimate-ca-manager:1.8.2

🔄 Migration from v1.8.3 / v1.8.1

Remove Old Version

sudo apt remove ucm
sudo apt autoremove  # Remove nginx if it was auto-installed

Install v1.8.2

wget https://github.com/NeySlim/ultimate-ca-manager/releases/download/v1.8.2/ucm_1.8.2_all.deb
sudo dpkg -i ucm_1.8.2_all.deb
sudo systemctl restart ucm

Data Migration: Not required - all data preserved!


📋 Features (Unchanged from v1.8.3-beta)

All features from v1.8.3-beta are preserved:

🔐 Complete PKI Infrastructure

  • Full CA management (Root, Intermediate, Sub-CA)
  • Certificate lifecycle (create, sign, revoke, renew, export)
  • CRL & CDP (Certificate Revocation Lists)
  • OCSP Responder (RFC 6960)

📡 Industry Protocols

  • ACME (RFC 8555) - Let's Encrypt compatible
  • SCEP (RFC 8894) - Device auto-enrollment
  • OCSP - Real-time certificate status
  • CRL/CDP - Revocation list distribution

🔒 Advanced Security

  • mTLS Authentication - Client certificate auth
  • WebAuthn/FIDO2 - Hardware security keys (YubiKey, etc.)
  • JWT Sessions - Secure token-based auth
  • Export Authentication - All exports require JWT tokens

🎨 Modern Interface

  • 8 Themes - Light & dark variants (Sentinel, Amber, Blossom, Nebula)
  • Visual Theme Previews - 2×4 grid with live previews
  • HTMX-Powered - No page reloads
  • Responsive Design - Desktop, tablet, mobile

🔌 REST API

  • Complete JWT-authenticated API
  • Certificate operations
  • CA management
  • OCSP/SCEP/ACME endpoints

📊 Changes from v1.8.1

Fixed

  • .github/workflows/build-deb.yml - Removed nginx from hard dependencies
  • Package description enhanced with complete feature list

Improved

  • Documentation clarity on deployment options
  • Package metadata with all protocols listed

No Breaking Changes

All v1.8.3-beta features preserved and working.


🧪 Verification

Test that nginx is NOT required:

# Download package
wget https://github.com/NeySlim/ultimate-ca-manager/releases/download/v1.8.2/ucm_1.8.2_all.deb

# Inspect dependencies
dpkg-deb -I ucm_1.8.2_all.deb | grep Depends:
# Should show: python3, pip, venv, systemd (NO nginx!)

# Install
sudo dpkg -i ucm_1.8.2_all.deb
# ✅ SUCCESS - No nginx dependency error!

📝 Documentation Updates

  • README.md - Updated to v1.8.2
  • UPGRADE.md - Updated upgrade instructions
  • DOCKER_QUICKSTART.md - Updated Docker examples
  • CHANGELOG.md - Added v1.8.2 and v1.8.3-beta entries

🔗 Links


💡 Support


Previous: v1.8.3-beta
Next: v1.9.0 (TBD)


v1.8.0-beta

Release Date: January 10, 2026
Release Type: Beta Feature Release
Previous Version: v1.7.0


🎯 Overview

Version 1.8.3-beta enhances certificate and CA export functionality, improves HTTPS certificate management display, and introduces visual theme preview cards. This beta release focuses on improving security, user experience, and cross-platform compatibility.


✨ What's New

Enhanced Certificate & CA Export

Fixed Authentication Issues:

  • ✅ Certificate exports now properly authenticated with JWT tokens
  • ✅ CA exports now include Bearer token in Authorization header
  • ✅ Eliminated 401 Unauthorized and 500 Internal Server errors

Improved Download Experience:

  • Files now download with descriptive names instead of numeric IDs
  • Filename extracted from Content-Disposition header
  • Download spinner with toast notifications
  • ✅ "Preparing download..." → "Download started: filename.pem" flow

Technical Details:

  • Added JWT bearer token injection to exportWithToken() functions
  • Created window.exportWithTokenCert() for certificate exports
  • Implemented filename parsing from response headers
  • Fixed HTMX redeclaration errors with proper scope management

HTTPS Certificate Type Detection

Accurate Certificate Classification:

  • ✅ Correctly identifies Self-Signed certificates (subject == issuer)
  • ✅ Distinguishes CA-Signed (Auto-generated) certificates
  • ✅ Shows UCM Managed for user-selected certificates

Before: All auto-generated certs showed as "Self-Signed" ❌
After: Proper detection based on issuer comparison ✅

API Endpoint: /api/ui/system/https-cert-info

Certificate Source Selection Synchronization

Fixed Race Condition:

  • Radio button selection now properly syncs with current certificate
  • Eliminated unreliable 800ms setTimeout approach
  • Implemented Promise-based synchronization

Technical Implementation:

// loadCertificateCandidates() now returns Promise
// loadHTTPSCertInfo() awaits candidates before selecting
await loadCertificateCandidates();
// Then fetch and select current cert

Visual Theme Previews

Replaced: Simple theme buttons
With: Interactive preview cards showing actual theme appearance

Features:

  • Miniature UI preview with theme colors
  • Shows backgrounds, buttons, cards, and text
  • Hover effects with color-matched borders and shadows
  • 2 rows × 4 columns layout (8 themes total)
  • Responsive with 200px minimum width per card

Grid Layout:

grid-template-columns: repeat(4, minmax(200px, 1fr));
min-width: 0; /* prevents grid blowout */

Sidebar Improvements

Renamed: "Settings" → "System Settings"

  • Clearer distinction between system and user settings
  • Consistent with sidebar organization from v1.7.0

🔧 Technical Improvements

Docker & Native Installation Compatibility

Dynamic Path Resolution:

  • Replaced hardcoded /opt/ucm paths with current_app.config[]
  • Uses HTTPS_CERT_PATH, HTTPS_KEY_PATH, CERT_DIR, PRIVATE_DIR
  • Paths dynamically calculated from BASE_DIR in settings.py

Result:

  • ✅ Native installation: /opt/ucm/backend/data/
  • ✅ Docker installation: /app/backend/data/
  • ✅ No code changes needed between environments

JavaScript Architecture

Export Functions:

  • window.exportWithToken(url) - CA exports with JWT
  • window.exportWithTokenCert(url) - Certificate exports with JWT
  • Proper scope management to prevent HTMX redeclaration errors

HTMX Integration:

if (typeof window.exportWithToken === 'undefined') {
    window.exportWithToken = function(url) { ... }
}

CSS Enhancements

Theme Preview Cards:

  • ~120 lines of inline styles per theme
  • Interactive hover transitions (0.2s ease)
  • Theme-specific color variables
  • Responsive grid layout

🐛 Bug Fixes

Certificate Export Issues

  • ❌ Before: 500 errors due to missing Certificate import
  • ✅ After: Added import in backend/api/cert.py

CA Export Authentication

  • ❌ Before: 401 Unauthorized errors
  • ✅ After: JWT token properly injected in requests

Download Filenames

  • ❌ Before: Files downloaded as cert_123.pem
  • ✅ After: Certificate_Name.pem from Content-Disposition

HTMX Function Redeclaration

  • ❌ Before: "Identifier 'exportWithToken' has already been declared"
  • ✅ After: Proper scope management with window and existence checks

HTTPS Certificate Display

  • ❌ Before: CA-signed certs showed as "Self-Signed"
  • ✅ After: Correct type based on subject/issuer comparison

Theme Preview Layout

  • ❌ Before: Simple buttons, themes wrapped on small screens
  • ✅ After: Visual cards with 2×4 grid and 200px minimum width

📝 Files Modified

Backend

  • backend/api/cert.py - Added Certificate import
  • backend/api/ui_routes.py - Enhanced exports, HTTPS detection, dynamic paths
  • backend/config/settings.py - No changes (already had dynamic paths)

Frontend

  • frontend/templates/my_account.html - Visual theme preview cards
  • frontend/templates/settings.html - Certificate synchronization fixes
  • frontend/templates/base.html - Sidebar "System Settings" rename

📊 Git Commits (v1.8.3-beta)

77d2f42 - fix: replace hardcoded /opt/ucm paths with dynamic config paths
6688944 - fix: prevent theme preview cards from being crushed on small screens
1835c24 - fix: force theme previews to display in 2 rows of 4
1f62191 - fix: remove duplicate theme preview buttons
93cf047 - feat: compact theme previews and rename sidebar Settings
94dd4ee - feat: add visual theme previews instead of simple buttons
da1dfbf - fix: simplify and globalize export functions
5cf670b - fix: HTTPS certificate display and export improvements
34d4eb2 - fix: certificate/CA export with proper authentication and filenames

🚀 Deployment

Native Installation (/opt/ucm)

# After installing the package
systemctl restart ucm

Docker Installation

# Pull latest beta image
docker pull neyslim/ultimate-ca-manager:1.8.3-beta

# Or update from source
cd /path/to/ucm-src
docker build -t neyslim/ultimate-ca-manager:1.8.3-beta .
docker restart ucm

Upgrade Notes

  • ✅ No database migrations required
  • ✅ No configuration changes needed
  • ✅ Backward compatible with existing data
  • ✅ Works with all 8 themes

🎨 Theme Compatibility

All changes fully compatible with UCM's 8 themes:

  • ✅ Sentinel Light/Dark
  • ✅ Amber Light/Dark
  • ✅ Blossom Light/Dark
  • ✅ Nebula Light/Dark

Theme preview cards showcase:

  • Background colors
  • Card backgrounds
  • Primary/secondary button styles
  • Text colors
  • Interactive hover effects

🔒 Security Improvements

JWT Authentication

  • All export endpoints now properly secured
  • Token validation on both certificate and CA exports
  • No more unauthenticated download attempts

Certificate Validation

  • Accurate certificate type detection
  • Proper subject/issuer comparison
  • Clear visibility of certificate sources

🐛 Known Issues

Beta Limitations

  • Theme preview cards require minimum 800px viewport width
  • Mobile responsive design for previews not optimized yet
  • Some theme hover effects may vary slightly by browser

Future Improvements

  • Mobile-optimized theme selector
  • Keyboard navigation for theme selection
  • Accessibility improvements (ARIA labels)

🔮 Planned for v1.8.3 Stable

  • Mobile theme selector optimization
  • Additional export format options (DER, PKCS12)
  • Bulk certificate export
  • Enhanced certificate search/filtering
  • Accessibility audit and improvements

📖 Documentation Updates

  • Created Release-Notes-v1.8.3-beta.md
  • Updated README.md version references
  • Added deployment notes
  • Documented dynamic path architecture

🙏 Acknowledgments

This release addresses real-world deployment challenges with Docker compatibility and improves the overall user experience with better visual feedback and accurate certificate information.


📦 Download


📞 Support


Previous Release: v1.7.0 Release Notes


v1.7.0

Release Date: January 8, 2026
Release Type: Feature Release
Previous Version: v1.6.2


🎯 Overview

Version 1.7.0 enhances the user interface with collapsible sidebar submenus, optimized navigation, and improved organization of user account settings. This release focuses on improving the user experience with smoother navigation and better space utilization.


✨ What's New

Collapsible Sidebar Submenus

The sidebar navigation now features expandable/collapsible submenus for better organization:

  • Certificate Authorities Section

    • List CAs
    • Create CA
    • Import CA
  • Certificates Section

    • List Certificates
    • Create Certificate
    • Import Certificate
  • SCEP Section

    • SCEP Configuration

Features:

  • Smooth chevron rotation animations
  • State persisted in browser localStorage
  • Auto-expand when navigating to child pages
  • ⚡ HTMX-aware: works seamlessly with dynamic content loading

Submenu Icons

All submenu items now have dedicated icons for better visual hierarchy:

  • Icon Size: 14×14px (smaller than main menu 20×20px)
  • Hover Effect: Opacity transitions from 0.7 to 1.0
  • Theme Integration: Works across all 8 color schemes

My Account Section at Bottom

User-specific settings are now grouped together at the bottom of the sidebar:

  • Email Notifications - Configure email alerts
  • mTLS Authentication - Manage client certificates
  • Security Keys - WebAuthn/FIDO2 configuration

Benefits:

  • Visual separation with border-top separator
  • Always accessible regardless of scroll position
  • Clear distinction between system and user settings

Optimized Sidebar Width

Before: 240-260px (varied by theme)
After: 220px (uniform across all themes)

Benefits:

  • 20-40px more space for main content
  • Consistent layout across all themes
  • Better space utilization on smaller screens

🔧 Technical Improvements

JavaScript Architecture

  • New Module: sidebar-toggle.js (165 lines)
    • Submenu state management
    • localStorage persistence
    • HTMX integration
    • Auto-expand logic

CSS Enhancements

  • ~150 lines added to components.css
  • Smooth transition animations (0.3s ease)
  • Flexbox-based sidebar layout
  • Theme-aware submenu styling

State Management

// localStorage keys for submenu persistence
'sidebar-ca-expanded'           // Certificate Authorities
'sidebar-certificates-expanded' // Certificates
'sidebar-scep-expanded'        // SCEP

🎨 Theme Compatibility

All changes fully compatible with UCM's 8 themes:

  • ✅ Sentinel Light/Dark
  • ✅ Amber Light/Dark
  • ✅ Blossom Light/Dark
  • ✅ Nebula Light/Dark

📊 Performance Impact

  • Bundle Size: +6.5KB (sidebar-toggle.js)
  • CSS Size: +150 lines in components.css
  • Performance: No noticeable impact, animations remain smooth
  • Compatibility: All modern browsers supported

🚫 Known Limitations

Sidebar Collapse Feature (Disabled)

During development, we explored a full sidebar collapse feature (icon-only mode with flyout menus). However, this was disabled in the final release due to:

  • Layout stability issues
  • Complexity in maintaining responsive behavior
  • Tooltip positioning challenges

Status: Code preserved in comments for potential future implementation


📝 Migration Notes

For Existing Users

No action required. The update is seamless:

  1. Submenus will be collapsed by default on first load
  2. User preferences auto-saved as you navigate
  3. All existing functionality preserved

For Developers

If you've customized the sidebar:

  1. Review changes in frontend/templates/base.html
  2. Check CSS in frontend/static/css/components.css
  3. Test submenu behavior with your customizations

🐛 Bug Fixes

  • Fixed submenu icon opacity transitions
  • Improved sidebar flexbox layout
  • Corrected theme-specific width inconsistencies

📖 Documentation Updates

  • Updated README.md to v1.7.0
  • Added comprehensive CHANGELOG entry
  • Created this release notes page

🔮 Future Considerations

Potential Future Features

  1. Sidebar Collapse - Revisit with improved architecture
  2. Mobile Responsive Sidebar - Hamburger menu for mobile devices
  3. Keyboard Navigation - Arrow key support for submenus
  4. Accessibility - Enhanced ARIA attributes
  5. Active Tooltips - Utilize existing data-tooltip attributes

🙏 Acknowledgments

This release represents continuous improvement in user experience design. Special thanks to all users who provided feedback on navigation and layout.


📦 Download

  • GitHub Release: v1.7.0
  • Docker Image: docker pull neyslim/ultimate-ca-manager:1.7.0
  • Source Code: Available on GitHub

📞 Support


Previous Release: v1.6.2 Release Notes


v1.6.2

Release Date: January 7, 2026
Release Type: Bugfix Release
Previous Version: v1.6.0


🎯 Overview

Version 1.6.2 is a critical bugfix release addressing JavaScript errors in the OPNsense import functionality and improving the import statistics display.


🐛 Critical Bugfixes

Fixed

OPNsense Import Page

Fixed critical JavaScript errors preventing configuration imports:

  • Added global showToast() function to base template for reliable toast notifications
  • Fixed "showToast is not defined" error in HTMX-loaded content
  • Removed authentication method toggle, now uses API Key only (simplified UX)
  • Improved error handling and user feedback during import process
Import Statistics Display

Fixed toast message showing "0 CA 0 Cert" after successful import:

  • Corrected response data parsing in import completion handler
  • Enhanced import result feedback with proper counts

🔧 Changed

  • Simplified OPNsense import authentication to API Key only (removed username/password option)
  • Improved toast notification system with consistent styling across all themes

📦 Download

  • GitHub Release: v1.6.2
  • Docker Image: docker pull neyslim/ultimate-ca-manager:1.6.2

Next Release: v1.7.0 Release Notes
Previous Release: v1.6.0 Release Notes


v1.6.0

Release Date: January 5, 2026
Status: Stable Release


🎉 Major Release: Custom CSS Migration & Enhanced UX

This release represents a significant architectural improvement, removing all Tailwind CSS dependencies and implementing a fully custom CSS system with theme variables.


🚀 What's New

🎨 Complete UI Overhaul

  • Removed Tailwind CSS - Eliminated all ~827 Tailwind class occurrences across the codebase
  • Custom CSS Variables - Full theme control with CSS custom properties
  • 8 Professional Themes - All themes now feature consistent styling and behavior
  • Custom Scrollbars - Theme-aware scrollbars for both light and dark modes
  • No External CSS Dependencies - Faster load times and complete UI control

🔒 Modal System Improvements

  • Body Scroll Lock - Page scrolling is now properly disabled when modals are open
  • Proper Z-Index Management - Modals now correctly appear above sidebar (z-index: 1000)
  • Global Modal Utilities - New modal-utils.js provides consistent modal behavior
  • HTMX Integration Fixed - Sidebar navigation links now properly trigger modals
  • Better Focus Management - Improved accessibility and keyboard navigation

📄 CRL Information Pages

  • Public CRL Info - Standalone page at /cdp/{refid}/info (no authentication required)
  • Integrated CRL View - In-app page at /crl/info/{refid} (requires authentication)
  • Complete CRL Details - Shows CRL number, issue/next update dates, revocation count
  • Direct Download Links - Quick access to CRL files in PEM and DER formats

🌐 CDP (Certificate Distribution Point) Support

  • Enhanced CDP Routes - Improved certificate distribution point functionality
  • OCSP Integration - Better integration between CRL and OCSP services
  • Public Access - CDP endpoints available without authentication for certificate validation

🐛 Bug Fixes

  • ✅ Fixed JavaScript variable conflicts (pkcs12ExportId, IconSystem, SessionManager)
  • ✅ Fixed HTMX modal triggers from sidebar navigation
  • ✅ Fixed theme flash on initial page load
  • ✅ Fixed scrollbar visibility issues in various themes
  • ✅ Resolved modal positioning appearing under sidebar
  • ✅ Fixed modal backdrop not covering entire viewport
  • ✅ Corrected theme inconsistencies across different pages

📦 Installation

Debian/Ubuntu

Download and install the DEB package:

wget https://github.com/NeySlim/ultimate-ca-manager/releases/download/v1.6.0/ucm_1.6.0_all.deb
sudo dpkg -i ucm_1.6.0_all.deb

RHEL/CentOS/Fedora

Download and install the RPM package:

wget https://github.com/NeySlim/ultimate-ca-manager/releases/download/v1.6.0/ucm-1.6.0-1.noarch.rpm
sudo rpm -ivh ucm-1.6.0-1.noarch.rpm

Manual Installation

git clone -b v1.6.0 https://github.com/NeySlim/ultimate-ca-manager.git
cd ultimate-ca-manager
sudo ./install.sh

🔄 Upgrading from Previous Versions

From 1.5.x or earlier

# Stop the UCM service
sudo systemctl stop ucm

# Backup your database (important!)
sudo cp /opt/ucm/data/ucm.db /opt/ucm/data/ucm.db.backup-$(date +%Y%m%d)

# Install new version
sudo dpkg -i ucm_1.6.0_all.deb  # Debian/Ubuntu
# OR
sudo rpm -Uvh ucm-1.6.0-1.noarch.rpm  # RHEL/CentOS/Fedora

# Service will restart automatically
sudo systemctl status ucm

Important Notes:

  • Your data, certificates, and CAs are preserved during upgrade
  • Configuration files are maintained
  • No database migration required for this version

📋 Technical Changes

Frontend Architecture

  • Migrated from Tailwind CSS to custom CSS system
  • Implemented CSS variable theming across all 8 themes
  • Added modal-utils.js for centralized modal management
  • Updated all templates to use semantic CSS classes and theme variables
  • Enhanced scrollbar styling for all modern browsers (Chrome, Firefox, Safari)

Files Modified (50+ files)

  • All templates in frontend/templates/ (ca, certs, crl, ocsp, config, settings)
  • frontend/static/css/components.css - Added scrollbar styles and modal utilities
  • All 8 theme files in frontend/static/css/themes/
  • frontend/static/js/modal-utils.js - New global modal management
  • backend/api/ui_routes.py - Updated modal triggers
  • backend/api/cdp_routes.py - New CRL info endpoints
  • backend/api/ocsp_routes.py - Enhanced OCSP integration

CSS Classes Migration

  • Removed: ~827 Tailwind CSS utility classes
  • Added: Semantic custom classes with theme variable support
  • Result: Smaller CSS footprint, faster page loads

New CSS Variables

/* Scrollbar theming */
--scrollbar-track
--scrollbar-thumb
--scrollbar-thumb-hover

/* Modal system */
--modal-backdrop-z
--modal-dialog-z

🎨 Theme System

All 8 themes have been enhanced with:

  • Consistent color schemes and contrast ratios
  • Custom styled scrollbars matching theme colors
  • Smooth CSS transitions
  • ♿ Optimized accessibility (WCAG AA compliant)
  • Full dark mode support

Available Themes:

  • Sentinel (Light & Dark) - Professional blue/grey palette
  • Amber (Light & Dark) - Warm amber tones
  • Blossom (Light & Dark) - Soft pink/purple palette
  • Nebula (Light & Dark) - Deep purple cosmic theme

📚 Documentation Updates

  • ✅ Updated installation guide for DEB and RPM packages
  • ✅ Added CRL/CDP documentation
  • ✅ Theme customization guide
  • ✅ API reference updates for new endpoints
  • ✅ Migration guide from older versions

🔐 Security Improvements

  • Enhanced input validation on CRL info endpoints
  • Improved access control for public vs. authenticated endpoints
  • Better error handling preventing information disclosure
  • Updated dependencies for security patches

🚀 Performance Improvements

  • Faster Page Loads - Removed ~200KB of Tailwind CSS
  • Reduced HTTP Requests - Consolidated CSS files
  • Improved Rendering - CSS variables enable hardware-accelerated theme switching
  • Better Caching - Static assets now have optimal cache headers

📊 Statistics

Metric Before After Change
CSS File Size ~220KB ~45KB ⬇️ 80% reduction
Tailwind Classes 827 0 ✅ Complete removal
Theme Variables 0 50+ ✅ Full theming support
Load Time ~1.2s ~0.6s ⚡ 50% faster

🐛 Known Issues

None at this time. Please report any issues on our GitHub Issues page.


🙏 Acknowledgments

Special thanks to all contributors and testers who helped identify issues and improve UCM!


📝 Checksums

Download the release and verify integrity:

DEB Package:

# MD5
md5sum ucm_1.6.0_all.deb

# SHA256
sha256sum ucm_1.6.0_all.deb

RPM Package:

# MD5
md5sum ucm-1.6.0-1.noarch.rpm

# SHA256
sha256sum ucm-1.6.0-1.noarch.rpm

Checksums are also available as separate files in the release assets.


🔗 Links


📅 What's Next?

Looking ahead to version 1.7.0:

  • Enhanced SCEP features
  • Certificate templates
  • Advanced reporting and analytics
  • Multi-language support improvements
  • API v2 with GraphQL support

Stay tuned and follow our GitHub repository for updates!


Full Changelog: v1.5.0...v1.6.0

Last Updated: January 5, 2026

Clone this wiki locally