7

Maybe there is an answer to my question already but I was not able to find it after a long time searching.

My use case is the following: I have one ASP.Net Core 3.1 web application. It uses MSSQL database to store some information (just FYI I don't store any users' secrets, but still the information is valuable for me). It also uses an email client to send emails. I need to store the connection string for the database and also the credentials for the email client. So far I was storing them in the appsettings.json file until I realized that they are stored in plain text and if somebody access them he/she will have access to my database and my email client.

Now I am looking for a way to more securely store them. After reading questions in SO I came to understanding that the suggest way for storing such information is by using the Azure Key Vault. I can use it and I started updating my application to work with it (I read that I can access it outside Azure). But I came to realize that I need to store somewhere the Vault URL, ClientID and ClientSecret values.

How can I store them. In one of the tutorials they had them in the appsettings.json file but they said that this is not a good approach for a production, which is understandable. Suggested option was to store them in environment variables. But here comes my problem - I am hosting on a shared server and I can't add any environment variables. So usage of environment variables is not an option for me.

In my case, when I can't add any environment variables what would be the best approach to store any production secrets like the database connection string? Is the Azure Key Vault still a valid and a good option? Should I consider keeping them in the appsetting.json and encrypting that file? Or maybe there is another better approach?

It is only me who is developing the app plus I don't store it in any public GitHub repo or anything.

PS: Here is a link to a tutorial I was looking at:Using Azure Key Vault From A Non-Azure App

Thanks.

EDIT: Here is one tutorial which I find useful on how to Use Azure Key Vault With Certificate Outside of Azure

Xequtor
  • 125
  • 1
  • 12
  • 2
    You are on right path. Storing secrets in Azure Keyvault is the recommended approach. However to get authorized access to KeyVault, you would need the credentials like ClientId and Secret or Certificate. So the question is where to store those secrets to access the KeyVault for the actual secrets! :). Now if you were in Azure host like for example Azure Web App or VM, I could straightaway recommend Managed Identity https://docs.microsoft.com/en-us/azure/key-vault/general/tutorial-net-create-vault-azure-web-app where you would not have to maintain the credentials in App..(Contd in next comment) – krishg Aug 24 '20 at 19:25
  • 1
    But since you mentioned, it's a non-Azure host, I would like to know more about that to give you a good solution. What is the host? VM, 3rd party hosting? Or? – krishg Aug 24 '20 at 19:25
  • @KrishnenduGhosh-MSFT: I am using 3rd party hosting - https://www.smarterasp.net/ I asked them about setting environment variables and they told me it is not possible since the server is shared. – Xequtor Aug 25 '20 at 05:42
  • 1
    In that case, do they have "bring your own certificate" support? You could authenticate to keyvault using ClientId and Certificate (recommended) instead of Secret if they support certificate installation. https://learn.microsoft.com/en-us/azure/key-vault/general/authentication#tutorial – krishg Aug 25 '20 at 07:15
  • @KrishnenduGhosh-MSFT I asked the server support but they don't know how is this done and if it is even possible. Is there any article, which describes how this is done? They ask me if I need to change any configurations in the server. The provided link is very well explaining, but the example is with a .pem file. Is this file somehow installed on the server? How is it then accessed? – Xequtor Aug 26 '20 at 17:05
  • 1
    even if the example has pem format file (it used self-signed certificate just as an example using openssl tool), it can work with pfx format too...basically an x509 certificate https://www.ssl.com/faqs/what-is-an-x-509-certificate/ having client authentication extension. Yes it should be installed in the server and C# code should be like https://www.c-sharpcorner.com/article/accessing-azure-key-vaults-using-certification/ (towards the end of this article) – krishg Aug 26 '20 at 17:13
  • I sent that link to the customer support. Hopefully they will understand it. In case they don't support it, then I have no other option but to store the secrets on my side, right? Maybe I should think of encrypting the appsetting.json file or some other technique? – Xequtor Aug 27 '20 at 05:53
  • 1
    Yeah if they don't support, you can authenticate to keyvault using client id and secret. You can store it in appsettings.json and encrypt, but then where would you store the encryption key? – krishg Aug 27 '20 at 05:57
  • Yeah, that is the other problem. What if it is in the source code? It can get compromised only if somebody gets access to my control panel and download the .dll files (and if somebody get that access, my issues will be bigger than just storing some secrets and keys). Usually I keep the source code only on a local server, where I am the only one who has access. Is it possible for somebody to get my .dll files and appsettings.json from outside, without gaining access to the control panel? – Xequtor Aug 27 '20 at 06:18
  • That totally depends on how secure your hosting provider is :) – krishg Aug 27 '20 at 06:44
  • 1
    @KrishnenduGhosh-MSFT: Some updates from my side. I already have one SSL certificate installed on my hosting. I exported it, created .cert file, added that file to Azure and from my local PC I was able to connect to the Key Vault and obtain some secrets from it. Now when I uploaded the application to my hosting I have issues. Seems that they are blocking the access to outside services. I have the option to add some IPs and ports to a whitelist. I did it, but still I have issues. I will check today evening and can provide more details. – Xequtor Sep 02 '20 at 08:18
  • there might be issue related to reading from cert store also (like whether you are reading from Machine or User scope)..check the actual exception log.. – krishg Sep 02 '20 at 08:29
  • @KrishnenduGhosh-MSFT: They had to give some access to the certificate. Now everything works as expected. Thank you veeeery much. You really helped me a lot. You can convert your comments to an answer which I can accept and close this question. – Xequtor Sep 02 '20 at 13:02
  • 1
    Great :). Posted the summarized answer. – krishg Sep 02 '20 at 13:12

2 Answers2

3

Two things:

1-You should store the secrets in Azure Key Vault. As you already noticed, it will provide an URL that will be used to retrieve the secret from Key Vault.

2-Only allowed services will be able to retrieve the secrets. What you need to do is create a manage identity to you web apps, then grant access to GET / LIST secrets from Key Vault to this Managed Identity.

here's a step by step:

https://learn.microsoft.com/en-us/azure/key-vault/general/tutorial-net-create-vault-azure-web-app

Thiago Custodio
  • 17,332
  • 6
  • 45
  • 90
  • Can this Managed Identity be used by applications, that are not hosted on Azure? My application is on another host. I think the link you provided is for applications, hosted on Azure or isn't it? – Xequtor Aug 25 '20 at 05:46
  • no, managed identities are valid only for Azure apps – Thiago Custodio Aug 25 '20 at 14:40
2

(Summarizing the discussion and resolution as Answer)

Storing secrets in Azure Keyvault is the recommended approach. However to get authorized access to KeyVault, you would need the credentials like ClientId and Secret or Certificate. So the question is where to store those secrets to access the KeyVault for the actual secrets! :). Now if you were in Azure host like for example Azure Web App or VM, I could straightaway recommend Managed Identity where you would not have to maintain the credentials in App, but since you mentioned it's a non-Azure host, I would suggest to go via Certificate authentication since Secret based auth would need you store the secret somewhere in config/environmental variable which is not a good idea. Also make sure that only your app has access to that certificate in the host.

As now you coordinated with your hosting vendor to configure certificate and things are working, I hope it helped. Thanks.

krishg
  • 5,935
  • 2
  • 12
  • 19