“Keep it secret. Keep it safe.” If you’ve worked in IT for any length of time you know those words apply to many things besides magic rings. Personally identifiable information (PII) and user secrets are at the top of the list of such items. When you’re developing .NET applications there are inevitably some magic strings, like API keys, you need to watch over in all the realms you pass through: development, testing, and production.
This post will show you how to use PowerShell and .NET Core 3.0 to store and use Twilio credentials securely as Windows 10 environment variables. It’s important to get this right, as these credentials control access to Twilio products like the Twilio API for WhatsApp and the Programmable Video service that cost money and connect to your customers.
It can be embarrassing and costly for developers to inadvertently disclose sensitive information like API keys. Developers sometimes make this mistake by hard-coding keys in their source code, then checking the code into GitHub or another widely-accessible source code repository. Using the available tools for managing user secrets is a good way to avoid doing that.
Understanding Twilio REST API keys and tokens
When you create a new Twilio account Twilio will create a default project for you called ExplorationOne. This project has two user secrets associated with it, an Account SID and Auth Token. If you create additional projects in your Twilio account they’ll each have their own Account SID and Auth Token. These keys are the “master keys” for accessing the Twilio REST APIs. They are the most sensitive and powerful Twilio user secrets you will use in developing programs.
API Keys are credentials you can create and revoke through the Twilio Console or the Twilio REST API. These keys can be used by your applications (and your developers) to access Twilio products. You have control over creating and revoking API keys, so you can generate and revoke them as needed to tailor access rights within your organization and applications. The capabilities of API Keys are limited in scope, but they should be safeguarded and they are normally restricted to use in server-side code.
API Keys are also used to generate Access Tokens which you can use to verify the identity of your application’s clients and grant them access to Twilio client API features. Twilio Access Tokens are based on the JSON Web Token (JWT, pronounced “jot”) standard and have a maximum lifetime of 24 hours. Because they’re dynamically generated and cryptographically signed for use by client-side code, and of limited lifespan, Access Tokens don’t have the same potential for damage as API Keys. The best practice is to generate them for the shortest time feasible for your application.
You can learn more about Twilio API keys and other security features in the Identity and Access Management (IAM) documentation on the Twilio website.
Understanding ASP.NET Core 3.0 configuration management
A complete explanation of how ASP.NET Core 3.0 starts up and creates web applications can be found in Microsoft’s ASP.NET Core fundamentals. The following is an overview of the highlights of the process as they apply to the Twilio secrets usually stored as environment variables.
Configuration in ASP.NET Core 3.0 uses data in key-value pairs from a variety of sources. Data sources include the Azure Key Vault, environment variables, settings files, command-line arguments, in-memory .NET objects, and others.
Configuration data is used to build hosts and apps, including web hosts and web applications. ASP.NET 3.0 web applications include Razor Pages, API, MVC, and Blazor apps, all of which can be used with Twilio products.
When building hosts, configuration data can be imported from environment variables and command-line arguments. Environment variables with specific prefixes are used in different ways when building hosts:
DOTNET_prefixed variables can be used by the .NET Generic Host HostBuilder class to create a generic host
ASPNETCORE_prefixed variables can be used by the IWebHostBuilder Interface to create a web host
Configuration data can also be used to create apps, such as web apps that include real-time video chat using Twilio Programmable Video. Configuration data for apps can come from a variety of sources, including:
- Secret Manager
- environment variables
- command-line arguments
Key-Value pairs are read by configuration providers, classes that can load configuration parameters from a variety of sources at runtime. The Environment Variables Configuration Provider loads configuration information from operating system environment variables. There are also configuration providers for file and command-line configuration data.
Using the ASP.NET Core 3.0 default configuration builder and the Environment Variables Configuration Provider you can easily retrieve Twilio credentials you’ve stored as user profile environment variables and use them in your web applications. This will help you restrict access to these secrets and help you prevent inadvertent disclosure of them in source code.
Further security considerations
It’s important to keep in mind that environment variables are stored as plain-text hex values in Windows Registry files, C:\users\<username>\NTUSER.DAT for user environment data and C:\Windows\System32\config\SYSTEM for machine data. Anyone with sufficient access to the machine can read them.
It’s important to keep hardware, like computers and magic rings, safe.
The following tutorial will teach you how to store your Twilio Account SID and Auth Token as Windows 10 user environment variables using the command line for:
- PowerShell 5 and PowerShell Core
- Windows Console
You’ll also learn keyboard shortcuts for getting to the environment variables in the Windows Settings graphical user interface.
You’ll need the following tools and resources to accomplish the tasks set forth in this tutorial:
- Windows 10 Pro
- PowerShell 5 (included with Windows 10 Pro)
- .NET Core 3.0 SDK and Runtime (The SDK installer includes the Runtime.)
- Twilio Account (Sign up for free and get a $10 credit.)
The following additional resources aren’t required, but they may enhance your experience:
- PowerShell Core (v6)
- Windows Terminal (Preview)
Getting your Twilio credentials
If you haven’t already signed up for a free Twilio trial account, use the link above to get started.
Once you’ve registered, sign in and navigate to twilio.com/console. If you’re creating a new account you’ll be asked about the kind of projects you’d like to build. Your answers will be used to create an initial project for you.
If you’re new to Twilio you’ll have a single Twilio project called ExplorationOne. If you’ve created your own projects you should select one you can use for experimentation.
In the Project Info section of the project dashboard you’ll see three items on the right-hand side:
Click the show link to reveal the value for AUTH TOKEN. Copy the values for ACCOUNT SID and AUTH TOKEN to a safe, temporary, place like a Notepad window.
Your project dashboard should look something like this (except you’ll have letters and numbers in place of the blurry parts):
Storing Twilio credentials in user environment variables
Contrary to a popular myth, you don’t have to use the Windows GUI to manipulate environment variables, although that’s a convenient way of doing so. There are actually two places for manipulating environment variables from the command line, PowerShell and the Windows Console.
Getting environment variables with PowerShell
Open a PowerShell window. Do this in regular user mode rather than as an Administrator. If you’re opening a PowerShell 5 window you’ll see something like:
Windows PowerShell Copyright (C) Microsoft Corporation. All rights reserved. Try the new cross-platform PowerShell https://aka.ms/pscore6 PS C:\Users\mithrandir>
Note the hint about trying PowerShell Core. If you opened a PowerShell Core window you should see the following:
PowerShell 6.2.3 Copyright (c) Microsoft Corporation. All rights reserved. https://aka.ms/pscore6-docs Type 'help' to get help. PS C:\Users\mithrandir>
The minor version number may be higher by the time you read this.
Checkout your current environment variables by getting the list from the env: virtual drive with the Get-ChildItem command:
PS C:\Users\mithrandir> Get-ChildItem env:
You should see a long list of environment variables, including the computer name, current Path, TEMP files location, and others.
You can select specific items by specifying their name, or part of their name and a wildcard:
PS C:\Users\mithrandir> Get-ChildItem env:t* Name Value ---- ----- TEMP C:\Users\mithrandir\AppData\Local\Temp TMP C:\Users\mithrandir\AppData\Local\Temp
You’ll use that command later to verify your Twilio values are being set. Also, note that
Get-ChildItem has an alias,
gci you can use if you want to save keystrokes.
Getting environment variables with PowerShell and .NET
PowerShell gives you the ability to use static methods on .NET objects, so you can also get environment variables that way. The GetEnvironmentVariable static method of the
System.Environment object enables you to specify the scope of the variable as well: machine, user, or session.
Try that with the
TEMP environment variable to see the differences between the machine and user settings:
PS C:\Users\mithrandir> [System.Environment]::GetEnvironmentVariable('TEMP','machine') C:\WINDOWS\TEMP PS C:\Users\mithrandir> [System.Environment]::GetEnvironmentVariable('TEMP','user') C:\Users\mithrandir\AppData\Local\Temp
Setting Twilio environment variables with PowerShell and .NET
As you might expect, setting environment variables uses a similar static method, SetEnvironmentVariable. You can specify the location of the environment variable with the EnvironmentVariableTarget enumeration. It’s important to do that with your Twilio environment variables because you’ll usually want them to be persistent and restricted to your user account.
Putting it all together, here’s the command-line instruction for creating a Windows 10 user environment variable for the Twilio Account SID. Replace the value in the code below with your actual Account SID:
When you run the
Get-ChildItem command to check that the variable has been stored correctly you ... won’t see it:
PS C:\Users\mithrandir> gci env:T* Name Value ---- ----- TEMP C:\Users\mithrandir\AppData\Local\Temp TMP C:\Users\mithrandir\AppData\Local\Temp PS C:\Users\mithrandir>
The reason is not because you haven’t set the variable correctly: it’s because new and changed values only become available in new sessions. To see the value, close the current PowerShell window and open a new one, then execute the same
gci command. You should see the Account SID variable listed:
PS C:\Users\mithrandir> gci env:T* Name Value ---- ----- TWILIO_ACCOUNT_SID AC13791379137913791379137913791379 TEMP C:\Users\mithrandir\AppData\Local\Temp TMP C:\Users\mithrandir\AppData\Local\Temp PS C:\Users\mithrandir>
You can set your
TWILIO_AUTH_TOKEN environment variable the same way.
Fixing environment variable mistakes with PowerShell and .NET
If you need to change the value of an environment variable with the
SetEnvironmentVariable method, just run the command again with the new value. Remember that the new value will be available in new sessions, so you’ll have to close the PowerShell window and open a new one to see the change.
To remove an environment variable using PowerShell and .NET, update the variable with
$null as the value, like so:
This will get rid of the environment variable in subsequent sessions.
Setting Twilio environment variables with the Windows Console
If you’re a programmer from the Second Age of Windows (before Windows NT 3.1), you might prefer to execute your command-line instructions at the old-school command prompt. Fortunately for you, there’s a convenient way to set environment variables that way. The setx command provides a way to set environment variables.
The command defaults to the current user environment, so all you only need to supply the variable name and value, and since there aren’t any spaces in the value you don’t need quotation marks.
Setting the Account SID environment variable with the Windows Console looks like the following:
Microsoft Windows [Version 10.0.18362.476] (c) 2019 Microsoft Corporation. All rights reserved. C:\Users\mithrandir>setx TWILIO_ACCOUNT_SID AC13791379137913791379137913791379 SUCCESS: Specified value was saved. C:\Users\mithrandir>
You can update an environment variable with
setx, but there isn’t any way to remove directly from the Windows Console command line. You’ll have to use Registry mode to do that, and you should be wary of digging too deep into the Registry from the command line.
Maybe it’s better to climb the mountains of PowerShell?
Or you could just use the GUI.
Setting Windows environment variables with the graphical user interface
There are some convenient keyboard shortcuts in Windows 10 that will take you directly to the right place:
Press Win+x, then n, to open the Windows Settings panel.
Select Edit environment variables for your account and press Enter.
The Environment Variables dialog box will open.
You can add, edit, and delete environment variables as you see fit.
This post introduced you to Twilio user secrets, like your Account SID and Auth Token, and explained some differences between them that relate to how they should be secured in your development environment and applications. It also provided a brief overview of ASP.NET Core 3.0 configuration management, which can be used in conjunction with Twilio environment variables to use your Twilio user secrets securely in your web applications. The tutorial showed you the specific commands for setting, changing, and deleting environment variables in PowerShell. It also showed you how to set environment variables from the Windows Console command line.
Safe storage of app secrets in development in ASP.NET Core – This article on docs.microsoft.com covers all the ways you can store app secrets when developing in ASP.NET Core. There are lots!
Identity and Access Management (IAM) – This is the home for all the topics relating to securely authenticating Twilio REST API requests and best practices for accessing Twilio. It includes links to quickstart code for C# (and other languages).
AJ Saulsberry is a Technical Editor at Twilio. Reach out to him if you’ve been “there and back again” with a C# development topic and want to write about it for the Twilio blog.