export VAULT_CACERT=/usr/local/etc/ssl/ca.pem
export VAULT_ADDR=https://vault0.example.com:8200
First setup the PKI
vault write pki/root/generate/internal common_name=example.com ttl=8760h
vault write pki/roles/example allowed_domains=example.com allow_subdomains=true max_ttl=72h
vault secrets tune -max-lease-ttl=87600h pki
vault write pki/config/urls issuing_certificates="https://vault0.example.com:8200/v1/pki/ca" crl_distribution_points="https://vault0.example.com:8200/v1/pki/crl"
Then create a policy
path "pki/issue/*" {
capabilities = ["create", "update"]
}
path "pki/sign/*" {
capabilities = ["create", "update"]
}
path "pki/certs" {
capabilities = ["list"]
}
path "pki/revoke" {
capabilities = ["create", "update"]
}
path "pki/tidy" {
capabilities = ["create", "update"]
}
path "pki/cert/ca" {
capabilities = ["read"]
}
path "auth/token/renew" {
capabilities = ["update"]
}
path "auth/token/renew-self" {
capabilities = ["update"]
}
And write it
vault policy write pki pki.hcl
Apply the policy to whatever auth method you plan to use. For example, to allow TLS certificates from a different CA, something like the following.
vault write auth/cert/certs/other \
display_name=other \
policies=pki \
certificate=@/usr/local/etc/ssl/ca.pem \
ttl=3600
vault login -method=cert -ca-cert=/usr/local/etc/ssl/ca.pem -client-cert=/var/puppet/ssl/certs/server1.testing.com.pem -client-key=/var/puppet/ssl/private_keys/server1.testing.com.pem -address=https://vault0.example.com:8200
Now tokens that have the pki
policy assigned will be able to retrieve TLS
certificates from vault for the domain example.com
.
Once you've got a token, in Go, we can load the token, and set it to renew to automate the process.
client, err := api.NewClient(apiConfig)
token, err := ioutil.ReadFile(vaultConfig.TokenPath)
authMethod := &vault.RenewingToken{
Initial: string(token),
RenewBefore: 15 * time.Minute,
TimeToLive: 24 * time.Hour,
}
// calling SetToken here kick starts the autorenew processes
err = authMethod.SetToken(context.Background(), client)
Then use certify.Certify
as mentioned in the docs.
c := &certify.Certify{
// Used when request client-side certificates and
// added to SANs or IPSANs depending on format.
CommonName: tlsConfig.CN,
Issuer: issuer,
// It is recommended to use a cache.
Cache: certify.NewMemCache(),
CertConfig: &cfg,
// It is recommended to set RenewBefore.
// Refresh cached certificates when < 24H left before expiry.
RenewBefore: 24 * time.Hour,
Logger: logrusadapter.New(logger),
IssueTimeout: 15 * time.Second,
}