Skip to content

ACME Best Practices

Security

Always Require External Account Binding

Enable Require EAB on all production ACME servers. EAB ensures that only pre-authorized clients can register accounts, preventing unauthorized certificate issuance.

Without EAB, any client that can reach your ACME endpoint can potentially register an account. While domain bindings still control what certificates can be issued, EAB provides an essential first line of defence.

Use Minimal Domain Bindings

Apply the principle of least privilege to domain bindings:

  • Grant exact domain bindings whenever possible
  • Enable subdomain permissions only when needed
  • Enable wildcard permissions only when the system genuinely requires wildcard certificates

Avoid: A single account with wildcard permissions for all company domains.

Prefer: Dedicated accounts with specific bindings for each system.

Protect EAB Credentials

EAB credentials are effectively API keys. Handle them with the same care:

Do Don't
Transmit via encrypted channels Send via unencrypted email
Store in a secrets manager Store in source control
Delete after configuration Leave in plaintext files
Regenerate if potentially exposed Reuse credentials across systems

Secure Key Storage on Clients

ACME clients generate and store private keys locally. Ensure:

  • Private keys are stored with restrictive file permissions (e.g., 600 or 400 on Linux)
  • The service account running the ACME client has minimal privileges
  • Key storage directories are excluded from backups that may be less secure than the host

Monitor for Unauthorized Activity

Review the audit log regularly for unexpected activity:

  • Account registrations from unknown sources
  • Orders for domains you wouldn't expect
  • Failed authorization attempts (may indicate misconfiguration or probing)

Operational Best Practices

Use Short Validity Periods

Configure short default and maximum validity periods:

Environment Recommended Default Recommended Maximum
Production 90 days 365 days
Development 30 days 90 days
High-security 30 days 90 days

Short validity periods:

  • Reduce the window of exposure if a key is compromised
  • Force automation — manual certificate management is unsustainable
  • Align with industry best practices (CA/Browser Forum recommends max 398 days for public TLS)

Automate Renewal

Configure ACME clients to renew certificates automatically, well before expiry:

Client Renewal Configuration
Certbot Runs via systemd timer or cron; renews at 30 days before expiry by default
acme.sh Cron job; renews at 60 days before expiry by default
Caddy Automatic; renews at 1/3 of lifetime remaining
Traefik Automatic; renews at 30 days before expiry

Use Separate Servers for Environments

Create separate ACME server configurations for:

  • Production — Stricter policies, longer maximum validity, production intermediate
  • Staging/Development — Shorter validity, separate intermediate, more permissive for testing

This prevents test systems from accidentally obtaining production certificates and keeps audit logs clean.

Plan for PKI Rotation

When rotating intermediate certificates:

  1. Update the ACME server configuration to use the new intermediate
  2. Ensure clients trust both old and new intermediates during transition
  3. Allow time for all certificates to renew with the new chain
  4. Remove trust for the old intermediate only after all certificates have rotated

Client Configuration

Prefer Strong Cryptography

When configuring ACME clients, request strong cryptographic parameters:

Parameter Recommended Avoid
Key algorithm ECDSA P-384 RSA 2048, ECDSA P-256 (for new deployments)
RSA key size 4096 bits (if RSA required) 2048 bits
Digest SHA-384 or SHA-512 SHA-1

Most ACME clients default to reasonable algorithms, but verify your configuration.

Handle Renewal Failures

Configure alerting for renewal failures. Most ACME clients provide hooks for error handling:

Certbot:

certbot renew --deploy-hook /path/to/success.sh --post-hook /path/to/alert-on-failure.sh

acme.sh:

acme.sh --issue -d example.com --reloadcmd "systemctl reload nginx" \
  --notify-hook sendmail

Test Before Production

Before deploying ACME to production:

  1. Create a test ACME server configuration
  2. Test the full flow: account registration, certificate issuance, renewal
  3. Verify the certificate chain is trusted by your systems
  4. Test failure scenarios: expired credentials, unauthorized domains, network failures

Comparison: When to Use ACME vs Courier

Scenario Recommended Approach
Web server with native ACME support (Caddy, Traefik) ACME
Kubernetes with cert-manager ACME
Legacy application requiring scripts for certificate installation Courier
Network-restricted systems (no internet access) Courier via Bridge
Systems requiring platform-side key generation Courier
Environments with existing ACME automation ACME
Need for detailed lifecycle hooks (pre/post scripts) Courier

You can use both ACME and Couriers within the same organization for different systems.


Troubleshooting Common Issues

Certificate Not Trusted

Symptom: Certificate is issued but clients report "certificate not trusted".

Causes: - Client system does not trust the root CA - Intermediate certificate is not included in the chain - Certificate was issued by a different intermediate than expected

Resolution: - Install the root CA certificate in the client's trust store - Verify the ACME server is configured with the correct intermediate - Check the full chain returned by the ACME server

Account Registration Fails

Symptom: Client reports "unauthorized" or "account does not exist".

Causes: - EAB credentials are incorrect or already used - Server requires EAB but client did not provide it - Account was deactivated

Resolution: - Verify EAB credentials match exactly (case-sensitive) - Regenerate credentials if they may have been used or compromised - Check account status in the platform UI

Authorization Denied

Symptom: Order creation fails with "unauthorized identifier".

Causes: - Account does not have a domain binding for the requested domain - Subdomain requested but subdomain permission not granted - Wildcard requested but wildcard permission not granted

Resolution: - Review the account's domain bindings - Add missing bindings or enable required permissions

Order Stuck in Processing

Symptom: Order status remains "processing" indefinitely.

Causes: - Backend certificate signing job failed - Network connectivity issue between front and back control planes

Resolution: - Check the order's error field for details - Review platform health status - Contact support if the issue persists


Summary Checklist

  • [ ] EAB required on all production ACME servers
  • [ ] Domain bindings follow least privilege
  • [ ] EAB credentials transmitted and stored securely
  • [ ] Short validity periods configured
  • [ ] Automatic renewal configured on all clients
  • [ ] Renewal failure alerting in place
  • [ ] Separate ACME servers for different environments
  • [ ] Audit log reviewed periodically