github NeySlim/ultimate-ca-manager v2.218

one hour ago

What's Changed

Added

  • Local ACME accounts: the contact e-mail can now be edited from the account detail (the piece of #303 that had been accepted but not shipped in 2.217). Per RFC 8555 the contact belongs to the ACME client and its next account update may overwrite the value; the edit form says so (#303, reported by @gb-123-git)
  • Settings > HTTPS now shows which certificate is bound to the web UI (renewals applied automatically) with a button to stop following renewals; the Let's Encrypt orders list gains the same status filter and naming as the Local orders view (#303, reported by @gb-123-git)
  • One-click TSA signing certificate: Settings > TSA > Signing certificate now has a "Generate a signing certificate" action that issues an end-entity certificate purpose-built as an RFC 3161 timestamp signer: BasicConstraints CA:FALSE, KeyUsage digitalSignature only (critical), and a critical, exclusive timeStamping EKU. The generic issue path cannot produce this (it always emits the EKU non-critical and merges the base profile with extra_ekus), so before this an operator had to hand-craft the certificate outside UCM. The private key is stored encrypted at rest. The certificate is issued and committed first; when no usable dedicated signer is configured yet it is then selected as tsa_signer_cert_refid (a second write), and if that selection write fails the certificate stays issued but unselected with a log line. An already-healthy signer is never swapped without an explicit request. Issued through POST /api/v2/tsa/signer-certificate (needs both write:settings and write:certificates), defaulting to the configured TSA CA, RSA 3072, and a 397-day validity clamped to the issuing CA's own expiry. The certificate is an ordinary UCM certificate: in-place renewal keeps the critical exclusive EKU and expiry alerts apply, but the auto-renewal scheduler only covers it if manual is added to auto_renewal_sources (default scep, acme, est); the generate form says so. The TSA page also now shows whether the active signer's timeStamping EKU is critical/exclusive (eku_critical_exclusive), on both the candidate list and the status box (#312, contributed by @Hemsby)
  • Dashboard surfacing for a near-expiry TSA signer: the System Health widget now has a TSA badge (disabled / signing with the CA certificate / dedicated signer, turning amber within 30 days of the signer's expiry and grey when the signer is expired, revoked or undecryptable and /tsa is therefore returning 503), and the Next Expirations widget tags the configured dedicated signer with a "TSA signer" chip so its expiry reads as an infrastructure event rather than one certificate among many. Service badges now render a distinct warning state and show their status message on hover. A dedicated signer is an ordinary certificate, so the existing email expiry alerts already cover it; this adds the at-a-glance view (#312, contributed by @Hemsby)

Fixed

  • ACME account detail: challenge status badges show valid in green and pending in yellow again (the API capitalizes statuses, the badge mapping compared lowercase, so everything rendered red); the scheduled purge and the purge button now also remove the leftover pending sibling challenges of authorizations validated before 2.217 (#303, reported by @gb-123-git)
  • Dashboard: the Webhooks badge queried a column that does not exist, so it always showed "Not configured" no matter how many endpoints were configured; on PostgreSQL the failed query also aborted the transaction, dragging the badges probed after it (TSA included) into their fallback state. The query is fixed and every status probe now resets the session on failure so one broken probe cannot poison the next

📜 Recent release history (last 2 versions)

[2.217] - 2026-08-31

Fixed

  • ACME proxy: the dns-01 TXT values computed with the CLIENT account keys are now published next to the upstream CA's value (the proxy knows every client thumbprint), so the propagation pre-checks of lego, Traefik and Caddy find the value they expect and no longer need to be disabled; the extra records are cleaned up with the others (#306, #307)
  • ACME proxy: a client retrying new-order for the same identifiers now gets its still-pending order back (checked against the upstream CA) instead of opening a new upstream order on every attempt, mirroring upstream behavior and stopping order accumulation under retry-happy clients (#303, reported by @gb-123-git)
  • Email notifications skip recipients that are not valid mailbox addresses at send time (one log line names them) instead of handing them to SMTP and bouncing; nothing changes at input time, so "tag only" account contacts keep working (#303, reported by @gb-123-git)
  • Local ACME server: once an authorization is validated, the unused sibling challenges are deprovisioned and no longer listed (RFC 8555 section 7.1.6, matching Let's Encrypt), so clients like Caddy stop seeing leftover pending http-01/tls-alpn-01 challenges next to the validated one; authorizations validated before this change also stop listing their leftover siblings (#303, reported by @gb-123-git)
  • Certificate issue form: the "No template" choice is back in the template selector, so a selected template can be deselected to return to manual mode. The select component silently dropped every empty-value option (a library constraint workaround); those options are now rendered through an internal sentinel, which also restores the "No template" choice in SCEP profiles and the "None (base role only)" choice in user role assignment (#303, reported by @gb-123-git)
  • ACME proxy: several downstream accounts can now order the same domain. The upstream CA reuses one authorization across them (the proxy signs upstream with a single account), and the proxy resolved it to the first account's order, so every other account was refused with 403 "Authorization does not belong to this account". Shared authorizations now resolve to the requesting account's order, the dns-01 automation for a shared challenge fires once instead of once per account, and the cross-account protections are unchanged (#307, contributed by @Hemsby)
  • TSA: timestamp requests no longer fail with 503 "TSA certificate does not include the timeStamping EKU" when the signing CA is a constrained sub-CA whose certificate carries an EKU without timeStamping. It is accepted with a warning like a CA certificate without any EKU; a dedicated end-entity signer lacking the EKU is still refused, and tsa_require_dedicated_cert still enforces the strict mode (#309, contributed by @Hemsby)

Added

  • Guardrails for the admin Base URL: saving a base URL that does not resolve or answer is refused with an explicit error (resend with "force": true to apply anyway), the canonical redirect steps aside whenever the configured host stops resolving instead of redirecting the whole UI into a wall, and starting the service with UCM_DISABLE_CANONICAL_REDIRECT=1 disables the redirect entirely to recover a locked-out instance (#303, reported by @gb-123-git)
  • The certificate applied to the web UI (Settings > HTTPS) is now remembered: when that certificate is renewed (including by the auto-renewal scheduler), the HTTPS files are re-materialized and the service restarts by itself, so the UI never keeps serving the pre-renewal certificate. Regenerating a self-signed certificate clears the binding; on Docker a log line asks for a container restart instead (#303, reported by @gb-123-git)
  • Local ACME server: orders now have a dedicated view (ACME > Local orders) with status filter, per-order deletion and a purge action, and a scheduled task removes expired non-issued orders with their authorizations and challenges every 6 hours, so they stop accumulating forever; issued orders are kept as history (#303, reported by @gb-123-git)
  • Local ACME server: the signing digest for orders that select no certificate profile is now configurable (ACME > Local ACME > Certificate profiles, sha256/sha384/sha512, default unchanged at sha256); profiles that omit their own digest inherit it (#303, reported by @gb-123-git)
  • Optional what's new window after an update: enable "Show release notes after an update" in Settings > Updates (off by default) and every user gets a one-time popup with the installed version, the install date and the release notes the next time a new version is running. Dismissal is per user and follows the account across browsers (#308)
  • The listen address is now configurable: HOST in ucm.env (or the container environment) is honored by the HTTPS server and the HTTP protocol port, not only by the development server. HOST=:: listens on IPv6 and IPv4 at once (dual-stack); the default stays 0.0.0.0. IPv4 clients reaching a dual-stack listener are normalized from ::ffff:a.b.c.d to plain IPv4 before trusted-proxy, rate-limit and audit handling, so existing UCM_TRUSTED_PROXIES values keep matching
  • Dedicated TSA signing certificate — Settings > TSA now has a "Signing certificate" section to point the RFC 3161 timestamp signer at an already-issued end-entity certificate instead of the CA's own certificate. Only certificates whose private key UCM holds and can decrypt and that carry the timeStamping EKU are offered; protocol-enrolled (client-key) and AD CS-proxied certificates are excluded. The signer is resolved by refid at signing time so an in-place renewal is followed automatically, and it is re-checked on every request: an expired, revoked or undecryptable signer fails the request with 503 and an explicit log line and never falls back to the CA certificate. The token embeds the signer's issuer chain (leaf plus its issuing CA chain) when the client asks for certificates, and the ESSCertIDv2 / SigningCertificate signed attribute follows the selected signer. The tsa_require_dedicated_cert toggle is only operable once a usable dedicated signer is saved. With no signer configured (tsa_signer_cert_refid unset) the token is byte-for-byte what it was — existing deployments see no change. No schema change (new tsa_signer_cert_refid SystemConfig key). One-click issuance of a TSA signing certificate is a planned follow-up (#312, contributed by @Hemsby)

[2.216] - 2026-08-29

Fixed

  • Translation cleanup across the 8 non-English locales (about 1,100 strings): a February locale sync had left whole sections in English (template pinning, public endpoints, webhooks, remote syslog, expiry alerts, trust store, service restart, audit integrity, SSH CA messages), 15 strings garbled by a broken word substitution in six locales ("Trusted for issuing certificatees", "Password must be at theast 12 characters", "Dandhande backup", "resand the database"), and roughly a hundred half-translated Spanish strings ("Error to eliminar CA", "Waiting for seguridad clave"). Every affected string was retranslated from the English reference; placeholders and technical terms are unchanged
  • The "Create CA" quick action was labelled in French in the German UI (now "CA erstellen", contributed by @gladiac, #304); the same untranslated label is also fixed in Spanish, Italian, Japanese, Portuguese and Ukrainian
  • ACME proxy orders in the Let's Encrypt view no longer offer Verify / Finalize / Renew: those orders are driven by the external ACME client (it answers the challenges, finalizes with its own key and downloads the certificate), so finalizing from UCM could only fail, previously with a misleading "ACME outbound URL blocked: URL has no hostname". The API now answers 409 with an explanation and the UI shows a hint instead of the buttons (#306)
  • Migrating to PostgreSQL with a role that is not a superuser no longer fails with "Can't operate on closed transaction inside context manager" and 0 rows copied: the FK-check bypass (session_replication_role) is now attempted inside a savepoint, so a refused SET falls back to the topological insert order as intended instead of aborting the whole copy. The switch-without-migration bootstrap (which copies users to the new backend) had the same failure class and is fixed by the same change (#305)

Full history: CHANGELOG.md


Installation

Docker (Recommended)

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

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

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

Debian/Ubuntu

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

Fedora/RHEL

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

Silent/Automated Install

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

Default Credentials

  • Username: admin
  • Password: changeme123

Change the password immediately after first login!

Documentation

Don't miss a new ultimate-ca-manager release

NewReleases is sending notifications on new releases.