Skip to content

Instantly share code, notes, and snippets.

@zachfi
Created May 22, 2020 19:51
Show Gist options
  • Save zachfi/1d106a7ce41b511e96d7c7c15bd1653a to your computer and use it in GitHub Desktop.
Save zachfi/1d106a7ce41b511e96d7c7c15bd1653a to your computer and use it in GitHub Desktop.
vault + certify getting started
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,
	}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment