diff --git a/README.md b/README.md new file mode 100644 index 0000000..0d79f05 --- /dev/null +++ b/README.md @@ -0,0 +1,105 @@ +# Gufo ACME + +*Gufo ACME is a Python asyncio client for the ACME protocol.* + +[![PyPi version](https://img.shields.io/pypi/v/gufo_acme.svg)](https://pypi.python.org/pypi/gufo_loader/) +![Python Versions](https://img.shields.io/pypi/pyversions/gufo_acme) +[![License](https://img.shields.io/badge/License-BSD_3--Clause-blue.svg)](https://opensource.org/licenses/BSD-3-Clause) +![Build](https://img.shields.io/github/actions/workflow/status/gufolabs/gufo_acme/py-tests.yml?branch=master) +![Sponsors](https://img.shields.io/github/sponsors/gufolabs) +[![Ruff](https://img.shields.io/endpoint?url=https://raw.githubusercontent.com/charliermarsh/ruff/main/assets/badge/v0.json)](https://github.com/charliermarsh/ruff) +--- + +**Documentation**: [https://docs.gufolabs.com/gufo_acme/](https://docs.gufolabs.com/gufo_acme/) + +**Source Code**: [https://github.com/gufolabs/gufo_acme/](https://github.com/gufolabs/gufo_acme/) + +--- + +The Automatic Certificate Management Environment (ACME) protocol defines a method +for automated certificate signing, now widely used by services +such as Let's Encrypt. Gufo ACME is a Python asyncio ACME client library that +simplifies the protocol complexity with a straightforward and robust API. + +## Examples + +### Account Creation + +Create an account and store state to the file. +``` python +client_key = ACMEClient.get_key() +async with ACMEClient(DIRECTORY, key=client_key) as client: + await client.new_account(email) + state = client.get_state() +with open(client_state_path, "wb") as fp: + fp.write(state) +``` + +### Private Key Generation + +To generate a private key in PEM format. +``` python +private_key = ACMEClient.get_domain_private_key() +``` + +### Generate CSR + +To generate a certificate signing request. +``` python +csr = ACMEClient.get_domain_csr(domain, private_key) +``` + +### Sign Certificate + +Sign the certificate using `http-01` challenge: + +``` python +CHALLENGE_DIR = "/www/acme/" + + +class SignACMEClient(ACMEClient): + async def fulfill_http_01( + self, domain: str, challenge: ACMEChallenge + ) -> bool: + v = self.get_key_authorization(challenge) + with open(os.path.join(CHALLENGE_DIR, challenge.token), "wb") as fp: + fp.write(v) + return True + + async def clear_http_01( + self: ACMEClient, domain: str, challenge: ACMEChallenge + ) -> None: + os.unlink(os.path.join(CHALLENGE_DIR, challenge.token)) + + ... +async with SignACMEClient.from_state(state) as client: + cert = await client.sign(domain, csr) +``` + +## Virtues + +* Pure-Python implementation. +* Asynchronous. +* Clean API. +* Robust well-tested code. +* 97%+ test coverage. + +## On Gufo Stack + +This product is a part of [Gufo Stack][Gufo Stack] - the collaborative effort +led by [Gufo Labs][Gufo Labs]. Our goal is to create a robust and flexible +set of tools to create network management software and automate +routine administration tasks. + +To do this, we extract the key technologies that have proven themselves +in the [NOC][NOC] and bring them as separate packages. Then we work on API, +performance tuning, documentation, and testing. The [NOC][NOC] uses the final result +as the external dependencies. + +[Gufo Stack][Gufo Stack] makes the [NOC][NOC] better, and this is our primary task. But other products +can benefit from [Gufo Stack][Gufo Stack] too. So we believe that our effort will make +the other network management products better. + +[Gufo Labs]: https://gufolabs.com/ +[Gufo Stack]: https://gufolabs.com/products/gufo-stack/ +[NOC]: https://getnoc.com/ \ No newline at end of file diff --git a/docs/index.md b/docs/index.md new file mode 100644 index 0000000..bfff7e8 --- /dev/null +++ b/docs/index.md @@ -0,0 +1,102 @@ +--- +template: index.html +hide: + - navigation + - toc +hero: + title: Gufo ACME + subtitle: The Python asyncio client for the ACME protocol + install_button: Getting Started + source_button: Source Code +--- +# Gufo ACME + +*Gufo ACME is a Python asyncio client for the ACME protocol.* + +The Automatic Certificate Management Environment (ACME) protocol defines a method +for automated certificate signing, now widely used by services +such as Let's Encrypt. Gufo ACME is a Python asyncio ACME client library that +simplifies the protocol complexity with a straightforward and robust API. + +## Examples + +### Account Creation + +Create an account and store state to the file. +``` python +client_key = ACMEClient.get_key() +async with ACMEClient(DIRECTORY, key=client_key) as client: + await client.new_account(email) + state = client.get_state() +with open(client_state_path, "wb") as fp: + fp.write(state) +``` + +### Private Key Generation + +To generate a private key in PEM format. +``` python +private_key = ACMEClient.get_domain_private_key() +``` + +### Generate CSR + +To generate a certificate signing request. +``` python +csr = ACMEClient.get_domain_csr(domain, private_key) +``` + +### Sign Certificate + +Sign the certificate using `http-01` challenge: + +``` python +CHALLENGE_DIR = "/www/acme/" + + +class SignACMEClient(ACMEClient): + async def fulfill_http_01( + self, domain: str, challenge: ACMEChallenge + ) -> bool: + v = self.get_key_authorization(challenge) + with open(os.path.join(CHALLENGE_DIR, challenge.token), "wb") as fp: + fp.write(v) + return True + + async def clear_http_01( + self: ACMEClient, domain: str, challenge: ACMEChallenge + ) -> None: + os.unlink(os.path.join(CHALLENGE_DIR, challenge.token)) + + ... +async with SignACMEClient.from_state(state) as client: + cert = await client.sign(domain, csr) +``` + +## Virtues + +* Pure-Python implementation. +* Asynchronous. +* Clean API. +* Robust well-tested code. +* 97+% test coverage. + +## On Gufo Stack + +This product is a part of [Gufo Stack][Gufo Stack] - the collaborative effort +led by [Gufo Labs][Gufo Labs]. Our goal is to create a robust and flexible +set of tools to create network management software and automate +routine administration tasks. + +To do this, we extract the key technologies that have proven themselves +in the [NOC][NOC] and bring them as separate packages. Then we work on API, +performance tuning, documentation, and testing. The [NOC][NOC] uses the final result +as the external dependencies. + +[Gufo Stack][Gufo Stack] makes the [NOC][NOC] better, and this is our primary task. But other products +can benefit from [Gufo Stack][Gufo Stack] too. So we believe that our effort will make +the other network management products better. + +[Gufo Labs]: https://gufolabs.com/ +[Gufo Stack]: https://gufolabs.com/products/gufo-stack/ +[NOC]: https://getnoc.com/ \ No newline at end of file diff --git a/docs/standards.md b/docs/standards.md new file mode 100644 index 0000000..8ccf870 --- /dev/null +++ b/docs/standards.md @@ -0,0 +1,16 @@ +# Supported Standards + +Gufo Err implements and is guided by the following standards: + +## RFC + +* [RFC-8555][RFC8555]: Automatic Certificate Management Environment (ACME) + +## :simple-python: Python PEP + +* [PEP8][PEP8]: Style Guide for Python Code +* [PEP561][PEP561]: Distributing and Packaging Type Information + +[PEP8]: https://peps.python.org/pep-0008/ +[PEP561]: https://peps.python.org/pep-0561/ +[RFC8555]: https://datatracker.ietf.org/doc/html/rfc8555 \ No newline at end of file