{"id":16956987,"url":"https://github.com/jgraichen/salt-acme","last_synced_at":"2025-10-08T19:20:06.881Z","repository":{"id":37036368,"uuid":"236714927","full_name":"jgraichen/salt-acme","owner":"jgraichen","description":null,"archived":false,"fork":false,"pushed_at":"2025-09-29T17:38:18.000Z","size":170,"stargazers_count":2,"open_issues_count":1,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-10-07T08:53:05.727Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/jgraichen.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2020-01-28T11:00:54.000Z","updated_at":"2025-09-27T22:55:40.000Z","dependencies_parsed_at":"2025-06-09T08:27:02.919Z","dependency_job_id":"a3ee0eed-dd1c-42b8-b83f-3398899d334c","html_url":"https://github.com/jgraichen/salt-acme","commit_stats":null,"previous_names":[],"tags_count":6,"template":false,"template_full_name":null,"purl":"pkg:github/jgraichen/salt-acme","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jgraichen%2Fsalt-acme","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jgraichen%2Fsalt-acme/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jgraichen%2Fsalt-acme/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jgraichen%2Fsalt-acme/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/jgraichen","download_url":"https://codeload.github.com/jgraichen/salt-acme/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jgraichen%2Fsalt-acme/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":279000700,"owners_count":26082805,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-10-08T02:00:06.501Z","response_time":56,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-10-13T22:16:34.250Z","updated_at":"2025-10-08T19:20:06.860Z","avatar_url":"https://github.com/jgraichen.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"# salt-acme\n\nManage TLS certificates with ACME using the salt master for certificate\nmanagement and authentication.\n\nAll cryptographic operations are handled by `salt-pki`. Signing requests are\nsent to a runner on the salt master, e.g. `acme.sign`.\n\nThe runner can authenticate the minion and check if it is permitted to request\ncertificates for a given domain.\n\n## Installation\n\nThe recommended way uses salts GitFS:\n\n```yaml\n# /etc/salt/master\ngitfs_remotes:\n  - 'https://github.com/jgraichen/salt-acme.git':\n      - base: v1.3.0\n  - 'https://github.com/jgraichen/salt-pki.git':\n      - base: v1.0.1\n```\n\nThe execution modules are usually used on the master too. Please synchronize the modules and runners on the master with `salt-run`:\n\n```console\n$ salt-run saltutil.sync_all\nmodules:\n    - modules.acme\n    - modules.acme_dns\nrunners:\n    - modules.acme\n```\n\n## Quick Start\n\nAn `acme` state is shipped with this file. It will automatically create certificates from the pillar using the `acme.sign` runner on the master.\n\nThe master must be configured for ACME and to accept to runner calls from the minions:\n\n```yaml\nacme:\n  config:\n    server: https://acme-v02.api.letsencrypt.org/directory  # default\n\n    # The directory where accounts (e.g. private key, registration) are stored.\n    # Defaults to an `acme` subdirectory in salts `cachedir`.\n    account_dir: /var/cache/salt/master/acme\n\n    # Email address passed to the CA on registration\n    email: certmaster@example.org\n\n  resolver:\n    # Setup resolvers to install DNS01 challenges. See more in\n    # runner documentation below.\n    example.org:\n      module: acme_dns\n      nameserver: 127.0.0.153\n      tsig: hmac-sha256:acme:opCLn9NM...xnoRJIo=\n```\n\n### Pillar Example\n\nExample: Creates certificate and private key in default location (e.g.\n`/etc/acme/example.org/{privkey.pem,fullchain.pem}`).\n\nIncludes other states (`nginx.service`) and reloads services on certificate\nchanges (`nginx`).\n\n```yaml\nacme:\n  certificate:\n    example.org:\n      domains: [example.org, www.example.org]\n      include:\n        - nginx.service\n      watch_in:\n        - nginx\n```\n\n## Execution modules\n\nThe `acme.sign` execution modules accepts a single CSR as arguments and returns an answer with the certificate chain embedded. It can be run on a minion, as well as on the master, e.g. using the runner below. Please note that execution modules must be properly synced on the master using `salt-run saltutil.sync_modules`.\n\n## Runners\n\nThe `acme.sign` runner uses the `acme.sign` execution module on the master to sign a CSR.\n\nAll involved execution modules, including the modules installing challenges, must be able to run in a salt master context, instead of a minion. The salt master must be configured for the acme module (see above) and to [accept runner invocations from the minion](https://docs.saltstack.com/en/latest/ref/peer.html):\n\n```yaml\n# /etc/salt/master\npeer_run:\n  .*:\n    - acme.sign\n```\n\nThe runner can validation signing requests using an authorization file. This file defines which minion is allowed to request a domain:\n\n```yaml\n# /etc/salt/master\nacme:\n  runner:\n    auth_file: /etc/salt/acme.yml\n```\n\n```yaml\n# /etc/salt/acme.yml\nminion_id:\n  - example.org\n  - '*.example.org'\n\n'*.minion_id':\n  - '*'\n```\n\nMinion IDs and domain names are matched with a glob-style pattern using [`fnmatch`](https://docs.python.org/3/library/fnmatch.html).\n\n## Resolver\n\nThe `acme.sign` execution modules uses other modules to install and remove challenges. These resolver modules must implement a common interface:\n\nAn `install` and `remove` function, both accepting a `name`, a list of `tokens` and additional arguments, passed from the resolver configuration. The `tokens` arguments is a list of `{\"name\": \"example.org\", \"token\": \"abc....def\"}` dictionaries.\n\nThe following resolvers are included in this repository.\n\n### `acme_dns`\n\nThe `acme_dns` challenge resolver sends DNS01 challenge tokens to a DNS server using DNS update (RFC 2136).\n\nExample configuration:\n\n```yaml\nacme:\n  resolver:\n    example.org:\n      module: acme_dns\n\n      # Which name server to use\n      nameserver: 127.0.0.153  # required; can be domain name\n      port: 53\n\n      # Zone\n      #\n      # Zone to update. If not given, the resolver name\n      # (here: example.org) will be used as the zone name.\n      zone: example.org\n\n      # Alias mode\n      #\n      # If set, this name will be used for the TXT records, for\n      # example with a CNAME:\n      #   _acme-challenge.example.org CNAME mychallenges.org\n      alias: mychallenges.org\n\n      # Timeout in seconds when sending the DNS update\n      timeout: 10\n\n      # TTL for added TXT records\n      ttl: 120\n\n      # Use a TSIG for authorization. Must be formatted as\n      # \"\u003calgorithm\u003e:\u003cname\u003e:\u003csecret\u003e\"\n      tsig: hmac-sha256:acme:opCLn9NM...xnoRJIo=\n\n      # Verify DNS record propagation\n      #\n      # This will check all nameservers listed in the zone to\n      # have at least the serial from the update in their SOA\n      # records.\n      verify: True\n\n      # Seconds to wait for DNS propagation\n      verify_timeout: 120\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjgraichen%2Fsalt-acme","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fjgraichen%2Fsalt-acme","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjgraichen%2Fsalt-acme/lists"}