Thursday, June 4, 2015

Using SecretManager in ASP.NET5 application

In today's blog post, I will be discussing how to use SecretManager to store secrets in an ASP.NET 5 web application. 

Earlier, we used to store our passwords or other secret information in config file. The secret information could be your database connection passwords or OAuth related shared secrets. It's very easy to send your config file to another team mate or by mistake check it in into source control which could some times be even public. Such a mistake could be a major security problem and increases the hassle for developers.

Secret Manager 

So instead of saving the secrets in config files, we can store them outside source control using Secret Manager. To begin with, let's take a look at Startup.cs inside our ASP.NET5 web application.
Here, we have:

public Startup(IHostingEnvironment env)

{

       // Setup configuration sources.

       var configuration = new Configuration()

           .AddJsonFile("config.json")

          .AddJsonFile($"config.{env.EnvironmentName}.json", 
           optional: true);



       if (env.IsEnvironment("Development"))

       {

       // This reads the configuration keys 
        //from the secret store.

          configuration.AddUserSecrets();

       }

       configuration.AddEnvironmentVariables();

       Configuration = configuration;

   } 


So here what it says is that the configuration information is first retrieved from config.json. If we are in debug environment (e.g. env.EnvironmentName = "debug") and we have same key in config.debug.json then the value in config.debug.json will override the value in config.json. Similarly, if we have the same key in environment variables, then that value will be used and all others will be ignored. The value added last, will override the previous values.

Here, we also have configuration.AddUserSecrets() which adds the config values from Secret Manager. The User Secrets configuration system consists of two parts: i) Global Tool and, ii) Configuration Source.

 In order to install global tool, in my command prompt, I first ran:

 dnu commands install SecretManager


And I got an output like this:

The following commands were installed: user-secret

The second part, Configuration Source is already set up by configuration.AddUserSecrets()

Now we are all set, we can add our secrets to the secret manager and use them in our application.

Last week, I posted on how to set up Facebook authentication in ASP.NET5 application here. In that project, I added the Facebook AppId and Facebook AppSecret to my config.json directly. Now, I want to add them to Secret Manager and use them in my application.

So inside Visual Studio 2015RC, Package Manager Console I was able to add my AppId and AppSecret to SecretManager like this:

user-secret set Authentication:Facebook:AppId 8xxxxxxxxxxx

user-secret set Authentication:Facebook:AppSecret dxxxxxxx


Now, behind the scenes, they were stored in

%APPDATA%\Microsoft\UserSecrets\aspnet5-TestAuth-axxxxxxxxxxxxxxxxxx\secrets.json

 and APPDATA value was:

 C:\Users\<username>\AppData\Roaming

The AppData folder is hidden by default. I was able to see the file contents and even manually edit them if needed. In future, the secrets.json file content might be encrypted.

How to Use

Now I can simply use them in my application

Configuration["Authentication:Facebook:AppId"];

Configuration["Authentication:Facebook:AppSecret"];


In this way, I was able to store the secrets in a separate folder outside source control. I can set them once per environment and I don't need to worry about accidentally checking them in my source control.

Conclusion

So we saw how to use SecretManager to store secret information in ASP.NET5 application without worrying about accidentally checking them into source control. I think that its a nice addition to developers' arsenal.
For future updates to my weekly blog, please subscribe to my blog via the "Subscribe By Email" feature at the right and follow me on Twitter. Until then Happy Coding :)


10 comments:

  1. This is a great thing to control outside source through secret manager. I will definitely use this secret manager to perform this activity. iOS Event Apps

    ReplyDelete
  2. Are these user-secrets only for development?
    What happens when you deploy this application with external login providers like Facebook, Google or Twitter to a hosting provider running IIS 7.5?
    This application still needs the user-secrets in the production environment.
    Without them you will get an ERROR 500.
    Who stores the application secrets in the hosting server?

    ReplyDelete
    Replies
    1. Yes, it will need the user-secrets - whether you are in development or production. It's just how u store it on the machine... Depending on how your production environment is setup, you will have to put the secrets on that machine too. It just gives you a way to store it on the machine outside the source control so you don't publish it unintentionally.

      Delete
    2. This comment has been removed by the author.

      Delete
    3. Thanks for your reply
      OK. This sounds simple.
      Can you try this out on a production environment and document it in this article...
      I'm eager to see how it works.
      One more thing though. What happens with the user-secrets when the production environment is at a hosting provider where you don't have the rights to access the file system and definitely not can run the Secret Manager.

      Delete
    4. Hi Brendt, We haven't started using ASP.NET5 in production yet. I will post about the experience once we do that.

      Delete
    5. OK Abhi
      Thank´s for your time.
      I'm waiting .......
      regards Berndt

      Delete
  3. Hi Abhi,
    Really great post about .Net Training.

    ReplyDelete
  4. Does this work on Azure? seeming that a local path is used, is this something that is Azure aware?

    ReplyDelete
  5. Hi Jan Van Rosmalen,
    Thanks for asking that question. There are ways to deploy the secrets to Azure through Azure Management Portal. I will cover that in a future post. Thanks

    ReplyDelete