Skip to main content

Serles: A Tiny and Extensible ACME Server/Proxy

Introduction

Serles is a tiny ACME-CA implementation to enhance your existing Certificate Authority infrastructure. Initially developed to support ACME with the Open Source version of PrimeKey’s EJBCA’s (ACME support is only available in the Enterprise version), the software is designed for easy adaptation to other PKI software/CAs which provide an API to issue certificates.

We sometimes call it a proxy, as it delegates certificate issuance to your existing PKI. From a user’s point of view, serles-acme can be your own private Let’s Encrypt, when combined with EJBCA.

If you want to use another PKI, feel free to implement your own backends. Contributions are welcome.

Who is this project for?

  • You want to build up your own PKI, either for company or home use

  • You want to automate the issuing process for all your devices

  • You already use another PKI Software and want to use certbot with it

Architecture

Serles is intended to automate certificate issuance from your existing CA. It will verify the legitimacy of certificate requests, and, if this is the case, pass them on to a plugin/backend.

+--------+                            +--------+                        +---------+
|        | (1) ---{authentication}--> |        |                        | Backend |
|  Web   | (2) ---{order cert}------> | Serles |                        |  (e.g.  |
| Server | <-----{validation}-----(3) |  ACME  |                        |  EJBCA) |
|        | (4) ---{CSR}-------------> |        | (5) ---{CSR}---------> |         |
+--------+ <-----{certificate}--- (7) +--------+ <--{certificate}-- (6) +---------+

The threat model is execution inside a (trusted) enterprise network. Yet, care has been taken when accepting any user data. While there is no user authentication (i.e. anyone who can access Serles is allowed to ask for certificates), one may specify to which IP subnets requested domains must resolve in order to be granted a certificate.

Installation

See installation https://serles-acme.readthedocs.io/en/latest/installation.html.

Configuration

The configuration file can be set using the CONFIG environment variable. If it is absent, it is loaded from /etc/serles.ini. An extensively commented example configuration file is included as config.ini.example. You may copy (and rename) it to the beforementioned location. Serles is compatible with any WSGI server; please consult your server’s manual for its configuration.

Backends

The software ships with a few predefined backends, but it is easy to write others. If you do, please send patches!

A backend is simply a class (no inheritance required) and has the following methods:

  • a constructor taking the parsed config (ConfigParser object; dict-like)

  • a method sign(self, csr, subjectDN, subjectAltNames, email):

    Parameters:

    • csr: the CSR as coming from the client (in PEM-encoded PKCS#10 format)

    • subjectDN: The CSR’s Distinguished Name as a string or, if absent, one created from the template string in the config file.

    • subjectAltNames: a list of domain names (as strings) that are to be written in the certificate’s SAN extension attributes.

    • email: the email stored in the requesting account (or None). Intended to be passed on to the backend for notification of the client.

    Returns:

    • on success, the tuple (pem_chain, None) where pem_chain is the full PEM-encoded certificate chain.

    • on error, the tuple (None, error_msg), where error_msg is a string (possibly forwarded from the backend) that describes why the CSR has been rejected. This is forwarded to the client in a badCSR problem document.

class SomeBackend:
    def __init__(self, config):
        self.config = config
    def sign(self, csr, subjectDN, subjectAltNames, email):
        return None, "not implemented"

Optionally, one can also inherit from the abstract serles.backends.base:

class SomeBackend(serles.backends.base):
    def sign(self, csr, subjectDN, subjectAltNames, email):
        return None, "not implemented"

EJBCA SOAP Backend

All you need is a user that has permission to issue certificates. Set up a Certificate Authority (e.g. testca), an End Entity Profile (e.g. acmeendentity) and a Certificate Profile (e.g. acmeserverprofile). Set up and enroll a user with a client certificate which will be used to talk to the API.

When issuing certificates, the Username and Enrollment Code will be generated from a template. This template can be configured in the config; you can use parameters from the Distinguished Name (from CSR) by wrapping them in curly braces.

If the client sets a contact email, we will pass it on to EJBCA when forwarding the CSR. EJBCA can then be configured to send notifications for the EndEntityProfile.

CertBot Backend

All you need is an existing installation of certbot on the host running serles that is capable of issuing certificates. Serles can then use certbot for any client requests. This is generally used in conjunction with DNS based validation.

At a minimum for setup, you will want to provide certbot.config or certbot.config-file specifying what method to use for validation of certificates and any necessary configuration for that method. You will need to refer to your particular certbot backend for minimum configuration required.

The certbot plugin is usually used with a DNS backend, however if you have your serles installation in a DMZ with a wildcarded host or similar, you could potentially use the http-01 based validation.

For Route53, with credentials already set up in environment, this may be sufficient:

preferred-challenges=dns
dns-route53

For CloudFlare:

preferred-challenges=dns
dns-cloudflare
dns-cloudflare-credentials=/path/to/cloudflare.ini

See certbot’s DNS plugin documentation for more details and other providers.

If you have set up certbot for serles to have it’s own installation directories, you may want to specify those here, otherwise make sure that serles is running with a userid that has filesystem perms to write to the certbot directories.

Additional configuration in that case assuming /local/acme/certbot installation path.

config-dir=/local/acme/certbot/config
work-dir=/local/acme/certbot/work
logs-dir=/local/acme/certbot/logs

Dependencies

Dependencies are stated in setup.py.

Metadata

Release files for serles-acme 1.3.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for serles-acme 1.3.0
File Size Uploaded Provenance Actions
serles_acme-1.3.0.tar.gz 53.0 kB Without provenance Details for serles_acme-1.3.0.tar.gz

Built distribution (wheel)

Table of built distributions (wheels) for serles-acme 1.3.0
File Interpreter ABI Platform Actions
serles_acme-1.3.0-py3-none-any.whl Python 3 none any Details for serles_acme-1.3.0-py3-none-any.whl

Total release size: 94.6 kB

Release files / serles_acme-1.3.0.tar.gz

Download URL serles_acme-1.3.0.tar.gz
Size 53.0 kB
Tags Source
SHA-256 checksum
How to use checksums
5bda29601237c060355631d0686415669080eeaf0331b58249e677dae1b49602
BLAKE2b-256 checksum
How to use checksums
c13b710e13edb786e1ee402fc3c637e22470bf1bc2f0097f2468682ba254f2fd
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.2.0 CPython/3.14.6

Release files / serles_acme-1.3.0-py3-none-any.whl

Download URL serles_acme-1.3.0-py3-none-any.whl
Size 41.6 kB
Tags Python 3
SHA-256 checksum
How to use checksums
7be9a386f013dcebd081252478200e71d6dca06898649d1365a7143535c0c3d8
BLAKE2b-256 checksum
How to use checksums
54e35bb452faa2b1dd20bb2ed656dc8185dac857f87334b89cd0e09c02e1d573
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.2.0 CPython/3.14.6

Security for serles-acme 1.3.0

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

No provenance found

None of the files in this release were uploaded with provenance metadata.

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

To learn more about protecting yourself from malicious actors, visit our package security documentation.

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page