TraGicCode / tragiccode-azure_key_vault

Pull secrets from Azure's key vault with this puppet module.
Apache License 2.0
6 stars 16 forks source link

Retrieve the certificates from key vault ? #54

Closed ngeegoh closed 3 years ago

ngeegoh commented 5 years ago

Hi,

Just wondering if this puppet module has the ability to retrieve the certificates from the key vault similar to how it retrieves secrets from the vault? Since key vault not only stores secrets, it also stores certificates, if it got this ability, it would be awesome to add in the puppet manifest to get and install certificates from the key vault.

Thanks.

TraGicCode commented 5 years ago

Hey @ngeegoh ,

I went and looked at some azure key vault certificates and it looks like they should be able to be retrieved perfectly fine as it looks like certificates are "under-the-covers" stored as a secret.

Can you try out the following puppet code:

file { 'C:\\DataForApplication.secret':
  content   => base64('decode', azure_key_vault::secret('production-vault', 'certificate-name', {
    metadata_api_version => '2018-04-02',
    vault_api_version    => '2016-10-01',
  })),
  ensure    => file,
}

NOTE: base64() function comes from puppetlabs-stdlib

That should return the PFX certificate from the vault. Let me know if this works so i can update the documentation.

ngeegoh commented 5 years ago

Hi @TraGicCode ,

I got this "AccessDenied" error when I tried to run: $secret = azure_key_vault::secret('puppetkeyvaulttesting', 'password', { metadata_api_version => '2018-04-02', vault_api_version => '2016-10-01', }) (Just wanna test out some basic stuff first before trying to get the certificates) ERROR: Error: Evaluation Error: Error while evaluating a Function Call, {"error":{"code":"Forbidden","message":"Access denied","innererror":{"code":"AccessDenied"}}} at C:/ProgramData/PuppetLabs/code/environments/production/manifests/test.pp:8:33 on node puppetserver

What I have done:

Everything seems alright, but I don't know what I have missed out that caused the access denied error when I tried to retrieve the password from the key vault.

Thanks,

ngeegoh commented 5 years ago

Hi @TraGicCode ,

Please ignore the above error since I have figured out what was wrong and fixed it. The problem was in the access policy, I set the Authorized application for my VM which somehow could not grant the access permission for my VM to the key vault. The solution was to remove the access policy and re-add without setting the authorised application.

In regards to the main topic, I have run your puppet code trying to retrieve and download the certificate but failed with this error: Error: Evaluation Error: Error while evaluating a Function Call, base64(): the second argument must be a string to base64 at C:/ProgramData/PuppetLabs/code/environments/production/manifests/test.pp:9:16 on node puppetserver

I have actually removed the base64(), and it worked, but the result was not quite right. This is what I have changed. I changed specified the pfx file name instead of keeping C:\DataForApplication.secret as default since it DID NOT download the pfx certificate file. The output looks alright as now I can see the pfx file stored in the destination directory, but the file itself is not the same as the certificate stored in the key vault (it just has the same name as the certificate but the certificate is not working).

file { 'C:/tmp/dev.com_2018-2020.pfx' 
  content   => azure_key_vault::secret('puppetkeyvaulttesting', 'dev-cert', {
    metadata_api_version => '2018-04-02',
    vault_api_version    => '2016-10-01',
  }),
  ensure    => file,
}

Have you got any ideas about this issue? would be awesome if we could get/ download the genuine certificate from the key vault?

Cheers,

TraGicCode commented 5 years ago

Hey @ngeegoh ,

The certificate is base64 encoded. Are you able to connect to that machine and manually base64 decode the certificate, rename the file to .pfx and see if it is working correctly?

ngeegoh commented 5 years ago

Hi @TraGicCode ,

I have manually decoded the secret file and then renamed it to .pfx, but the certificate is still not working correctly (I tested it by putting the password to open the certificate but it couldn't read the password).

This is the PS command I used to decode it, it was successfully executed and outputted the file certutil -decode DataForApplication.secret dev.com_2018-2020.pfx

TraGicCode commented 5 years ago

Hey @ngeegoh ,

I did some more looking around and it looks like there might be some manipulation that has to happen ( typically via powershell ) before it's a pfx complete which is unfortunate.

I'm currently working on a big project at the moment so i cannot really spend the time to implement this feature.

If you want we could start discussing what that implementation might look like and document that all in this github issue and you, another person, or myself in the future can do the required work to implement this feature.

ngeegoh commented 5 years ago

Hi @TraGicCode ,

That would be great if we could document that issue to work on later. Should I raise another github issue in regard to this problem? As I think this is the only puppet module that has the potential to retrieve certificates from Azure, apart from this there is like no other way to get the certs easily.

In the meantime, what implementation might look like for this issue? so I could look into it to see if it is an easy or difficult fix, although my development skill is not great.

Cheers,

TraGicCode commented 5 years ago

Hey @ngeegoh,

I think we should do the following:

  1. Figure out how to retrieve a valid pfx certificate from azure key vault using the same mechanism to retrieve regular secrets . This module currently uses the ARM api to make an http call.

As from the comments above it looks like it’s possible but some munging might have to happen before it’s fully usable based on what u ran into and what I found online but we need to fully document what exact munging needs to happen.

  1. Once we figure out how to retrieve the certificate we then need to talk about How to implement it. Does it require a new puppet function? Can we reuse the existing one and does it need more parameters to handle the certificate use case?

  2. Implement the code and test it!

TraGicCode commented 5 years ago

Leaving this link here as it has links and even summaries how you can pull different parts of a key vault cert via rest api which this module utilizes

https://github.com/Azure/kubernetes-keyvault-flexvol#more-about-certificates

ngeegoh commented 5 years ago

Hi @TraGicCode ,

I have talked to my co-worker and tested your module again, your module actually worked and pulled down the certificate. I main reason I thought it wasn't working at the first place because after decoding the downloaded certificate manually, I was able to just install the .pfx cert WITHOUT the password (the one which is required to get access and install the cert) which I thought was supposed to be required. However, as told by my colleague, seems like downloading the cert from the keyvault has radiated the password and then we no longer need that password to install the cert.

This is what I have done to get the certificate, decode and install it, it works for me, so maybe worth documenting it somewhere.

$secret = azure_key_vault::secret('puppetkeyvaulttesting', "${name}", {
            metadata_api_version => '2018-04-02',
            vault_api_version    => '2016-10-01',
          })

  file { "C:/tmp/${filename}" :
    content   => base64('decode', "${secret.unwrap}"),
    ensure    => file,
  }

  sslcertificate { "Install-${name}-Certificate" :
    name       => "${filename}",
    location   => 'C:\tmp',
    root_store => 'LocalMachine',
    thumbprint => "${thumbprint}"
  }

I cannot decode directly the certificate as you suggested me at your initial comment on this issue, the issue was the decode() looks for a string, thats why i need to separate them. Anyway, thanks for your assistance :)

Cheers,

TraGicCode commented 5 years ago

Hey @ngeegoh that’s is great news. Thanks for the response. Let’s leave this open so I can create a pull request with documentation for pulling a cert!!