ACMEEH v1.0.0
ACMEEH v1.0.0
Enterprise ACME (RFC 8555) server for internal PKI
Initial release of ACMEEH — a production-ready ACME server built for organizations that need automated certificate management on their internal network.
Highlights
- Full RFC 8555 implementation compatible with certbot, acme.sh, Caddy, Traefik, Lego, and all standards-compliant ACME clients
- 4 pluggable CA backends with circuit breaker resilience
- Docker-first deployment with multi-arch images (amd64/arm64)
- Comprehensive Admin REST API for server management
- Built-in revocation infrastructure (CRL, OCSP, ARI)
ACME Protocol
- RFC 8555 — Complete implementation: directory, nonce, account, order, authorization, challenge, certificate, and key-change endpoints
- JWS Authentication — Custom RFC 7515/7517/7638 implementation using the cryptography library
- Account Management — Registration, key rollover, deactivation, and Terms of Service agreement
- Order Lifecycle — Full state machine (pending → ready → processing → valid/invalid) with automatic cleanup
- External Account Binding (EAB) — Optional pre-registration requirement for controlled environments
- ACME Renewal Information (ARI) — Draft-ietf-acme-ari support for suggested renewal windows
CA Backends
| Backend | Description |
|---|---|
internal |
Sign with a root CA key stored as PEM files on disk |
external |
Delegate signing to a remote HTTP API (HashiCorp Vault, EJBCA, etc.) |
hsm |
Sign using a Hardware Security Module via PKCS#11 |
acme_proxy |
Proxy to an upstream ACME CA (Let's Encrypt, etc.) |
ext:<path> |
Load a custom backend class for full extensibility |
All backends include a circuit breaker that prevents cascading failures on repeated signing errors.
Challenge Validation
- HTTP-01 — HTTP request to port 80 at
/.well-known/acme-challenge/{token} - DNS-01 — DNS TXT record query at
_acme-challenge.{domain} - TLS-ALPN-01 — TLS connection on port 443 with ALPN protocol
acme-tls/1 - Configurable timeouts, retries, and background validation workers
- Custom challenge validators via plugin system
Security Controls
- Per-endpoint rate limiting
- Key size and algorithm policies
- Identifier allowlists
- CAA enforcement (RFC 8659)
- CSR validation profiles
- Per-account certificate quotas
Admin API
Token-authenticated REST API for:
- User management and audit logs
- EAB credential management
- Identifier allowlists and CSR profiles
- Certificate search and bulk revocation
- Maintenance mode
Revocation Infrastructure
- CRL — Built-in Certificate Revocation List generation and distribution
- OCSP — Online Certificate Status Protocol responder
- ARI — ACME Renewal Information for proactive renewal scheduling
- Each subsystem independently toggleable
Observability
- Prometheus Metrics —
/metricsendpoint exposing certificate counts, issuance rates, challenge stats, and CA backend health - Structured Logging — JSON and text log formats with configurable levels
- Audit Trail — File and syslog output with optional webhook export
- Health Endpoints —
/livez,/healthz,/readyzfor orchestrator integration
Hook System
10 lifecycle events with pluggable handlers:
- Account registration
- Order creation
- Challenge validation
- Certificate issuance, delivery, and revocation
- Certificate Transparency submission
Email Notifications
- SMTP-based alerts for certificate expiration
- Configurable warning days and retry with backoff
- Jinja2 templates for full customization
Background Workers
HA-safe daemon threads with PostgreSQL advisory locks:
- Challenge validation worker
- Certificate expiration checker
- Nonce/order/challenge cleanup
- Data retention enforcement
Docker
- Multi-stage build with
python:3.12-slim-bookworm - Multi-arch support:
linux/amd64andlinux/arm64 - Optional HSM (PKCS#11) and gevent variants
- Non-root execution with configurable UID/GID
tinias PID 1 for proper signal handling- Docker Compose stack with PostgreSQL 16
- Full environment variable parameterization
Configuration
- Single YAML configuration file with 27 settings sections
- Environment variable substitution (
${VAR}/${VAR:-default}) - JSON Schema validation on startup
--validate-onlyCLI flag for config verification
CLI
acmeeh -c config.yaml # Start server (gunicorn)
acmeeh -c config.yaml --dev # Flask development server
acmeeh -c config.yaml --validate-only # Validate config and exit
acmeeh -c config.yaml db status # Check database connectivity
acmeeh -c config.yaml db migrate # Run database migrations
acmeeh -c config.yaml ca test-sign # Test CA signing
acmeeh -c config.yaml crl rebuild # Force CRL rebuild
acmeeh -c config.yaml admin create-user # Create admin user
acmeeh -c config.yaml inspect order <id> # Inspect resources
CI/CD
- GitHub Actions workflows for testing, linting, type checking, and Docker image publishing
- Ruff linting with 16 rule categories tuned to the codebase
- Mypy type checking with per-module overrides
- pytest with 2600+ tests across unit and integration suites
- Sphinx documentation auto-deployed to GitHub Pages
- Multi-arch Docker images published to Docker Hub on release tags
Tech Stack
- Python 3.12+ / Flask 3.0+
- PostgreSQL 14+ via psycopg 3 and PyPGKit
- cryptography library for all X.509 and JWS operations
- ConfigKit for configuration management
- gunicorn for production serving (Linux/macOS)
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