{"id":1307,"library":"acme","title":"ACME protocol implementation in Python","description":"The `acme` library is a low-level, comprehensive Python implementation of the Automated Certificate Management Environment (ACME) protocol, primarily maintained as part of the Certbot project. It enables programmatic certificate issuance, renewal, and management, supporting Let's Encrypt and other ACME-compatible certificate authorities. Currently at version 5.5.0, `acme` follows the release cadence of Certbot, typically seeing several updates per year, often driven by new ACME RFCs or internal Certbot architectural changes.","status":"active","version":"5.5.0","language":"python","source_language":"en","source_url":"https://github.com/certbot/certbot","tags":["ACME","SSL","TLS","Certbot","Let's Encrypt","certificates","cryptography","PKI"],"install":[{"cmd":"pip install acme","lang":"bash","label":"Install stable version"}],"dependencies":[{"reason":"Requires Python 3.10 or later.","package":"python","optional":false},{"reason":"Cryptography utilities for JOSE (JSON Object Signing and Encryption).","package":"josepy","optional":false},{"reason":"Core cryptographic primitives for Python.","package":"cryptography","optional":false},{"reason":"HTTP library for making requests to ACME servers.","package":"requests","optional":false},{"reason":"OpenSSL wrapper for Python (though usage has been reduced/deprecated in favor of 'cryptography').","package":"pyopenssl","optional":false}],"imports":[{"symbol":"ClientV2","correct":"from acme import client"},{"symbol":"messages","correct":"from acme import messages"},{"symbol":"challenges","correct":"from acme import challenges"},{"symbol":"josepy","correct":"import josepy as jose"},{"note":"While developed with Certbot, crypto_util is part of the acme package itself.","wrong":"from certbot import crypto_util","symbol":"crypto_util","correct":"from acme import crypto_util"}],"quickstart":{"code":"import os\nfrom cryptography.hazmat.primitives.asymmetric import rsa\nfrom cryptography.hazmat.backends import default_backend\n\nfrom acme import client\nfrom acme import messages\nimport josepy as jose\n\n# This is the staging ACME URL for Let's Encrypt\nDIRECTORY_URL = os.environ.get('ACME_DIRECTORY_URL', 'https://acme-staging-v02.api.letsencrypt.org/directory')\n\ndef run_acme_client():\n    # 1. Create a new ACME account private key\n    acc_key_pem = rsa.generate_private_key(\n        public_exponent=65537, key_size=2048, backend=default_backend()\n    )\n    acc_key = jose.JWK.from_pem(acc_key_pem.private_bytes(\n        encoding=jose.serialization.Encoding.PEM,\n        format=jose.serialization.PrivateFormat.PKCS8,\n        encryption_algorithm=jose.serialization.NoEncryption()\n    ))\n\n    # 2. Initialize the client network\n    net = client.ClientNetwork(acc_key, user_agent=\"my-acme-client/1.0\")\n\n    # 3. Get the ACME directory object\n    directory = messages.Directory.from_json(net.get(DIRECTORY_URL).json())\n\n    # 4. Create the ACME client\n    acme_client = client.ClientV2(directory, net=net)\n\n    # 5. Register a new account (or load existing)\n    #   email_contact is optional for staging/testing\n    new_reg = messages.NewRegistration(\n        terms_of_service_agreed=True, \n        contact=('mailto:test@example.com',) if 'test@example.com' in os.environ.get('ACME_EMAIL', '') else None\n    )\n    \n    try:\n        regr = acme_client.new_account(new_reg)\n        print(f\"Account created/loaded: {regr.uri}\")\n    except client.errors.ConflictError as e:\n        # Account already exists, retrieve it\n        print(f\"Account already exists, retrieving: {e.uri}\")\n        regr = acme_client.query_registration(messages.RegistrationResource(uri=e.uri, body=new_reg))\n\n    print(\"ACME client initialized and account registered.\")\n    return acme_client, regr\n\nif __name__ == \"__main__\":\n    acme_client_instance, account_resource = run_acme_client()","lang":"python","description":"This quickstart demonstrates the absolute minimum to initialize the `acme` client and register an account with an ACME server (like Let's Encrypt staging). Note that `acme` is a low-level library; most users will prefer a higher-level client like Certbot for end-to-end certificate management. This example creates an RSA account key, sets up the network client, fetches the directory, and attempts to register a new ACME account, handling potential conflicts if the account already exists. It uses the Let's Encrypt staging environment by default."},"warnings":[{"fix":"Migrate any code using these removed classes/functions to their `cryptography` equivalents or alternative ACME challenge methods. Review the `certbot` changelog for detailed migration paths. For TLS-ALPN, re-evaluate if still necessary as its support was deprecated and then removed.","message":"Major architectural shift in version 5.0.0 (aligned with Certbot 5.0.0) removed `acme.crypto_util.SSLSocket`, `acme.crypto_util.probe_sni`, and TLS-ALPN related challenge classes (`acme.challenges.TLSALPN01Response`, `acme.challenges.TLSALPN01`, `acme.standalone.TLSServer`, `acme.standalone.TLSALPN01Server`). This also removed final `pyopenssl` x509 and PKey objects usage within `acme`'s core cryptography, favoring `cryptography` library objects.","severity":"breaking","affected_versions":">=5.0.0"},{"fix":"Avoid using `acme.crypto_util.make_self_signed_cert`. If self-signed certificates are required, use `cryptography`'s API directly or an external tool.","message":"The function `acme.crypto_util.make_self_signed_cert` was deprecated in Certbot 5.1.0 and is slated for removal. This indicates a shift away from generating self-signed certificates directly within the `acme` library.","severity":"deprecated","affected_versions":">=5.1.0"},{"fix":"Ensure all ACME interactions adhere to RFC 8555. Update any references to `OLD_ERROR_PREFIX` or the removed `Directory` and `Authorization` attributes. The `source_address` removal requires alternative methods for binding to specific local IPs if needed.","message":"Version 2.0.0 (aligned with Certbot 2.0.0) removed support for pre-RFC 8555 ACME versions and related deprecated messaging constructs like `acme.messages.OLD_ERROR_PREFIX`. It also removed the `source_address` argument from `acme.client.ClientNetwork` and several deprecated attributes from `acme.messages.Directory` and `acme.messages.Authorization`.","severity":"breaking","affected_versions":">=2.0.0"},{"fix":"Ensure your environment meets these minimum dependency versions to avoid runtime errors, especially when upgrading `acme` or `certbot`.","message":"The `acme` library's cryptographic requirements are tightly coupled with `certbot`'s and have increased over time. As of Certbot 3.2.0, `acme` requires `cryptography>=43.0.0` and `pyOpenSSL>=25.0.0`.","severity":"gotcha","affected_versions":">=3.2.0"}],"env_vars":null,"search_vec":"'5.5.0':55 'acm':1,7,23,48,56,73,80 'acme-compat':47 'architectur':78 'author':51 'autom':19 'cadenc':60 'certbot':31,62,77,83 'certif':20,36,50,87 'chang':79 'compat':49 'comprehens':14 'cryptographi':88 'current':52 'driven':70 'enabl':34 'encrypt':44,86 'environ':22 'follow':57 'implement':3,16 'intern':76 'issuanc':37 'let':42,84 'level':13 'librari':8 'low':12 'low-level':11 'maintain':26 'manag':21,40 'new':72 'often':69 'part':28 'per':67 'pki':89 'primarili':25 'programmat':35 'project':32 'protocol':2,24 'python':5,15 'releas':59 'renew':38 'rfcs':74 'see':64 'sever':65 'ssl':81 'support':41 'tls':82 'typic':63 'updat':66 'version':54 'year':68","created_at":"2026-04-09T03:42:18.131230+00:00","updated_at":"2026-04-15T19:06:59.448146+00:00","problems":[{"fix":"Downgrade pyOpenSSL to version 23.1.0 by running: pip install 'pyOpenSSL==23.1.0'.","cause":"This error occurs when using acme v1.23.0 with pyOpenSSL>=23.2.0 on Python 3.6, due to an invalid version being set in the CSR.","error":"ValueError: Invalid version. The only valid version for X509Req is 0."},{"fix":"Ensure that the ACME object being processed adheres to the correct JSON schema as defined in the acme library documentation.","cause":"This error indicates that the ACME object does not conform to the expected JSON schema.","error":"acme.errors.SchemaValidationError: JSON schema ACME object validation error."},{"fix":"Verify that the ACME server is functioning correctly and that the client is handling nonce values appropriately.","cause":"This error occurs when the ACME server's response lacks the required Replay-Nonce header field.","error":"acme.errors.MissingNonce: Server response nonce error."},{"fix":"Check the authorization resources for errors and ensure that domain validation challenges are correctly configured and passing.","cause":"This error signifies that one or more authorization resources are invalid, often due to failed domain validation challenges.","error":"acme.errors.ValidationError: Error for authorization failures."},{"fix":"Increase the timeout settings in the client configuration or investigate potential network issues causing the delay.","cause":"This error indicates that the client timed out while waiting for an authorization or order to complete.","error":"acme.errors.TimeoutError: Error for when polling an authorization or an order times out."}],"ecosystem":"pypi","meta_description":null,"install_score":100,"quickstart_score":null,"quickstart_tag":null,"pypi_latest":"5.7.0","cli_name":"","cli_version":null,"type":"library","homepage":null,"github":"https://github.com/certbot/certbot","docs":null,"changelog":null,"pypi":"https://pypi.org/project/acme/","npm":null,"openapi_spec":null,"status_page":null,"smithery":null,"categories":["auth-security"],"base_url":null,"auth_type":null,"provenance":{"verified_status":"passing","verified_at":"2026-06-28","last_verified":"2026-08-27","next_check":"2026-07-28","install_tag":"verified"}}