{"id":22832567,"url":"https://github.com/waldner/cert-manager-webhook-he","last_synced_at":"2025-04-23T21:25:14.187Z","repository":{"id":92012176,"uuid":"582092672","full_name":"waldner/cert-manager-webhook-he","owner":"waldner","description":"`cert-manager` webook to use HE DNS as ACME DNS01 solver","archived":false,"fork":false,"pushed_at":"2024-03-30T18:19:13.000Z","size":86,"stargazers_count":8,"open_issues_count":0,"forks_count":3,"subscribers_count":3,"default_branch":"master","last_synced_at":"2025-03-30T03:41:15.666Z","etag":null,"topics":["cert-manager","cert-manager-webhook","hurricane-electric","kubernetes","webhook"],"latest_commit_sha":null,"homepage":"","language":"Go","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"gpl-3.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/waldner.png","metadata":{"files":{"readme":"README.md","changelog":null,"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}},"created_at":"2022-12-25T16:36:56.000Z","updated_at":"2024-11-11T22:31:23.000Z","dependencies_parsed_at":null,"dependency_job_id":"9e2edfa8-5603-47f5-9f92-010b20dd6808","html_url":"https://github.com/waldner/cert-manager-webhook-he","commit_stats":null,"previous_names":[],"tags_count":5,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/waldner%2Fcert-manager-webhook-he","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/waldner%2Fcert-manager-webhook-he/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/waldner%2Fcert-manager-webhook-he/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/waldner%2Fcert-manager-webhook-he/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/waldner","download_url":"https://codeload.github.com/waldner/cert-manager-webhook-he/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":250516005,"owners_count":21443528,"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","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":["cert-manager","cert-manager-webhook","hurricane-electric","kubernetes","webhook"],"created_at":"2024-12-12T21:08:01.492Z","updated_at":"2025-04-23T21:25:14.164Z","avatar_url":"https://github.com/waldner.png","language":"Go","funding_links":[],"categories":[],"sub_categories":[],"readme":"# `cert-Manager` ACME DNS01 Webhook Solver for HE DNS\n\n[![Go Report Card](https://goreportcard.com/badge/github.com/waldner/cert-manager-webhook-he)](https://goreportcard.com/report/github.com/waldner/cert-manager-webhook-he)\n[![Releases](https://img.shields.io/github/v/tag/waldner/cert-manager-webhook-he)](https://github.com/waldner/cert-manager-webhook-he/tags)\n[![LICENSE](https://img.shields.io/github/license/waldner/cert-manager-webhook-he)](https://github.com/waldner/cert-manager-webhook-he/blob/master/LICENSE)\n\nA webhook to use [HE DNS](https://dns.he.net) as a DNS01 ACME Issuer for [cert-manager](https://github.com/jetstack/cert-manager).\n\n\n## Installation\n\nThe webhook must be installed in the same namespace where cert-manager is running (usually `cert-manager`).\nSee the following paragraph for an explanation of what \"use secrets\" or \"use environment variables\" mean.\n\nTo install with helm from the registry, run:\n\n```bash\n# to use secrets for credentials:\n$ helm upgrade --install --namespace cert-manager --set auth.useSecrets=true cert-manager-webhook-he oci://ghcr.io/waldner/charts/cert-manager-webhook-he\n\n# to use environment variables\n$ helm upgrade --install --namespace cert-manager \\\n   --set auth.heUsername=myusername \\\n   --set auth.hePassword=mypassword \\\n   --set auth.heApiKey=myapikey \\\n   cert-manager-webhook-he oci://ghcr.io/waldner/charts/cert-manager-webhook-he\n```\n\nIf you want to install from the repo checkout:\n\n```bash\n$ git clone https://github.com/waldner/cert-manager-webhook-he.git\n$ cd cert-manager-webhook-he\n\n# to use secrets for credentials:\n$ helm upgrade --install --namespace cert-manager \\\n     --set auth.useSecret=true cert-manager-webhook-he deploy/cert-manager-webhook-he\n\n# to use environment variables:\n$ helm upgrade --install --namespace cert-manager \\\n   --set auth.heUsername=myusername \\\n   --set auth.hePassword=mypassword \\\n   --set auth.heApiKey=myapikey \\\n   cert-manager-webhook-he deploy/cert-manager-webhook-he\n```\n\nCheck the logs with\n\n```bash\n$ kubectl get pods -n cert-manager --watch\n$ kubectl logs -n cert-manager cert-manager-webhook-he-xxxxx\n```\n\n\n## Concepts and configuration\n\nThe webhook can work in two modes: `login` and `dynamic-dns` (explained later).\nWhatever method you choose, in the `Issuer` YAML the configuration options must\nbe under the `dns01.webhook` path (see examples below).\nAlso regardless of the mode, the webhook can read its credentials either from\nenvironment variables (the default) or from kubernetes `Secret`s.\n\nThe main difference is that credentials passed via environment variables are static\nand can only be changed by redeploying the container, while credentials stored\nin secrets can be updated by just updating the secrets (or creating new ones),\nthen referencing them from the `Issuer`.\n\nIf you want to use multiple accounts, or be able to set per-issuer credentials,\nyou should use secrets. If, on the other hand, you only have a single set of\ncredentials that you want to use everywhere, using environment variables is\nappropriate.\n\nWhether the webhook reads the credentials from environment variables (the\ndefault) or from secrets is determined by the `auth.useSecrets` variable of the\nHelm chart, which you can override when you deploy the chart.\n\nChoosing to use secrets or environment variables has implications for the\ndeployment, since when using secrets additional permissions will be given to\nthe webhook service account to be able to read secrets (see below for details).\n\n### `login` mode\n\nIn `login` mode, the TXT record(s) are created and deleted by logging into the\nHE DNS control panel using the normal user credentials. The credentials needed\nfor this mode are the HE DNS control panel username and password. If you store\nthem in a secret, they must be associated respectively to the `username` and \n`password` keys in the secret data. Example secret:\n\n```yaml\napiVersion: v1\nkind: Secret\nmetadata:\n  name: he-credentials\ntype: Opaque\nstringData:\n  username: \"myHEusername\"\n  password: \"myHEpassword\"\n```\n\nIf you use environment variables, you must pass them as `auth.heUsername` and\n`auth.hePassword` when deploying the Helm chart.\n\nHere's a sample `Issuer` configuration for the `login` mode:\n\n```yaml\napiVersion: cert-manager.io/v1\nkind: Issuer\n...\n  solvers:\n    - dns01:\n        webhook:\n          solverName: he\n          groupName: acme.xdb.me\n          config:\n            heUrl: \"https://dns.he.net\"   # URL for operations. Default (and probably the only valid value): \"https://dns.he.net\"\n            method: \"login\"               # method to use. \"login\" is also the default\n            # only if you use secrets\n            credentialsSecretRef:\n              name: \"my-secret\"           # name of secret. Default: \"he-credentials\"\n              namespace: \"myns\"           # optional namespace for the secret. If not given, the secret is\n                                          # looked for in the issuer namespace.\n                                          # For a ClusterIssuer, specify this or the release namespace (eg,\n                                          # `cert-manager`) will be used.\n```\n\n\n### `dynamic-dns` mode\n\nIn `dynamic-dns` mode, the TXT record(s) are never created or deleted, but \ninstead you need to pre-create an aptly named TXT entry (eg, \n`_acme-challenge.mydomain.com`) in the domain control panel and the webhook\nwill update/overwrite it with the actual key needed to solve the ACME\nchallenge. To do this, you also need to generate or set an API key (done via\nthe control panel for the record) that will be used for the dynamic update\nrequests.\n\n*NOTE: The `dynamic-dns` mode cannot do concurrent validations (it's always\nthe same TXT record that gets updated), so it should only be used in environments\nwhere you expect only a single challenge at a time for each domain, and you know\nin advance the name of the TXT record to update.*\n\nFor more information, see the section \"Dynamic TXT records\" [here](https://dns.he.net/).\n\nFor this mode, the only credential you need is the API key. If you want to\nuse a secret, you store it in the `apiKey` field. Here's an example:\n\n```yaml\napiVersion: v1\nkind: Secret\nmetadata:\n  name: he-credentials\ntype: Opaque\nstringData:\n  apiKey: \"skdhjfkdhkjs\"\n```\n\nIf you pass it via the environment, you must use the `auth.heApiKey`\nvariable when deploying the Helm chart.\n\nHere's a sample `Issuer` configuration for the `dynamic-dns` mode:\n\n```yaml\napiVersion: cert-manager.io/v1\nkind: Issuer\n...\n  solvers:\n    - dns01:\n        webhook:\n          solverName: he\n          groupName: acme.xdb.me\n          config:\n            heUrl: \"https://dyn.dns.he.net\" # URL for operations. Default: \"https://dyn.dns.he.net\"\n            method: \"dynamic-dns\"           # method to use.\n\n            # Only if you use secrets\n            apiKeySecretRef:\n              name: \"my-secret\"             # name of secret. Default: \"he-credentials\"\n              namespace: \"myns\"             # optional namespace for the secret. If not given, the secret is\n                                            # looked for in the issuer namespace.\n                                            # For a ClusterIssuer, specify this or the release namespace (eg,\n                                            # `cert-manager`) will be used.\n```\n\n### Access control for secrets\n\nIf using secrets, there is the option to limit the namespaces the webhook will\nbe able to access, and also the name of the secrets it will have permission to\nread. This is done by setting the helm variables `rbac.secretNamespaces` (a list\nof namespaces, by default `[default]`) and `rbac.secretNames` (a list of names,\nby default `[he-credentials]`).\nIf you want to be able to read secrets in any namespace, pass an empty list for\n`rbac.secretNamespaces`, and a `ClusterRole` will be created instead of a `Role`\n(use with caution).\n\n\n\n## Development\n\n*IMPORTANT NOTE: only the `login` mode is conformant with the cert-manager\nrequirements, as it allows for multiple simultaneous DNS01 challenges (and\nthus TXT records) in a single domain. The `dynamic-dns` mode cannot do that\n(it's always the same TXT record that gets updated), so it should only be\nused in environments where you expect only a single challenge at a time for\neach domain.*\n\nFor the same reason, a `dynamic-dns` mode test is not included in the test\nsuite, as it expects the TXT record to be removed for the test to be declared\nsuccessful (`dynamic-dns` mode merely overwrites the key with new values every\ntime; the TXT record is never removed).\n\nFortunately, in the actual runtime cert-manager doesn't check that a given\nrecord is deleted or not after the challenge, so that's why you can use the\n`dynamic-dns` method if you want (but not run tests with it), modulo the above\nnotice.\n\n\n### Running the test suite\n\nConformance testing is achieved through Kubernetes emulation via the\nkubebuilder-tools suite, in conjunction with real calls to HE on a\ntest domain, using valid credentials or API token stored in secrets.\n\nThe test configures a `_acme-challenge-test` TXT entry, attempts to verify\nits presence, and removes the entry, thereby verifying the Prepare and CleanUp\nfunctions.\n\nTo run the test suite, you must create two files under `testdata/he`. One \n(let's call it `config.json`) represents the configuration fragment that\nwill be used by the webhook; the other one (`secret.yaml`) must contain the\nHE credentials (username and password). There are examples of both files\nunder `testdata/he`.\n\nOnce the files are in place, run the test suite with:\n\n```bash\nTEST_ZONE_NAME=yourdomain.com. make test\n```\n\nYou can also set `VERBOSE=1` (or to any other nonempty value) to see debug messages\n(note that this increases verbosity for all components):\n\n```bash\nVERBOSE=1 TEST_ZONE_NAME=yourdomain.com. make test\n```\n\nHave a look at `main_test.go` in case you want to customize the test suite.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fwaldner%2Fcert-manager-webhook-he","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fwaldner%2Fcert-manager-webhook-he","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fwaldner%2Fcert-manager-webhook-he/lists"}