2

With Hashicorp's Vault, is it possbile to generate a secret without revealing that secret to the user who generated it?

Along the lines of:

vault generate secret/my/awesome/secret 32

Where it would generate a string of 32 random characters, will store that in Vault, and will not show the resulting value to the user who created it without them without them explicitly requesting it with a

vault kv get

operation?

After a quick reading the Vault docs I was sure this would be possible but now that I've gone looking for details about how to do it I'm finding so little info that I'm not sure it's possible [yet].

Jeff Welling
  • 402
  • 1
  • 4
  • 11

1 Answers1

4

It's tempting to ask what is your exact use case... But here is a straighforward way to store 32 random alphanumeric (I presume) characters in Vault.

vault write secret/my/awesome/secret - << EOF
{ "key":"$(< /dev/urandom tr -dc A-Za-z0-9 | head -c${1:-32};echo;)" }
EOF

Reading the characters back is standard K/V operation:

$ vault read --field=key secret/my/awesome/secret
FA9hxKMejhKyRHVAclPQbNWaLFDPUMky

The problem with this approach is that it uses a Linux "here file", so the random characters are generated by the user, not Vault. Even though the user can't see it, that could be a problem. A malicious user could write a well known string instead of a random one. Pedantic readers could also argue that Vault and openssl entropy could be different.

If you want Vault to generate the characters without the user beign involed, you will have to forget about printable characters. Vault has top notch cryptography and there is no way to restrict its randomness to a set of printable ASCII. There are various ways to produce base64 encoded output, but it base 64 has some patterns in it that will lower the (already low) entropy of the generated string.

But if pure randomness is ok with you, then you could abuse the features of the transit secret backend. First enable it:

vault secrets enable transit

Ask Vault to generate a key and keep it for itself, forever. I named that key serverfault:

vault write --force transit/keys/serverfault

Now that you have a key, produce a Seinfeld hash (a hash about nothing) using an algorithm that happens to produce 32 bytes. The second line (cut|openssl|xxd) is only for pretty printing, adjust to your taste:

vault write --field=hmac transit/hmac/serverfault algorithm=sha2-256 input=AAAA \
   | cut -d: -f3 | openssl base64 -d -A | xxd

00000000: d2e5 8e43 bed4 13be 4488 1823 457b 4575  ...C....D..#E{Eu
00000010: 3030 8059 198e 669a bdaa cbb6 d4e7 8130  00.Y..f........0

Try it a few times, you will always get the same output back. To get a new, completely random value, simply change the HMAC key:

vault write --force transit/keys/serverfault/rotate

The command to get random bytes now produces a new value:

vault write --field=hmac transit/hmac/serverfault algorithm=sha2-256 input=AAAA \
   | cut -d: -f3 | openssl base64 -d -A | xxd

00000000: d2e5 8e43 bed4 13be 4488 1823 457b 4575  ...C....D..#E{Eu
00000010: 3030 8059 198e 669a bdaa cbb6 d4e7 8130  00.Y..f........0

This method also allows you to create more than one key (named production and test for example) and set diferent policies on each path, so that not all users will be allowed to change the random value (aka rotate the key).

ixe013
  • 928
  • 2
  • 7
  • 25