This repository contains a cert-manager DNS01 webhook solver for BlueCat Address Manager REST v2.
- Webhook solver name:
bluecat-address-manager - Official Helm chart:
containeroo/cert-manager-webhook-bluecat - Default image repo:
ghcr.io/containeroo/cert-manager-webhook-bluecat
BlueCat API docs: https://docs.bluecatnetworks.com/
cert-manager sends DNS01 challenge requests to this webhook API service. The solver then:
- Authenticates to BlueCat.
- Resolves the target zone.
- Creates a TXT record for
_acme-challenge.<domain>. - Deletes only the matching TXT value during cleanup.
The webhook supports these auth modes:
- bearer token from Kubernetes secret
- basic auth from Kubernetes secret
- username + password secret (creates BlueCat session via
/api/v2/sessions)
- Kubernetes cluster.
- cert-manager installed and running.
- Access to BlueCat Address Manager REST v2 endpoint.
- A DNS zone in BlueCat for the domains you will validate.
- Permission to install cluster-scoped RBAC and APIService resources.
GitHub Actions workflow: .github/workflows/build.yml
Trigger:
- push a tag matching
v*(example:v0.1.0)
What it does:
- Runs
go test ./... - Runs GoReleaser (
.goreleaser.yaml) - Builds and pushes multi-arch images to GHCR:
ghcr.io/containeroo/cert-manager-webhook-bluecat:<tag>ghcr.io/containeroo/cert-manager-webhook-bluecat:latest
Release commands:
git tag v0.1.0
git push origin v0.1.0Install or upgrade using the official chart repository:
helm repo add containeroo https://charts.containeroo.ch
helm repo update
helm upgrade --install cert-manager-webhook-bluecat containeroo/cert-manager-webhook-bluecat \
--namespace cert-manager \
--create-namespace \
--set groupName=acme.bluecat.yourdomain.tld \
--set image.repository=ghcr.io/containeroo/cert-manager-webhook-bluecat \
--set image.tag=v0.1.0Notes:
groupNamemust be a DNS name you own. Keep it stable.- The same
groupNamemust be used in your Issuer/ClusterIssuer webhook stanza.
webhook.config supports:
| Field | Required | Description |
|---|---|---|
apiHost |
yes | BlueCat base URL, example https://bam.example.internal |
apiPath |
no | REST base path, default /api/v2 |
view |
no | BlueCat DNS view name (recommended when zone names overlap) |
zoneID |
no | Numeric BlueCat zone ID |
zone |
no | Zone name, example example.com; if omitted, cert-manager resolvedZone is used |
ttl |
no | TXT TTL in seconds, default 120 |
quickDeploy |
no | Trigger BlueCat quick deploy after TXT create/delete, default true |
insecureSkipTLSVerify |
no | Skip TLS verification (avoid in production) |
caBundleSecretRef |
no | Secret ref for PEM CA bundle used to trust BlueCat TLS cert |
bearerTokenSecretRef |
one auth mode required | Secret ref containing bearer token |
basicAuthSecretRef |
one auth mode required | Secret ref containing either username:password or base64 basic credentials |
username |
one auth mode required | BlueCat username when using session login |
passwordSecretRef |
one auth mode required | Secret ref containing password when using session login |
Authentication requirement:
- configure exactly one of:
bearerTokenSecretRefbasicAuthSecretRefusername+passwordSecretRef
Create a secret for username/password session auth:
kubectl -n cert-manager create secret generic bluecat-auth \
--from-literal=password='YOUR_BLUECAT_PASSWORD'Create a secret for bearer token auth:
kubectl -n cert-manager create secret generic bluecat-token \
--from-literal=token='YOUR_BLUECAT_TOKEN'Create a secret for custom CA bundle:
kubectl -n cert-manager create secret generic bluecat-ca \
--from-file=ca.crt=./bluecat-ca.pemNamespace rules:
- For
Issuer, the secret must be in the same namespace as theIssuer. - For
ClusterIssuer, the secret must be in cert-manager's cluster resource namespace (typicallycert-manager).
apiVersion: cert-manager.io/v1
kind: ClusterIssuer
metadata:
name: letsencrypt-bluecat
spec:
acme:
email: [email protected]
server: https://acme-v02.api.letsencrypt.org/directory
privateKeySecretRef:
name: letsencrypt-bluecat-account-key
solvers:
- dns01:
webhook:
groupName: acme.bluecat.yourdomain.tld
solverName: bluecat-address-manager
config:
apiHost: https://bam.example.internal
apiPath: /api/v2
view: internal
zone: example.com
ttl: 120
quickDeploy: true
username: cert-manager
passwordSecretRef:
name: bluecat-auth
key: password
# Optional custom CA:
# caBundleSecretRef:
# name: bluecat-ca
# key: ca.crtapiVersion: cert-manager.io/v1
kind: Certificate
metadata:
name: app-example-com
namespace: default
spec:
secretName: app-example-com-tls
issuerRef:
name: letsencrypt-bluecat
kind: ClusterIssuer
dnsNames:
- app.example.comkubectl get apiservice | grep acme.bluecat.yourdomain.tld
kubectl -n cert-manager get deploy,po | grep cert-manager-webhook-bluecat
kubectl -n cert-manager logs deploy/cert-manager-webhook-bluecat
kubectl get challenges -A
kubectl get orders -Ano such hostor timeout to BlueCat:- check
apiHost, network policies, and DNS resolution from webhook pod.
- check
- TLS errors to BlueCat:
- provide
caBundleSecretRefor correct server certificate chain.
- provide
secret ... not found:- verify secret namespace and key names.
- zone not found:
- set
zoneID, or setzone+viewexplicitly.
- set
- challenge stuck in pending:
- inspect webhook pod logs and
Challengeevents.
- inspect webhook pod logs and
Unit tests:
go test ./...Integration conformance tests are tagged:
go test -tags=integration .The integration test requires kubebuilder test assets (etcd, kube-apiserver,
kubectl) and environment variables used by cert-manager's test harness.
