Releases: fabriziosalmi/certmate
v2.1.1
Bug Fixes
- ca_manager: resolve private CA certificate key mismatch (#79) — the backend now correctly reads the
ca_certkey from settings, allowing proper injection ofREQUESTS_CA_BUNDLEfor private CAs
Tests
- test_ui: fix Playwright browser auth flow — correct user creation/login order, proper session cookie injection, and authenticated API calls for security banner toggle
v2.1.0
Bug Fixes
Issue #76 — Unable to save settings (HTTP 500)
Root cause: The web UI GET endpoint masks api_bearer_token as '********'. When saving, this masked value overwrites the real token. save_settings() then validates the 8-char masked string against a 32-char minimum, causing HTTP 500.
Fix (defense-in-depth):
routes.py: Strip masked/emptyapi_bearer_tokenbefore mergesettings.py: Safety net — skip validation for masked/empty tokens
Tests
- 4 new unit tests in
tests/test_issue76_masked_token.py
Closes #76
v2.0.4 - Fix DNS provider plugins in Docker image
What's Changed
Bug Fixes
- Fix DNS provider plugins missing in Docker image (#75) — The CI/CD pipeline was building Docker images with
requirements-minimal.txt(Cloudflare-only). All DNS provider plugins (Route53, DigitalOcean, Google Cloud, Azure, Hetzner, Porkbun, GoDaddy, and 10 more) are now included. - Runtime plugin availability check — CertMate now verifies the certbot plugin is installed before attempting certificate creation, providing clear error messages with install instructions instead of cryptic certbot tracebacks.
- Remove broken
certbot-dns-namecheap— The only version on PyPI (v1.0.0, alpha) targets Python 2.7–3.8 and is incompatible with certbot 2.x / Python 3.12. Namecheap users should useacme-dnsas an alternative. - Fix 8 non-existent version pins in
requirements-extended.txt— Several third-party plugin versions (e.g.,certbot-dns-powerdns==2.11.0) don't exist on PyPI and have been corrected to actual latest versions.
Verified Plugins in Docker Image
All 17 DNS plugins are now confirmed working inside the Docker container:
acme-dns, dns-arvancloud, dns-cloudflare, dns-digitalocean, dns-dnsmadeeasy, dns-gandi, dns-godaddy, dns-google, dns-hetzner, dns-linode, dns-nsone, dns-ovh, dns-porkbun, dns-powerdns, dns-rfc2136, dns-route53, dns-vultr
Upgrade
docker pull fabriziosalmi/certmate:latestFull Changelog: v2.0.3...v2.0.4
v2.0.3 — Fix Route53 propagation flag & Private CA SSL verification
What's Changed
Bug Fix — AWS Route53: --dns-route53-propagation-seconds unrecognised (#75)
certbot-dns-route53 >= 1.22 removed the --dns-route53-propagation-seconds CLI flag. The plugin now polls Route53 internally until the TXT record propagates and no longer accepts the argument, causing every Route53 certificate request to fail immediately with an "unrecognised arguments" error.
Fix: Added a supports_propagation_seconds_flag property to the DNSProviderStrategy base class (defaults to True). Route53Strategy overrides it to False. The propagation-seconds argument is now only appended to the certbot command when the active strategy explicitly declares support for it.
Bug Fix — Private CA ACME endpoint "Connection failed" with self-signed certificates (#74)
The "Test Connection" button always used Python's system CA bundle (verify=True) to validate the ACME server's TLS certificate. Private CAs with self-signed or internal-root certificates are not in the system bundle, so every connection test reported "ACME endpoint is not accessible" even when the endpoint was fully reachable.
Fix: When a CA certificate is provided in the Private CA configuration, it is written to a temporary PEM file and passed as verify=<path> to requests.get(). The temp file is always removed in a finally block. SSL error messages now include actionable hints — whether to supply a CA certificate or verify the correct root/intermediate was uploaded.
Bug Fix — Residual Route53 / san_domains failures after v2.0.2 (#56)
The san_domains keyword-argument error and the Cloudflare-hardcoded DNS provider fallback were resolved in v2.0.1 and v2.0.2 respectively. The remaining failure mode reported by users (--dns-route53-propagation-seconds unrecognised) is fully resolved by the Issue #75 fix above.
Test Suite
161 passed, 9 skipped, 0 failed (9 skipped require live DNS/CA credentials).
New unit tests added in tests/test_san_domains.py:
TestRoute53PropagationFlag(4 tests) — verifiesRoute53Strategy.supports_propagation_seconds_flagisFalse, all other strategies areTrue, and the flag is absent from the constructed certbot command for Route53.TestAcmeConnectionSSLHandling(2 tests) — verifies the temp-file CA bundle logic and the no-cert system-bundle fallback.
Upgrade
# Docker Hub (recommended)
docker pull fabriziosalmi/certmate:v2.0.3
docker compose down && docker compose up -d
# Build from source
git pull origin main
docker compose build --no-cache && docker compose up -dv2.0.1
Bug Fixes
- Logout button not visible (#73): Fixed auth check in navigation bar — the JavaScript was reading
d.usernamebut the/api/auth/meendpoint returns{user: {username: ...}}. The button now correctly appears for authenticated users. - Private CA rejected for internal networks (#72): Removed SSRF IP validation that incorrectly blocked private CA deployments (e.g., step-ca on
step-ca.internal.local). Private CAs legitimately resolve to internal network addresses.
Security Hardening
- Added
allow_redirects=Falseto the private CA connectivity test to prevent redirect-based SSRF.
Full Changelog: v2.0.0...v2.0.1
CertMate v2.0.0 — Complete UI Overhaul & Automation Platform
CertMate v2.0.0 — Complete UI Overhaul & Automation Platform
Highlights
- RBAC & Scoped API Keys — Role-based access control (viewer/operator/admin) with fine-grained API key management
- Built-in Notifications — Email, Slack, webhook (HMAC-SHA256 signed), weekly digest — no external tools needed
- Deploy Hooks — Post-issuance shell commands with env vars, global + per-domain, dry-run testing
- Modern Dashboard — SSE real-time updates, activity timeline, certificate health cards
- Keyboard Shortcuts — Cmd+K palette, global hotkeys, vim-style navigation
- Setup Wizard — Guided first-run configuration for new installations
- Dark Mode — Full dark theme with system preference detection
- 22 DNS Providers — Added ArvanCloud, Infomaniak, ACME-DNS
Post-release fixes (included in this tag)
- Fix
fa-sparkles→fa-star(invalid FontAwesome icon in help page) - Update stale version strings across docs, settings migration, webhook User-Agent
- Fix async/await in client-certs.js → ES5
.then()/.catch()for convention compliance - Fix
CertMate.confirmcallback→Promise pattern in deploy hooks settings - Add filename validation before Path construction in API backup endpoints (defense-in-depth)
- Fix EventBus
_listenersthread safety — snapshot under lock before iteration
Upgrade
```bash
docker pull ghcr.io/fabriziosalmi/certmate:v2.0.0
```
Full Changelog: v1.10.4...v2.0.0
v1.12.0 — Certificate Auto-Deploy Hooks
Certificate Auto-Deploy Hooks
Run shell commands automatically after certificate issuance or renewal — complete the automation loop from request to deployment.
How it works
Configure deploy hooks in Settings > Deploy tab. After a certificate is created or renewed, CertMate executes your shell commands with cert paths passed as environment variables:
| Variable | Description |
|---|---|
CERTMATE_DOMAIN |
Domain name (e.g., example.com) |
CERTMATE_CERT_PATH |
Path to cert.pem |
CERTMATE_KEY_PATH |
Path to privkey.pem |
CERTMATE_FULLCHAIN_PATH |
Path to fullchain.pem |
CERTMATE_EVENT |
created or renewed |
Features
- Global hooks — run for all domains (e.g.,
systemctl reload nginx) - Domain-specific hooks — run only for matching domains
- Event filtering — trigger on created, renewed, or both
- Configurable timeout — 1-300 seconds per hook
- Dry-run testing — test hooks from the UI without real certs
- Execution history — JSONL log with full audit trail
- Real-time feedback — SSE events for hook start/completion
- Security — admin-only access, commands run as CertMate process user
API Endpoints
| Method | Endpoint | Description |
|---|---|---|
GET |
/api/deploy/config |
Get deploy hooks config |
POST |
/api/deploy/config |
Save deploy hooks config |
POST |
/api/deploy/test/<hook_id> |
Dry-run test a hook |
GET |
/api/deploy/history |
Execution history |
Example
# Global hook: reload Nginx after any cert change
systemctl reload nginx
# Domain hook: sync to remote server
rsync -avz $CERTMATE_CERT_PATH $CERTMATE_KEY_PATH user@server:/etc/ssl/
ssh user@server systemctl reload nginx28 new unit tests — 146 total tests passing.
Full Changelog: v1.11.1...v1.12.0
v1.11.1 — Keyboard Shortcuts
Keyboard Shortcuts for Power Users
New global keyboard shortcuts module for fast navigation and actions:
| Shortcut | Action |
|---|---|
? |
Show/hide keyboard shortcuts overlay |
/ |
Focus certificate search (or Cmd+K on other pages) |
n |
Focus new certificate domain input |
r |
Refresh certificate list |
t |
Toggle dark mode |
g h |
Go to Certificates |
g c |
Go to Client Certificates |
g s |
Go to Settings |
g a |
Go to Activity |
g d |
Go to API Docs |
Esc |
Close panel / overlay |
UI Hints
- Keyboard icon button in navbar (opens shortcut help)
/badge inside certificate search input- All shortcuts suppressed when typing in input fields
Full Changelog: v1.11.0...v1.11.1
v1.11.0 — Scoped API Key Management
What's New
Scoped API Keys
Create and manage multiple API keys, each scoped to a role from the RBAC hierarchy (viewer/operator/admin). Replaces the single shared token model for teams and CI/CD pipelines.
Key features:
- Create/List/Revoke lifecycle via API and UI
- Role scoping — viewer keys can only read, operator keys can create/renew certs, admin keys have full access
- Token format —
cm_prefix + 40 hex chars, stored as SHA-256 hash (plaintext shown once at creation) - Optional expiration — set an expiry date per key
- Usage tracking —
last_used_atupdated on each authentication - Soft revocation — revoked keys retained for audit trail
API endpoints:
GET /api/keys— list all keys (admin only)POST /api/keys— create a new scoped key (admin only)DELETE /api/keys/<id>— revoke a key (admin only)
UI: New "API Keys" tab in Settings with create form, one-time token display with copy button, and keys table with role badges and revoke action.
Backward compatible: The legacy api_bearer_token in the General tab continues to work with full admin access. No migration needed.
Tests
- 25 unit tests covering key CRUD, auth flow, revocation, expiration, and edge cases
- Bandit clean
Full Changelog: v1.10.7...v1.11.0
v1.10.7 — Weekly Digest & Bug Fix
What's New
Weekly Digest Email
- Scheduled summary: Automatic email every Sunday at midnight with certificate stats, client cert overview, and weekly activity (created/renewed/failed).
- On-demand send:
POST /api/digest/send(admin) or "Send now" button in Notification Settings. - Preview endpoint:
GET /api/digest/previewreturns digest data as JSON. - Toggle:
digest_enabledflag in notification config — enabled by default when SMTP is configured. - HTML + plain text: Formatted email with color-coded stats and expiring domain list.
Bug Fix
- Fix #71: Settings tab content (Users & Backup) was leaking across all tabs due to malformed HTML
<div>tags missing closing>. Alpine.jsx-showdirectives were not parsed, causing content to display unconditionally.
Details
- New
WeeklyDigestmodule (modules/core/digest.py) - APScheduler cron job:
day_of_week='sun', hour=0, minute=0 - 10 unit tests for digest (stats, formatting, skip conditions, SMTP send)
- Bandit clean, all tests passing
Full Changelog: v1.10.6...v1.10.7