A HashiCorp Vault secrets plugin that provides automated SSL/TLS certificate management using Let's Encrypt and the ACME protocol. This plugin enables you to issue, renew, and manage certificates directly from Vault using DNS-01 challenges.
- ACME Account Management: Create and manage ACME accounts with automatic key generation
- Certificate Issuance: Automatically issue SSL/TLS certificates for domains using DNS-01 challenges
- Automatic Renewal: Certificates are automatically renewed when they approach expiration (30 days before expiry)
- DNS Provider Support: Supports all DNS providers available in the LEGO library
- Custom DNS Providers: Register custom DNS challenge providers
- Secure Storage: Account keys and certificates are stored securely in Vault's storage backend
- Multiple Accounts: Support for multiple ACME accounts with different configurations
- Environment Variable Support: Configure DNS provider credentials via environment variables per account
- HashiCorp Vault 1.0 or later
- Go 1.25.0 or later (for building from source)
- Access to a DNS provider that supports API-based DNS record management (for DNS-01 challenges)
- Clone the repository:
git clone https://github.com/playeveryware/vault-plugin-letsencrypt.git
cd vault-plugin-letsencrypt- Build the plugin:
go build -o vault-plugin-letsencrypt ./cmd/vault-plugin-letsencrypt- Register the plugin with Vault (see Vault Plugin Registration)
- Place the compiled plugin binary in a location accessible by Vault
- Calculate the SHA256 checksum:
sha256sum vault-plugin-letsencrypt- Register the plugin in Vault:
vault plugin register \
-sha256=<checksum> \
secret vault-plugin-letsencrypt- Enable the plugin:
vault secrets enable -path=letsencrypt vault-plugin-letsencryptThe plugin can be configured with the following options (if supported by your Vault version):
- Custom DNS resolvers
- TLS configuration
- Custom DNS provider registration
Create a new ACME account for certificate issuance:
vault write letsencrypt/accounts/myaccount \
email="admin@example.com" \
tos_agreed=true \
directory_url="https://acme-v02.api.letsencrypt.org/directory" \
key_type="EC256" \
dns_provider_env=CLOUDFLARE_API_TOKEN=your-cloudflare-dns-token \
dns_provider_env=LINODE_TOKEN=your-linode-dns-token \
dns_provider_env=DO_AUTH_TOKEN=your-digitalocean-dns-token \
;You can find the dns environment variable by inspecting the LEGO source code.
Start at https://github.com/go-acme/lego/blob/master/providers/dns, then locate your DNS provider.
For example, DigitalOcean > https://github.com/go-acme/lego/blob/master/providers/dns/digitalocean
// Environment variables names.
const (
envNamespace = "DO_"
EnvAuthToken = envNamespace + "AUTH_TOKEN"
EnvAPIUrl = envNamespace + "API_URL"
EnvTTL = envNamespace + "TTL"
EnvPropagationTimeout = envNamespace + "PROPAGATION_TIMEOUT"
EnvPollingInterval = envNamespace + "POLLING_INTERVAL"
EnvHTTPTimeout = envNamespace + "HTTP_TIMEOUT"
)The dns_provider_env in this case is DO_AUTH_TOKEN
Parameters:
email(required): Email address for the ACME accounttos_agreed(required): Set totrueto accept the Terms of Servicedirectory_url(optional): ACME directory URL (defaults to Let's Encrypt production)key_type(optional): Key type for the account key (EC256,EC384,RSA2048,RSA4096,RSA8192)dns_provider_env(optional): Key-value pairs of environment variables to set for DNS provider authentication
vault read letsencrypt/accounts/myaccountIssue or retrieve a certificate for a domain:
vault read letsencrypt/certs/dns-01/myaccount/cloudflare/example.comPath Format: certs/dns-01/{account}/{provider}/{fqdn}
account: The ACME account name to useprovider: The DNS provider name (e.g.,cloudflare,route53,gcloud, etc.)fqdn: The fully qualified domain name for the certificate
Response: The response includes:
certificate: PEM-encoded certificate chainprivate_key: PEM-encoded private key
The secret has a TTL set to expire 30 days before the certificate expires, ensuring automatic renewal.
The plugin supports all DNS providers available in the LEGO library, including:
- Cloudflare
- AWS Route53
- Google Cloud DNS
- Azure DNS
- DigitalOcean
- And many more...
See the LEGO DNS Providers documentation for a complete list and required environment variables.
vault delete letsencrypt/accounts/myaccountThis will deactivate the ACME account registration and remove it from Vault.
GET /accounts/{account}- Read account informationPOST /accounts/{account}- Create or update an accountDELETE /accounts/{account}- Delete an account
GET /certs/dns-01/{account}/{provider}/{fqdn}- Issue or retrieve a certificate
go test ./....
├── backend/ # Plugin backend implementation
│ ├── account.go # ACME account management
│ ├── cert.go # Certificate handling
│ ├── path_*.go # API endpoint handlers
│ └── ...
├── cmd/
│ └── vault-plugin-letsencrypt/
│ └── main.go # Plugin entry point
└── go.mod # Go module definition
- Account private keys are stored securely in Vault's storage backend
- Certificate private keys are returned as Vault secrets with appropriate TTLs
- DNS provider credentials are configured via the
dns_provider_envparameter when creating accounts; the plugin handles setting these environment variables internally during certificate issuance - Use Vault's access control policies to restrict access to accounts and certificates
- Consider using separate accounts for different environments (production, staging, etc.)
- Verify the ACME account exists and is properly registered
- Check that DNS provider credentials are correctly configured
- Ensure the DNS provider has API access enabled
- Verify DNS propagation is working for the domain
- Check Vault logs for detailed error messages
- Ensure the DNS provider API credentials have permissions to create TXT records
- Verify the domain is properly configured with the DNS provider
- Check that DNS propagation delays are accounted for (some providers may take time)
This project is licensed under the BSD 2-Clause License - see the LICENSE file for details.