DEV Community

Cover image for Securing Sensitive Information in Polyglot Notebooks
M. James Harmon
M. James Harmon

Posted on

Securing Sensitive Information in Polyglot Notebooks

First, let's tackle the most important question – why did the cat refuse to store its password in Git? Because it heard it's a cat-astrophic idea and wanted to keep its purr-sonal information safe! Jokes aside, the leaking of sensitive information through GitHub and other source repositories is no laughing matter.

TLDR; take me to the code!

The scale of the problem related to the accidental exposure of passwords, API keys, credentials, and other sensitive information on public GitHub repositories is challenging to gauge but remains a significant concern. GitHub addressed this issue by introducing a secret scanning service several years ago. Unfortunately, each year brings reports of significant information breaches originating from source repositories. As an illustration, in 2023, AI researchers from Microsoft inadvertently disclosed over 32TB of data, including confidential information, by committing it to a publicly accessible source repository.

Despite the existence of long-standing best practices, interactive coding tools like notebooks raise some unique concerns. When working in notebooks, one might find themselves in the informal atmosphere reminiscent of a lone graduate student hastily crafting solutions during late-night sessions, rather than engaging with code that has undergone rigorous engineering, testing, and scrutiny through formal code review processes. While the user-friendly nature of notebooks makes them an enjoyable and practical tool, it is precisely this informality that introduces the risk of inadvertently exposing sensitive information.

Developers utilizing .NET have long benefitted from a handy tool called User Secrets. This tool serves the purpose of relocating sensitive information, such as API keys, entirely out of the code project. Instead, the information undergoes encryption and is securely stored in a designated user-level directory. .NET developers can programmatically access this information through the utilization of the special project (.csproj) file in conjunction with the Configuration extensions library.

Harnessing User Secrets in Polyglot Notebooks is surprisingly straightforward, even if it may not be immediately evident. Typically, Polyglot Notebooks aren't paired with the formality of being an integral part of an actual .NET project—a prerequisite for utilizing User Secrets. Although it's feasible to integrate them into a formal project following established development practices, for simplicity and to align with a common user scenario, let's focus on the basics. We'll initiate a temporary project to set up user secrets and then guide you through the process of importing and utilizing them within Polyglot Notebooks.


What You Will Need

  • Proficiency with the command line
  • .NET 8.0 or a later version installed
  • Installation of the Polyglot Notebooks extension in Visual Studio Code

Create a project

Execute the following from the command line:

dotnet new console --name temporaryproject
Enter fullscreen mode Exit fullscreen mode

Initialize User Secrets

Run the following command from the command line:

dotnet user-secrets init
Enter fullscreen mode Exit fullscreen mode

Add Your Secrets

Now, include a client ID and an API key in the secrets file. Execute the following from the command line:

dotnet user-secrets set "ClientId" "1234567"
dotnet user-secrets set "ApiKey" "11992288337744665"
Enter fullscreen mode Exit fullscreen mode

Add the Unique ID To The Notebook

User Secrets generates a unique ID for each project. Open the project file and copy the value of the secrets ID into your notebook. In your preferred editor, locate the tag named UserSecretsId and copy its value:

<PropertyGroup>
    <TargetFramework>net8.0</TargetFramework>
    <RootNamespace>temporaryproject</RootNamespace>
    <ImplicitUsings>enable</ImplicitUsings>
    <Nullable>enable</Nullable>
    <UserSecretsId>7ffbd8ef-bb06-47e8-a5e1-9c3103773101</UserSecretsId>
  </PropertyGroup>
Enter fullscreen mode Exit fullscreen mode

Copy the value of UserSecretsId into your notebook:

string UserSecretsId = "7ffbd8ef-bb06-47e8-a5e1-9c3103773101";
Enter fullscreen mode Exit fullscreen mode

At this point, you have the option to either delete the temporary .csproj file or retain it for sharing and updating values as needed.

Create a POCO For the Secrets:

public class MyCredentials {

  public string ClientId {get; set;} = string.Empty;

  public string ApiKey {get; set;} = string.Empty;
}
Enter fullscreen mode Exit fullscreen mode

Import the Secrets Into the Notebook

To access the secrets, use a ConfigurationBuilder with User Secrets enabled. Start by adding the necessary packages to your notebook and include the using statements to import into your code:

#r "nuget: Microsoft.Extensions.Configuration"
#r "nuget: Microsoft.Extensions.Configuration.Binder"
#r "nuget: Microsoft.Extensions.Configuration.UserSecrets"

using Microsoft.Extensions.Configuration;
Enter fullscreen mode Exit fullscreen mode

Create a ConfigurationBuilder and load your secrets into an instance of MyCredentials:

var configuration = new ConfigurationBuilder().
  AddUserSecrets(UserSecretsId).
  Build();

var credentials = configuration.Get<MyCredentials>();
Enter fullscreen mode Exit fullscreen mode

That's it! You can find a working example in a notebook HERE.

Thanks for reading! If you have any questions or need further assistance, feel free to reach out.

Top comments (0)