Modern, async-native Python ACME client library for embedding TLS certificate automation.
Project description
lacme
Modern, async-native Python ACME client library for embedding TLS certificate automation.
What is lacme?
lacme fills the gap between full-featured CLI tools like certbot (not designed for embedding) and low-level ACME protocol libraries that leave orchestration to you. It provides a high-level Client.issue() one-liner alongside full access to every step of the ACME workflow. lacme has just two runtime dependencies -- httpx and cryptography -- and supports Python 3.11+.
Features
- Async-native with sync wrapper --
Clientfor asyncio,SyncClientfor blocking code - HTTP-01 and DNS-01 challenges -- built-in handlers with pluggable DNS providers (Cloudflare, Route 53, shell hooks)
- Built-in Certificate Authority --
CertificateAuthorityfor issuing private CA certs, ideal for mTLS - ACME Responder --
ACMEResponderASGI app backed by the built-in CA for internal PKI - Framework integrations -- first-class support for Starlette, FastAPI, and Uvicorn
- CLI tool --
lacme issue,lacme renew,lacme revokefrom the command line - Auto-renewal --
RenewalManagerruns in the background and re-issues expiring certificates - Rate limit tracking -- client-side awareness of Let's Encrypt rate limits with warnings and blocking
- Event system + Prometheus metrics --
EventDispatcherwith typed events; optionalMetricsCollector MockACMEServerfor testing -- in-process mock ACME server viahttpx.MockTransport
Quick Start
pip install lacme
import asyncio
from lacme import Client
from lacme.challenges.http01 import HTTP01Handler
async def main():
handler = HTTP01Handler()
async with Client(
directory_url="https://acme-v02.api.letsencrypt.org/directory",
contact="mailto:you@example.com",
challenge_handler=handler,
) as client:
server = await handler.start_server() # port 80
bundle = await client.issue("example.com")
server.close()
await server.wait_closed()
print(bundle.fullchain_pem.decode())
asyncio.run(main())
Private CA / mTLS
from lacme import CertificateAuthority, client_ssl_context, server_ssl_context
ca = CertificateAuthority()
ca.init()
server_cert = ca.issue("myservice.internal")
client_cert = ca.issue("worker-1", client=True)
server_ctx = server_ssl_context(
cert_pem=server_cert.fullchain_pem,
key_pem=server_cert.key_pem,
ca_cert_pem=ca.root_cert_pem, # require client certs
)
client_ctx = client_ssl_context(
cert_pem=client_cert.cert_pem,
key_pem=client_cert.key_pem,
ca_cert_pem=ca.root_cert_pem,
)
CLI
# Issue a certificate via Let's Encrypt staging
lacme --staging --contact you@example.com issue example.com
# Renew all certificates expiring within 30 days
lacme renew --days 30
# Revoke a certificate
lacme revoke example.com
Documentation
Full documentation is available at turnstonelabs.github.io/lacme.
License
Apache-2.0
Project details
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file lacme-1.0.3.tar.gz.
File metadata
- Download URL: lacme-1.0.3.tar.gz
- Upload date:
- Size: 200.2 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
0061ff25da85a316ff86fe80dc25ab62eac555ffa4f99b2adacfeddd4896952a
|
|
| MD5 |
d6a541e577b910a3220f81cf46089a9f
|
|
| BLAKE2b-256 |
8bcf1f1516f783da4858835e0fc514a0085198aa79ff700bec97e8ef55168f4d
|
Provenance
The following attestation bundles were made for lacme-1.0.3.tar.gz:
Publisher:
publish.yml on turnstonelabs/lacme
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
lacme-1.0.3.tar.gz -
Subject digest:
0061ff25da85a316ff86fe80dc25ab62eac555ffa4f99b2adacfeddd4896952a - Sigstore transparency entry: 1186364043
- Sigstore integration time:
-
Permalink:
turnstonelabs/lacme@3382826e2eb804aa4c80f00ceff51ebf8bb96780 -
Branch / Tag:
refs/tags/v1.0.3 - Owner: https://github.com/turnstonelabs
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@3382826e2eb804aa4c80f00ceff51ebf8bb96780 -
Trigger Event:
push
-
Statement type:
File details
Details for the file lacme-1.0.3-py3-none-any.whl.
File metadata
- Download URL: lacme-1.0.3-py3-none-any.whl
- Upload date:
- Size: 72.0 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
c2b814dc8350720ab3088639b9fe7e5c65143aa81d0b7a427c2e916259b35adf
|
|
| MD5 |
5c5bd7f5bf699470346a38d005ed47bb
|
|
| BLAKE2b-256 |
dd4ee7be52ace45396088b8b20e9c339c15ed4782ac391a10403da984857b144
|
Provenance
The following attestation bundles were made for lacme-1.0.3-py3-none-any.whl:
Publisher:
publish.yml on turnstonelabs/lacme
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
lacme-1.0.3-py3-none-any.whl -
Subject digest:
c2b814dc8350720ab3088639b9fe7e5c65143aa81d0b7a427c2e916259b35adf - Sigstore transparency entry: 1186364082
- Sigstore integration time:
-
Permalink:
turnstonelabs/lacme@3382826e2eb804aa4c80f00ceff51ebf8bb96780 -
Branch / Tag:
refs/tags/v1.0.3 - Owner: https://github.com/turnstonelabs
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@3382826e2eb804aa4c80f00ceff51ebf8bb96780 -
Trigger Event:
push
-
Statement type: