ACME.Certificate reference
Certificate
Section titled “Certificate”Source:
src/ACME/Certificate.ts
A TLS certificate issued over ACME at deploy time, with renewal.
Reconcile places an order, proves control of every name over DNS-01
through the solver, finalizes with a fresh key’s CSR and stores the
chain and redacted private key in state. Protect the state store as
secret material. diff reports an update when the
names change or when renewBefore of validity remains, so a scheduled
alchemy deploy keeps certificates fresh.
Certificate: Wildcard certificate
Section titled “Certificate: Wildcard certificate”const account = yield* ACME.Account("Issuer", { ca: ACME.LetsEncrypt, termsOfServiceAgreed: true,});const zone = yield* Zone;const wildcard = yield* ACME.Certificate("Wildcard", { account, identifiers: ["*.example.com", "example.com"], solver: Cloudflare.DNS.AcmeSolver(zone),});Certificate: Using the certificate
Section titled “Certificate: Using the certificate”The chain and key are Outputs — pass them to whatever terminates TLS.
const www = yield* Fly.Certificate("Www", { app: Site, hostname: "www.example.com", kind: "custom", fullchain: wildcard.chain, privateKey: wildcard.privateKey,});Certificate: Renewal
Section titled “Certificate: Renewal”const api = yield* ACME.Certificate("Api", { account, identifiers: ["api.example.com"], solver: Cloudflare.DNS.AcmeSolver(zone), renewBefore: "45 days", revokeOnDelete: true,});IssueCertificate
Section titled “IssueCertificate”Source:
src/ACME/IssueCertificate.ts
Issue (and revoke) certificates at runtime as an Account — for
services that terminate TLS themselves and need certificates on demand,
like a relay minting *.<tenant>.example.com when a tenant first
connects.
Init transports the account’s directory URL, account URL and redacted private key through resource Outputs. Protect the runtime and state store as secret material. The caller chooses where to store the issued PEMs.
IssueCertificate: Issue on demand
Section titled “IssueCertificate: Issue on demand”Publish the DNS-01 record through any runtime DNS write client wrapped
as a solver (Cloudflare.DNS.acmeDnsSolver(dns)).
export default class Relay extends Fly.Service<Relay>()( "Relay", { app: RelayApp, main: import.meta.url }, Effect.gen(function* () { const acme = yield* ACME.IssueCertificate(ZeroSsl); const dns = yield* Cloudflare.DNS.WriteDns(Zone); const certs = yield* Fly.WriteCertificates(RelayApp); return { fetch: Effect.gen(function* () { const issued = yield* acme.issue({ identifiers: ["*.tenant.example.com"], solver: Cloudflare.DNS.acmeDnsSolver(dns), }); yield* certs.upload({ hostname: "*.tenant.example.com", fullchain: issued.chain, privateKey: issued.privateKey, }); return HttpServerResponse.text("ok"); }), }; }).pipe( Effect.provide(ACME.IssueCertificateHttp), Effect.provide(Cloudflare.DNS.WriteDnsHttp), Effect.provide(Fly.WriteCertificatesHttp), ),) {}IssueCertificate: Rate limits
Section titled “IssueCertificate: Rate limits”The SDK retry policy applies to individual requests. Apply
Acme.Retry.none from @distilled.cloud/acme to surface failures
immediately; AcmeRateLimited.retryAfter carries the CA’s retry hint.
IssueCertificate: Which CA from a Cloudflare Worker
Section titled “IssueCertificate: Which CA from a Cloudflare Worker”CA reachability depends on the host’s egress. Let’s Encrypt has returned TLS failures from deployed Cloudflare Workers in live testing; the deployed-Worker example uses ZeroSSL instead. Verify the selected CA from the runtime where issuance will run.
IssueCertificateHttp
Section titled “IssueCertificateHttp”Source:
src/ACME/IssueCertificateHttp.tsKind: Layer · Provides:ACME.IssueCertificate
Implementation of IssueCertificate: the account’s directory
URL, account URL and private key are bound into the host at deploy time
and read back at runtime; every call signs with them over HTTPS.
Provide it on the Worker / Service / Action Effect.
IssueCertificateHttp: Provide the layer
Section titled “IssueCertificateHttp: Provide the layer”Effect.gen(function* () { const acme = yield* ACME.IssueCertificate(LetsEncrypt); // ...}).pipe(Effect.provide(ACME.IssueCertificateHttp))