CA private key from Vault CA

I’ve read through a few guides, I am trying to supply the Vault CA cert and private key to create a secret in Kubernetes as per this:

This shows how to generate said CA certificate:

However there is no mention of how to get the private key while generating the root ca cert nor the intermediate.
Commands such as this:

vault write -format=json pki/root/generate/internal \
 common_name="pki-ca-root" ttl=87600h | tee \
>(jq -r .data.certificate > ca.pem) \
>(jq -r .data.issuing_ca > issuing_ca.pem) \
>(jq -r .data.private_key > ca-key.pem)

Do not produce a key, only null.
The only time I can get private keys is when producing subdomain signed certs.
Does anyone know if it’s possible to get the root or intermediate key from a Vault CA?

Although you can use a Vault CA to generate a cert to use on Vault it isn’t as simple are you think it is.

Setting up the Vault CA is a lot more involved and needs to go through cross signing and Intermediate certs, etc… follow Build Your Own Certificate Authority (CA) | Vault - HashiCorp Learn

If you are going to use the Vault CA for other systems, then it’s worth it, if not then don’t waste time with it as it’ll be a beast to manage (any CA is). If you just need a cert for Vault then use openssl or letsencrypt to generate your cert depending on your situation.

Lastly, if you do want to use Vault CA, you have to setup and stand up your vault without an SSL, then setup CA/Intermediate, then generate your cert, then stop and reconfigure your Vault to use that cert.

I probably should have provided a bit more detail, I actually have an existing Vault in the cloud, which is the CA for our on-prem domain, I was looking to deploy a local Vault (not a CA) within our Kubernetes cluster using certificates from the cloud Vault CA (which provides many certs for our various applications with no issues).
It seems that Vault hides/consumes private keys on generation of root and intermediate certs, which hasn’t been an issue to this point, but since the setup of Vault in a Kubernetes environment requires a CA root private key along with the root cert, this is where the issue lies.
Perhaps the answer is to create a root cert and key from openssl and import this into the cloud vault somehow to use, instead of it generating it’s own.
Then proceed to use that cert and key for importing to any other vault installs that you need to stand up.

Then AFAIK you’re using the wrong engine to try to create your server cert. I know enough to be dangerous here, so take this with some salt:

I believe, you generate server certs from your PKI engine not your PK engine. At least that’s what I use and this works great.

# vault write pki-int/issue/<server-cert-role> ttl=${ttl} common_name="${common}" ${altNames} ip_sans="${ipSans}," -format=json > ${common}.certs.json"

Your ${common}.certs.json now contains your “certificate”, “private_key”, “issuing_ca”, “ca_chain” as well as your “serial_number” which you can use to track the cert in vault.

yes this is the way to issue certs for the various subdomains from the CA, sadly however it cannot issue the CA root certificate and key as I understand it.
This is what is required to be in the kubernetes secret as per the setup guide:

kubectl --namespace='vault' create secret tls vault-ca-crt --cert ./tls-ca.cert --key ./tls-ca.key

This provision of the CA root cert and key is what allows the new install of Vault to trust the certs produced further along for the cluster encrypted connections to support raft (or any other created certs by the original Vault CA)

I’m know even less about Kubernetes than I do about CA’s but from reading that command and what I have gleamed from other conversations, I think that’s actually importing your your CA cert into Kubernetes so that you can auto provision certs out of Kubernetes for your ingress(es).

Now if you have a cert (from Vault) and just need to assign it to an ingress, I believe this is what you need to do to import a cert into a kub secret so you can use it as on an ingress.

It’s never possible to get the private key out of PKI Certificate Authority. Nothing to do with Vault.

If you ever find yourself wanting to export the private key of a Certificate Authority, whatever make or model, you’re doing it wrong.

Your Vault CA could issue a subCA certificate to your Kubernetes cluster. You will end up with a two level PKI, a common practice but not every client is able to walk the chain, you might have to store Vault’s CA’s public key along with the Kubernetes subCA public key in your client’s various keystores.

I don’t think this is correct, it’s also bad policy to say “export” your key. I agree to be secure you don’t want to, or shouldn’t. but it’s certainly possible and can be done – the answer to that is you have to do when you generate your CA cert, after that it isn’t exportable anymore.

You can’t trust a key that’s going around. Once it is out, it’s out and it can’t be trusted. You could indeed export Vault’s private key, even import an existing key from some external system, but you get the trust that goes with a key that was seen outside the system: next to zero.

I’m told that Hashicorp is working on a HSM enabled PKI backend (beyond the current seal wrap) to enforce the “impossible to export” concept even further. The private key would never leave the HSM and the actual certificate signature would be done by the HSM, like many/most enterprise grade PKI already do.

That’s a fine argument of shouldn’t. But then you can’t say “Cannot”.

Hi @ixe013 appreciate the feedback and yes it makes perfect sense that we shouldn’t be exposing keys that aren’t meant to be exposed, clearly bad security practice.

This public key sounds interesting, in the guide for Vault on Kubernetes, it does not actually specify public or private CA key, just “For PEM encoded TLS Certs where you have the key:

So my next question then is, how do we obtain the public key from our Vault CA?
There is no mention in the tutorial on “Build your own CA” of exporting a key of any type, public or private.

google saves the day:

openssl x509 -pubkey -noout -in /root/ca/vault_root_ca.pem > pubkey.pem

I’ll go and test this and see if it works.

Looks like that is a no:
error: tls: failed to find PEM block with type ending in “PRIVATE KEY” in key input after skipping PEM blocks of the following types: [PUBLIC KEY]
Must be a private key.

There is a public endpoint for that in Vault, but you must use cURL for it (not vault read) because vault cli expects a JSON document.

curl $VAULT_ADDR/v1/pki/ca/pem --output vault-ca.pem

Of course your Linux configuration should already trust your CA :wink: . If not, add --insecure to the cURL command line.

If you need the DER (aka binary) version of the certficate, better to remove /pem at the end of the url instead of running the PEM through openssl.

curl $VAULT_ADDR/v1/pki/ca --output vault-ca.der