10

I'm trying to use Key Vault references in my Azure Function (v1) as described here. It works fine for secrets, but not for certificates.

The docs don't mention certs at all, so maybe they are simply not supported? I was hoping to get it as a base64 string.

Example app setting I'm using: @Microsoft.KeyVault(SecretUri=https://myvault.vault.azure.net/certificates/ApiClientAuthenticationCertificate/f9580a1f5a0c4a6ca65ea089976ca2b0)

Thomas Kappler
  • 3,795
  • 1
  • 22
  • 21

2 Answers2

12

Turns out the cert is available under the /secrets path. My example above should look like this: @Microsoft.KeyVault(SecretUri=https://myvault.vault.azure.net/secrets/ApiClientAuthenticationCertificate/f9580a1f5a0c4a6ca65ea089976ca2b0).

Then, the setting value will be a base64 string of the cert in PFX format. Instantiate like so in your Azure Function:

byte[] certBytes = Convert.FromBase64String(base64Pfx);
var cert = new X509Certificate2();
cert.Import(certBytes, String.Empty, X509KeyStorageFlags.MachineKeySet);
Thomas Kappler
  • 3,795
  • 1
  • 22
  • 21
  • 1
    Will this work for a local development(config in local.settings.json)? – cameron Apr 28 '20 at 10:14
  • @cameron No, local development do not has access to Azure Key Vault because the managed identity is only available once is hosted in Azure. For local development read the data directly from the PFX file using the certificate's Import function. To know if I'm executing locally or in Azure cloud, I use a simple configuration value (like "ExecutionEnvironment"="cloud" or "local") – Luis Art Guerra Nov 23 '20 at 03:38
4

I'm using a self-signed certificate for connection to SharePoint using Application Permissions.

The reference to the Key Vault value in the configuration is set as this:

@Microsoft.KeyVault(SecretUri=https://keyvaultname.vault.azure.net/certificates/NameOfMyCertificate/id)

The secret Uri is easily obtained from the Key Vault. It is called Certificate Identifier, and is located in the properties of the certificate in Azure Key Vault.

For the Azure Function to be able to access the certificate in Key Vault, it should have a managed identity activated and a proper access policy to Get Certificates.

The value that is loaded in the configuration variable is indeed a base64 string. The code I used to load the certificate is as follows:

public static X509Certificate2 ReadCertificateFromBase64StringPfx(string base64Pfx)
    {
        byte[] certBytes = Convert.FromBase64String(base64Pfx);
        X509Certificate2Collection collection = new X509Certificate2Collection();
        collection.Import(certBytes, string.Empty, X509KeyStorageFlags.PersistKeySet);
        return collection[0];  
    }

If you have more than one certificate in the PFX, you will need to change the return value and select the proper certificate from the collection.

NOTE: You must also add WEBSITE_LOAD_USER_PROFILE=1 in the configuration of your Azure Function, otherwise you will get an error stating that Import function was unable to find the file. Check this source.

Luis Art Guerra
  • 354
  • 2
  • 12