ACMEEH v2.0.0
Enterprise ACME (RFC 8555) server for internal PKI
Major release focused on connection pool resilience, operational hardening, and admin API enhancements. Includes breaking changes: OCSP responder removal and internal CA key_provider deprecation.
Breaking Changes
- OCSP responder removed — The built-in OCSP responder (
ocsp:config section,/ocspendpoint,OcspService) has been removed entirely. Use CRL and ARI for revocation status instead. Remove anyocsp:section from your configuration file. - Internal CA
key_providerremoved — Theca.internal.key_providersetting (file/pkcs11/encrypted_file) has been removed. Internal CA now supports file-based keys only. For HSM signing, use the dedicatedhsmbackend. Removekey_provider: filefrom your config if present. - Database pool defaults changed —
min_connections: 2 → 5,max_connections: 10 → 50,connection_timeout: 30s → 10s. Review yourdatabase:section if you had tuned these values. - Example configs removed —
examples/ocsp-crl-ari.yamlreplaced byexamples/crl-ari.yaml;examples/pkcs11-hsm.yamlremoved (useexamples/hsm-backend.yaml).
Connection Pool Resilience
- Pool pressure guard — New four-tier load shedding in
before_requesthook rejects non-health requests when the connection pool is nearly exhausted, with configurable thresholds based on pool size. Includes periodic recovery probes to break deadlock scenarios. - Batch nonce pre-generation — Nonces are now bulk-inserted in batches of 100 and served from an in-memory buffer, reducing per-response pool checkouts by ~100x.
- Pool-aware rate limiter — Rate limiting skips DB access when the pool is under pressure (fail-open), preventing cascading failures.
- Pool health monitoring — New
log_pool_stats(),get_pool_health(), andis_pool_healthy()utilities for runtime diagnostics. - Pool timeout detection — Pool timeout exceptions now return 503 with
Retry-Afterheader instead of 500. - CRL stale-serve under pressure — CRL manager serves cached CRL instead of hitting DB when pool is stressed.
Worker Lifecycle
- Post-fork worker startup — Background workers (challenge, cleanup, expiration) now start after gunicorn fork via
post_forkhook, fixing thread survival acrossfork(). - Advisory lock leader election — Cleanup and expiration workers now use PostgreSQL advisory locks via a new
advisory_lock()context manager that guarantees lock and unlock happen on the same connection. - Batched cleanup deletes — Retention cleanup now deletes in 1000-row batches to avoid long-held row locks.
- Two-phase expiration notifications — Expiring certificates are collected under lock (fast), then notifications are sent after lock release (slow network I/O).
- Pool-aware worker yields — Workers check pool health before acquiring locks and defer when under pressure.
Admin API Enhancements
- Input validation hardening — Comprehensive validation for all admin endpoints: string length limits, strict boolean type checking, username character validation, email format enforcement, pagination bounds, and ISO datetime parsing.
- EAB-to-account linkage — New endpoints to associate EAB credentials with allowed identifiers and CSR profiles, with automatic sync to ACME accounts on registration.
- New routes — GET/PUT/DELETE for EAB ↔ identifier and EAB ↔ CSR profile associations; POST/DELETE for account ↔ identifier and account ↔ CSR profile bindings.
- Audit log access — Auditor role can now view audit logs (previously admin-only).
Notification System
- 8 new notification types —
ORDER_REJECTED,CHALLENGE_FAILED,CSR_VALIDATION_FAILED,ORDER_STALE_RECOVERED,ACCOUNT_DEACTIVATED,KEY_ROLLOVER_SUCCEEDED,ORDER_QUOTA_EXCEEDED,AUTHORIZATION_DEACTIVATED. - Email templates — Jinja2 HTML body and subject templates for all new notification types.
- CC/BCC support — SMTP settings now accept
ccandbccrecipient lists. - Disabled notification types — New
notifications.disabled_typesconfig to suppress specific event types. - Three-phase notification delivery — Create → send (without holding DB connection) → update status, preventing pool exhaustion during slow SMTP operations.
Security Hardening
- JWS field validation — JWS payloads now reject unexpected top-level fields per RFC 8555 §6.2.
- Server header masking — New
ServerHeaderMiddlewarereplaces theServerresponse header to hide implementation details. - Health endpoint hardening — Removed version and internal metrics from health probes to limit reconnaissance surface.
- CSR profile enforcement — New
security.require_csr_profileoption to reject certificate finalization when no CSR profile is assigned.
Structured Logging
- Added structured logging across all API route handlers, repositories, challenge validators, and notification renderer.
- CAS guard failures in repositories now emit debug-level logs for operational visibility.
- Challenge validation failures emit warning-level logs.
Configuration
- New settings —
security.require_csr_profile,ca.deferred_signing_timeout,notifications.disabled_types,smtp.cc,smtp.bcc,database.max_idle_seconds. - Config validation — Warnings for risky pool configurations,
gthreadworker class tuning, and EAB-without-admin-API misconfigurations.
ACME Proxy
- Idempotent startup —
startup_check()is now safe to call multiple times. - Revocation enum fix — Revocation reason now correctly maps to ACMEOW's
RevocationReasonenum. - SSL warning suppression —
verify_ssl: falsesilences urllib3InsecureRequestWarning(when urllib3 is available).
Docker
- ACME proxy build arg — New
INSTALL_ACME_PROXYDocker build argument to optionally include acmeow in the image. - Expanded environment variables — Full parameterization for ACME proxy, external CA, HSM, CRL, ARI, and audit subsystems.
Tests
- 2943 tests (up from 2600+ in v1.0.0)
- New test suites for admin input validation, repository edge cases, notification types, DB init coverage, and remaining coverage gaps.
- Removed OCSP test suite (275 lines).
Migration Guide
- Remove any
ocsp:section from your config file. - Remove
key_provider: filefromca.internalif present (file-based is now the only option; usehsmbackend for HSM signing). - Review
database:pool settings — defaults changed to 5/50/10s. - Replace
examples/ocsp-crl-ari.yamlreferences withexamples/crl-ari.yaml. - Replace
examples/pkcs11-hsm.yamlreferences withexamples/hsm-backend.yaml.
Links
- Documentation: https://miichoow.github.io/ACMEEH/
- PyPI: https://pypi.org/project/acmeeh/
- Docker Hub: https://hub.docker.com/r/miichoow/acmeeh
- GitHub: https://github.com/miichoow/ACMEEH
License
Apache License 2.0