Certify allows easy automatic certificate distribution and maintenance.
Certificates are requested as TLS connections
are made, courtesy of the GetCertificate
and GetClientCertificate
tls.Config
hooks. Certificates are optionally cached. Simultaneous requests
are deduplicated to minimize pressure on issuers.
Are you using Certify and want to be visible here? Open an issue!
Certify exposes an Issuer
interface which is used to allow switching
between issuer backends.
Currently implemented issuers:
- Vault PKI Secrets Engine
- Cloudflare CFSSL Certificate Authority
- AWS Certificate Manager Private Certificate Authority
Create an issuer:
issuer := &vault.Issuer{
URL: &url.URL{
Scheme: "https",
Host: "my-local-vault-instance.com",
},
Token: "myVaultToken",
Role: "myVaultRole",
}
Create a Certify:
c := &certify.Certify{
// Used when request client-side certificates and
// added to SANs or IPSANs depending on format.
CommonName: "MyServer.com",
Issuer: issuer,
// It is recommended to use a cache.
Cache: certify.NewMemCache(),
// It is recommended to set RenewBefore.
// Refresh cached certificates when < 24H left before expiry.
RenewBefore: 24*time.Hour,
}
Use in your TLS Config:
tlsConfig := &tls.Config{
GetCertificate: c.GetCertificate,
}
That's it! Both server-side and client-side certificates can be generated:
tlsConfig := &tls.Config{
GetClientCertificate: c.GetClientCertificate,
}
For an end-to-end example using gRPC with mutual TLS authentication, see the Vault tests.
Certify hooks into the GetCertificate
and GetClientCertificate
methods of
the Go TLS stack Config
struct. These get called when the server/client
respectively is required to present its certificate. If possible, this is
fetched from the cache, based on the requested server name. If not, a new
certificate is issued with the requested server name present. For client
requests, the configured CommonName
is used.
My presentation at the London HashiCorp meetup has more information: