Skip to content

ACME Server

SSL-CLM includes a built-in ACME server that exposes RFC 8555-compliant endpoints. This allows any standard ACME client (certbot, acme.sh, win-acme, Caddy, Traefik, etc.) to request certificates from your internal Certificate Authorities using the ACME protocol.

Navigation: Sidebar → Infrastructure → ACME Server

ACME Server


Organizations often need:

  • Developers to request certificates without accessing the SSL-CLM UI
  • CI/CD pipelines to auto-provision certificates
  • Web servers with built-in ACME support (Caddy, Traefik) to use internal CAs
  • A standard protocol interface to private PKI

The built-in ACME server bridges this gap — it exposes your internal CAs via the industry-standard ACME protocol.


The main view lists all configured ACME profiles:

ColumnDescription
NameProfile display name
Directory URLThe ACME directory endpoint URL
EnvironmentPRODUCTION or SANDBOX
Trust ModelPRIVATE_PKI or PUBLIC_CA
ValidationValidation mode: POLICY or CA_ENFORCED (derived from Trust Model)
StatusACTIVE or DISABLED
ActionsEdit, Disable, View URL, Delete

FieldDescriptionOptions
NameDisplay name for the profileFree text
Profile IDURL-safe identifier (used in directory URL)e.g., internal-pki
EnvironmentDeployment contextPRODUCTION, SANDBOX
Trust ModelType of PKI trustPRIVATE_PKI, PUBLIC_CA
CA IntegrationWhich configured CA backs this profileSelect from configured CAs
Validation ModeDerived automatically from Trust ModelPOLICY (PRIVATE_PKI), CA_ENFORCED (PUBLIC_CA)

Note: Validation Mode is set automatically from the Trust Model — you do not choose it directly. PRIVATE_PKI maps to POLICY (no challenge), PUBLIC_CA maps to CA_ENFORCED (the backing CA enforces validation).

Each ACME profile defines what certificates it will issue:

FieldDescriptionExample
Allowed Key TypesWhich key algorithms are acceptedRSA, ECDSA
Allowed Key SizesWhich key sizes are accepted2048, 3072, 4096
Allowed SAN TypesWhich SAN types are acceptedDNS, IP
Max Certificate Validity (days)Maximum validity for issued certs365
Auto-Renewal AllowedWhether ACME renewal is permittedYes / No

EAB is always required for every profile. It ties an ACME account to a profile you authorized, so anonymous clients cannot register.

FieldDescription
EAB KIDKey identifier for the external account
EAB HMAC KeyShared secret for account binding

Credentials are generated when the profile is created (and shown once). ACME clients must supply both the --eab-kid and --eab-hmac-key during account registration or the very first certonly run.


  1. Click + Create ACME Profile
  2. Fill in the profile configuration:
    • Name and Profile ID
    • Select environment (Production / Sandbox)
    • Select trust model (PRIVATE_PKI or PUBLIC_CA) — this also sets the validation mode automatically
    • Choose the backing Certificate Authority
    • Set policy constraints (key types, sizes, validity)
  3. Click Save
  4. Save the EAB credentials shown in the dialog — the HMAC secret is displayed only once. A ready-to-run certbot example is shown alongside them.

The system generates a Directory URL like:

https://ssl-clm.example.com/acme/internal-pki/directory

EnvironmentPurposeRecommended Use
PRODUCTIONLive certificates for production workloadsReal infrastructure
SANDBOXTesting ACME client configuration without affecting productionCI/CD testing, client onboarding, dry runs

Use a SANDBOX profile to test ACME client configurations before pointing clients at a PRODUCTION profile.


ModelDescriptionValidation ModeUse Case
PRIVATE_PKICertificates issued from an internal CA (e.g., Smallstep/step-ca), trusted only within your organizationPOLICY — no challenge; issuance controlled by EAB + policyInternal services, microservices, dev/test
PUBLIC_CACertificates issued through a public/managed CA connector (e.g., DigiCert, or Let’s Encrypt via the ACME gateway)CA_ENFORCED — the backing CA performs its own domain validationPublic-facing services

Important: For a PUBLIC_CA profile backed by Let’s Encrypt, the backing CA validates the domain over the public internet (DNS-01 via a configured DNS provider). The domain must be real and publicly resolvable — local/internal names like myapp.internal.corp cannot be validated by a public CA.


Validation Mode is derived from the Trust Model — you do not set it directly.

ModeSet When Trust Model IsHow It Works
POLICYPRIVATE_PKINo ACME challenge. Authorizations are auto-approved and the certificate is issued immediately. Access is gated by EAB + issuance policy. Best for internal PKI where requestors are already authenticated.
CA_ENFORCEDPUBLIC_CAThe backing CA performs domain validation (e.g., Let’s Encrypt DNS-01 via a configured DNS provider). Requires the domain to be publicly resolvable.

