Skip to content

ACME Responder

lacme.acme_server

ASGI application implementing ACME protocol endpoints.

Provides :class:ACMEResponder, an ASGI app that implements enough of RFC 8555 for :meth:~lacme.client.Client.issue to work against it. Certificate signing is delegated to :class:~lacme.ca.CertificateAuthority. Mount in your web framework (Starlette, FastAPI, etc.) at a path prefix.

ACMEResponder

ASGI application implementing ACME protocol endpoints.

Delegates certificate signing to a :class:~lacme.ca.CertificateAuthority. Mount in your web framework at a path prefix.

When the responder is reached through NAT or a reverse proxy, pass the canonical externally reachable responder URL via external_url. The URL must include the mount prefix and is used for every URL advertised through the ACME protocol. Supply it as an ASCII HTTP(S) URI, using punycode for internationalized hostnames and percent-encoded UTF-8 bytes for non-ASCII paths; credentials, query strings, fragments, and ambiguous path segments are not accepted.

.. warning::

This responder does **not** validate JWS signatures or nonces.
It is intended for trusted internal networks where the transport
layer (mTLS, private network) provides authentication.  Do not
expose to untrusted clients without additional auth middleware.

Usage::

ca = CertificateAuthority(store=store)
ca.init()
responder = ACMEResponder(
    ca=ca,
    auto_approve=True,
    external_url="https://ca.example/acme",
)
# Mount at /acme in your ASGI app
# Clients use: directory_url="https://ca.example/acme/directory"
__call__ async
__call__(scope: Scope, receive: Receive, send: Send) -> None

ASGI entry point.

ChallengeValidator

Bases: Protocol

Protocol for external challenge validation.

validate async
validate(identifier: str, identifier_type: str, token: str, key_authorization: str) -> bool

Return True if the challenge is satisfied.