Challenge Handlers¶
Handlers for completing ACME challenges. The library supports three challenge types: DNS-01, HTTP-01, and TLS-ALPN-01.
ChallengeHandler (Base)¶
- class acmeow.ChallengeHandler[source]¶
Bases:
ABCAbstract base class for ACME challenge handlers.
Challenge handlers are responsible for deploying and cleaning up challenge responses. Implementations must handle both setup and cleanup to ensure proper resource management.
Example
>>> class MyDnsHandler(ChallengeHandler): ... def setup(self, domain, token, key_authorization): ... # Create DNS TXT record ... pass ... def cleanup(self, domain, token): ... # Remove DNS TXT record ... pass
- abstractmethod setup(domain, token, key_authorization)[source]¶
Deploy the challenge response.
This method is called before notifying the ACME server that the challenge is ready for validation. It should set up whatever resource is needed for the challenge type (DNS record, HTTP file, etc.).
- Parameters:
- Raises:
Exception – If setup fails and the challenge cannot proceed.
- Return type:
- abstractmethod cleanup(domain, token)[source]¶
Remove the challenge response.
This method is called after challenge validation completes (whether successful or not) to clean up deployed resources.
- Parameters:
- Return type:
Note
This method should not raise exceptions even if cleanup fails, as it’s called during error handling paths.
DNS-01 Handlers¶
CallbackDnsHandler¶
- class acmeow.CallbackDnsHandler[source]¶
Bases:
ChallengeHandlerDNS-01 handler using user-provided callbacks.
This handler delegates DNS record management to user-provided callback functions, allowing integration with any DNS provider.
- Parameters:
create_record (
Callable[[str,str,str],None]) – Callback to create a DNS TXT record. Signature: (domain: str, record_name: str, record_value: str) -> None - domain: The domain being validated (e.g., “example.com”) - record_name: The full record name (e.g., “_acme-challenge.example.com”) - record_value: The TXT record value (base64url SHA-256 hash)delete_record (
Callable[[str,str],None]) – Callback to delete a DNS TXT record. Signature: (domain: str, record_name: str) -> Nonepropagation_delay (
int) – Seconds to wait after creating record. Default 60.
Example
>>> def create_txt(domain, name, value): ... dns_api.create_record(name, "TXT", value) >>> def delete_txt(domain, name): ... dns_api.delete_record(name, "TXT") >>> handler = CallbackDnsHandler(create_txt, delete_txt)
HTTP-01 Handlers¶
CallbackHttpHandler¶
- class acmeow.CallbackHttpHandler[source]¶
Bases:
ChallengeHandlerHTTP-01 handler using user-provided callbacks.
This handler delegates challenge file management to user-provided callback functions, allowing integration with any HTTP serving method.
- Parameters:
Example
>>> def setup_challenge(domain, token, key_auth): ... redis.set(f"acme:{token}", key_auth) >>> def cleanup_challenge(domain, token): ... redis.delete(f"acme:{token}") >>> handler = CallbackHttpHandler(setup_challenge, cleanup_challenge)
FileHttpHandler¶
- class acmeow.FileHttpHandler[source]¶
Bases:
ChallengeHandlerHTTP-01 handler that writes challenge files to a webroot directory.
This handler writes challenge response files to the standard .well-known/acme-challenge/ directory structure. The web server must be configured to serve this directory.
- Parameters:
webroot (
Path) – Path to the web server’s document root. Files will be written to {webroot}/.well-known/acme-challenge/
Example
>>> handler = FileHttpHandler(Path("/var/www/html")) >>> # Challenge file will be at: >>> # /var/www/html/.well-known/acme-challenge/{token}
TLS-ALPN-01 Handlers¶
CallbackTlsAlpnHandler¶
- class acmeow.CallbackTlsAlpnHandler[source]¶
Bases:
ChallengeHandlerTLS-ALPN-01 handler using user-provided callbacks.
This handler delegates certificate deployment to user-provided callback functions, allowing integration with any TLS server.
- Parameters:
Example
>>> def deploy_cert(domain, cert_pem, key_pem): ... # Configure TLS server with certificate ... server.set_certificate(domain, cert_pem, key_pem) >>> def cleanup_cert(domain): ... server.remove_certificate(domain) >>> handler = CallbackTlsAlpnHandler(deploy_cert, cleanup_cert)
FileTlsAlpnHandler¶
- class acmeow.FileTlsAlpnHandler[source]¶
Bases:
ChallengeHandlerTLS-ALPN-01 handler that writes certificates to files.
This handler writes the validation certificate and key to files, which can then be loaded by a TLS server. Optionally calls a reload callback to signal the server to reload certificates.
- Parameters:
cert_dir (
Path) – Directory to write certificate files.cert_pattern (
str) – Pattern for certificate filename. {domain} is replaced.key_pattern (
str) – Pattern for key filename. {domain} is replaced.reload_callback (
Callable[[],None] |None) – Optional callback to reload the TLS server. Signature: () -> None
Example
>>> handler = FileTlsAlpnHandler( ... cert_dir=Path("/etc/tls/acme"), ... cert_pattern="{domain}.crt", ... key_pattern="{domain}.key", ... reload_callback=lambda: subprocess.run(["nginx", "-s", "reload"]), ... )
- __init__(cert_dir, cert_pattern='{domain}.alpn.crt', key_pattern='{domain}.alpn.key', reload_callback=None)[source]¶
Helper Functions¶
generate_tls_alpn_certificate¶
- acmeow.generate_tls_alpn_certificate(domain, key_authorization, key=None, validity_days=1)[source]¶
Generate a TLS-ALPN-01 validation certificate.
Creates a self-signed certificate with the acmeIdentifier extension containing the SHA-256 hash of the key authorization, as required by RFC 8737.
- Parameters:
domain (
str) – The domain name to validate.key_authorization (
str) – The key authorization string (token.thumbprint).key (
Union[DHPrivateKey,Ed25519PrivateKey,Ed448PrivateKey,RSAPrivateKey,DSAPrivateKey,EllipticCurvePrivateKey,X25519PrivateKey,X448PrivateKey,None]) – Private key to use. If None, generates an EC P-256 key.validity_days (
int) – Certificate validity period in days. Default 1.
- Return type:
- Returns:
Tuple of (certificate_pem, private_key_pem) as bytes.
Example
>>> cert_pem, key_pem = generate_tls_alpn_certificate( ... "example.com", ... "token.thumbprint", ... )