Every active subordinate CA has a private ACME (RFC 8555) directory:
https://pki.ezghcloud.com/acme/<CA ID>/directoryACME clients register with an ACME binding: an External Account Binding key ID (the binding’s
eab_… slug) and HMAC key. A binding orders certificates with its owner’s access, so its owner
needs certificates.certificateAuthorities.issue on the CA for as long as it’s used. Each order
and finalization checks that again: if the owner loses the permission, leaves the organization, or
the binding is deleted, its clients stop getting certificates.
There are no challenges. EZGH can’t reach your private names to validate them, so authorizations are valid from the start: control comes from the binding’s key, its allowed names, and the CA’s name constraints. Keep the HMAC key as secret as a private key.
Create a binding
You need certificates.acmeBindings.create and certificates.certificateAuthorities.issue on the
CA. A binding has a profile (tlsServer, tlsClient or tlsServerClient), a longest validity (at
most the CA’s longest certificate), and optionally the names it may order: exact DNS names or a
leading *. label, within the CA’s name constraints.
ezgh private-ca acme-binding create corp-issuing --name cert-manager \
--allowed-name '*.svc.corp.example' --max-validity-days 30The directory URL, key ID and HMAC key are shown once. In the console, use Create ACME binding on the CA’s ACME tab; its last screen also has the cert-manager and certbot setups below.
Deleting a binding stops every ACME account registered with it.
cert-manager
apiVersion: v1
kind: Secret
metadata:
name: corp-issuing-eab
namespace: cert-manager
stringData:
secret: <HMAC key>
---
apiVersion: cert-manager.io/v1
kind: ClusterIssuer
metadata:
name: corp-issuing
spec:
acme:
server: https://pki.ezghcloud.com/acme/<CA ID>/directory
privateKeySecretRef:
name: corp-issuing-account
externalAccountBinding:
keyID: <key ID>
keySecretRef:
name: corp-issuing-eab
key: secretCertificates then name the issuer as usual (issuerRef: {kind: ClusterIssuer, name: corp-issuing}).
Pods that verify them need the root certificate in their trust bundle.
certbot
certbot certonly --server https://pki.ezghcloud.com/acme/<CA ID>/directory \
--eab-kid <key ID> --eab-hmac-key <HMAC key> \
--manual --preferred-challenges dns --manual-auth-hook true \
-d app.corp.example --agree-tos -m you@corp.exampleThe no-op --manual-auth-hook is never called, since there are no challenges; certbot renew
works the same way.
Limits
Each binding may send 20 ACME requests per second, with bursts of 100. Account key rollover
(keyChange) is supported; ACME Renewal Information isn’t.