The ACME challenge type (DNS-01 vs HTTP-01) is a separate concept from Validation Mode. In POLICY mode no challenge is used at all. Wildcard certificates from a public CA always require DNS-01.


A single certonly command registers the account (using the EAB credentials) and requests the certificate. Use the exact Directory URL shown on your ACME profile — the profile ID in the path selects the profile.

Terminal window
certbot certonly \
--server "https://ssl-clm.example.com/acme/internal-pki/directory" \
--standalone \
-d myapp.internal.corp \
--agree-tos \
-m admin@example.com \
--eab-kid "YOUR_KID" \
--eab-hmac-key "YOUR_HMAC_KEY"

Notes:

  • --eab-kid and --eab-hmac-key come from the ACME profile (shown once at creation). They are required.
  • If your SSL-CLM endpoint uses a self-signed or internal TLS certificate, add --no-verify-ssl (or point certbot at your internal CA bundle). Do not use --no-verify-ssl against a production, publicly-trusted endpoint.
  • --standalone makes certbot serve the HTTP-01 challenge itself on port 80. It is only relevant for CA_ENFORCED (public CA) profiles that use HTTP-01. For POLICY (private PKI) profiles no challenge is performed, so the flag is harmless but unused.

Where the certificate and key land: certbot generates the private key locally and writes the results to /etc/letsencrypt/live/<domain>/ (privkey.pem, cert.pem, chain.pem, fullchain.pem). The private key never leaves the client — SSL-CLM only receives the CSR and returns the signed certificate.

Terminal window
# Register once with EAB, then issue
acme.sh --register-account \
--server "https://ssl-clm.example.com/acme/internal-pki/directory" \
--eab-kid "YOUR_KID" \
--eab-hmac-key "YOUR_HMAC_KEY"
acme.sh --issue \
--server "https://ssl-clm.example.com/acme/internal-pki/directory" \
-d myapp.internal.corp \
--standalone

For an internal/self-signed SSL-CLM endpoint, set export HTTPS_INSECURE=1 (acme.sh’s equivalent of skipping TLS verification) or configure your internal CA bundle.

wacs.exe --baseuri https://ssl-clm.example.com/acme/internal-pki/directory
myapp.internal.corp {
tls {
ca https://ssl-clm.example.com/acme/internal-pki/directory
ca_root /path/to/internal-ca-root.pem
}
reverse_proxy localhost:8080
}
certificatesResolvers:
internal:
acme:
caServer: https://ssl-clm.example.com/acme/internal-pki/directory
email: admin@example.com
storage: /etc/traefik/acme.json
eab:
kid: YOUR_KID
hmacEncoded: YOUR_HMAC_KEY

1. Client → ACME Server: POST /acme/{profile}/new-account (register)
2. Client → ACME Server: POST /acme/{profile}/new-order (request cert)
3. ACME Server → Client: Challenge (DNS-01, HTTP-01, or POLICY auto-approve)
4. Client completes challenge (if required)
5. Client → ACME Server: POST /acme/{profile}/finalize (submit CSR)
6. ACME Server → Backing CA: Issue certificate
7. ACME Server → Client: Certificate + chain

For POLICY validation mode, steps 3–4 are skipped — the certificate is issued immediately based on the requestor’s ACME account authorization.


External Account Binding provides authenticated ACME access:

  • Generate EAB credentials from the ACME profile detail view
  • Credentials consist of a kid (key ID) and hmacKey (shared secret)
  • Distribute credentials securely to authorized ACME clients
  • Credentials can be rotated periodically for security
  • Revoke compromised credentials to block unauthorized issuance

ActionEffect
DisableProfile stops accepting new ACME requests. Existing certs remain valid.
EnableProfile resumes accepting requests.
DeleteProfile is permanently removed. Directory URL stops responding.

ACME operations are tracked in:

  • Audit Trail — Account registrations, orders, and issuances are logged (category ACME_PROFILE)
  • Certificates — Every ACME-issued certificate is added to the certificate inventory, linked to a certificate identity, showing its issuing CA and the ACME profile in its metadata

Certificates obtained by an ACME client (certbot, acme.sh, etc.) appear in the inventory with the MONITORED tier, not MANAGED. This is intentional and matches industry practice:

  • The ACME client holds the private key and drives its own renewal (it re-requests the certificate from SSL-CLM on its own schedule).
  • SSL-CLM therefore observes and tracks these certificates (inventory, expiry alerts, ownership, audit) but does not drive their renewal or deployment — which is what MANAGED implies.

Certificates that SSL-CLM issues and controls end-to-end (where it holds the key and drives renewal + deployment) are the ones treated as MANAGED.