
gibcert
An awesome declarative TLS certificate manager.
gibcert is an awesome declarative TLS certificate manager. It lets you issue certificates from ACME or a local CA, automate certificate deployment, automate DANE, handle renewals and revocations, and more. It is a declarative tool, meaning you write what you want in a configuration file, review the pending changes, and then apply them. No more --issue -d example.com -d www.example.com --challenge-type dns-01 blah blah blah, we're not cavemen.
Why does this exist?
An ACME client is a pretty important tool for a sysadmin if you are doing things related to TLS, but so many ACME clients have little to no thought put into them and are taped together with hopes and dreams. I won't name them, but the ones I've tried have a number of issues like bad (or no) plugin system, bad CLI design and horrible ergonomics, absolute spaghetti unmaintainable code, and... RCE's, somehow. This is why gibcert was born, as a portable and declarative certificate management tool, inspired by OpenBSD acme-client and IaC tools like Terraform, DNSControl, and so on.
Features
ACME
- HTTP-01, DNS-01, TLS-ALPN-01, and dns-persist-01 challenges
- Built-in CA profiles: Let's Encrypt, ZeroSSL, Google Trust Services, Buypass, SSL.com
- ACME Renewal Information (ARI): server-driven renewal scheduling
- ACME profiles: request specific certificate types where supported
- IP identifier support
- CA failover: automatic fallback to alternate issuers during outages or rate-limits
- DNS-01 providers: manual, RFC 2136/nsupdate, PowerDNS out of the box
- External DNS: install a gibdns provider (Cloudflare, deSEC, Gcore, or your own) and point
commandat it - DNS alias mode: keep API tokens scoped to a separate delegated zone
- Standalone HTTP-01 and TLS-ALPN-01 listeners when no external web server is available
- dns-persist-01 with accounturi, issuer-domain-names, wildcard policy, and persistUntil
DANE / TLSA
- Automatic TLSA record publication and rotation with safe pre-staging across renewals
Operations
- Atomic deployment of cert, chain, fullchain, and key files with strict mode enforcement
- Deploy hooks for reloading services after changed material is installed
- Native remote deployment over SSH: install certificates on other hosts with the same staging, rollback, and hooks (
docs/remote-deploy.md) - Certificate dependencies: sequence issuance across certs that rely on each other
- Renewal and deploy groups: share settings and template deploy paths across certs
- Plan mode: inspect every pending account, certificate, deploy, and hook action before committing
- Prune: review and remove stale certificates, accounts, local CAs, and old account key archives with a dry run and per-item exceptions
- Account deactivation: retire ACME accounts at the CA, on their own or as part of prune
- Local CA support for private certificates
Portability
- Single static binary, one single dependency (statically linked)
- Runs on Linux, macOS, BSDs, Windows, Plan 9/9front, Illumos, and Solaris
Showcase
Here is a minimal example of a configuration that issues certs for example.com and www.example.com from Let's Encrypt:
challenge http-01 {
webroot /var/www/acme-challenge
}
certificate example.com {
account letsencrypt
names example.com www.example.com
deploy nginx {
fullchain /etc/nginx/tls/example.com/fullchain.pem
key /etc/nginx/tls/example.com/privkey.pem
after "systemctl reload nginx"
}
}
Before you do anything, you can check what is about to be created or changed with:
gibcert plan
If you want to be super careful, you can also check your config's syntax for errors without showing the pending changes:
gibcert check
And once you are ready to make those changes, you can run:
gibcert apply
Cool, right?