Don't spill the beans - keep your secrets secure 🤫
In the previous post Sleep Worry-Free: The best tips for Local Secrets Management
I shared the best tips for managing local secrets. In this post I will take Secrets Management
to the next level by showing you how to create manage and use secrets securely by setting up a local secure store using PowerShell SecretManagement
and PowerShell SecretStore
modules.
Modules explained
Since this approach to Secrets Management
depends on the two just mentioned modules the purpose of each of the modules is explained next.
PowerShell SecretManagement module
Important to note here is that this module does not store any secrets it is a uniform interaction layer to to access and manage secrets stored different kind of extension vaults. This module supports managing the following secret data types:
- byte[]
- string
- SecureString
- PSCredential
- Hashtable
PowerShell SecretStore
The SecretStore module is an extension vault for the just mentioned PowerShell SecretManagement
module. This is the module that stores secrets and it does so locally within the current user context. It uses the .NET crypto APIs to encrypt the file which is used ot store the secrets. Since this modules works in all by PowerShell supported Operating systems it runs on Windows, Linux and macOS.
By default the store requires a password for unlocking it, this is done to provide the strongest. As all other extension vaults this vault is registered to the current logged in user context, and is available only to the user in question. The extension vault registry file is stored in the user account protected directory.
For Windows platforms the location is:
%LOCALAPPDATA%\Microsoft\PowerShell\secretmanagement
For non-Windows platforms the location:
$HOME/.secretmanagement
Set-up your Secure Store
The first step is to make sure that the two modules are installed and loaded, namely;
- Microsoft.PowerShell.SecretStore
- Microsoft.PowerShell.SecretManagement
For this I used a simple ForEach loop which checks if the modules are already installed both are loaded if not both are installed and then loaded. The snippet I use is as follows:
Register a new vault
To register a new vault a SecureString
password is required. This password is exported into an XML file and encrypted by Windows Data Protection (DPAPI) using the Export-Clixml
command. Next a new vault is created using the Register-SecretVault
command. To complete the registration of the vault the just created password is used to secure it and the following configurations values are also set.
- Authentication <- Setting this parameter to
Password
Ensures a password is required to secure the concerning vault - PasswordTimeout<- The amount of time the vault stays unlocked after using the password, the default is 15 minutes however I like to set it to 3600 seconds (1 hour)
- Interaction <- Specifies whether the SecretStore should prompt a user when they access it. I used
none
to be able to run the whole thing via an automation script. - Password <- the actual password encrypted using
Export-Clixml
. Needed when previous parameter is set tonone
. - Confirm <- Prompts you for confirmation before running the cmdlet. I set it to $false since I intend to execute it via an automation script.
I combine the above settings into a function based on the following snippet:
Use the new vault
The first step to start using the newly created vault is to make sure it’s unlocked. For this the password used during the creation must be provided using the Unlock-SecretStore
command. With the vault unlocked the Set-Secret
and Get-Secret
can be used to store and retrieve secrets.
-Metadata
parameter. Naturally the extension vault itself must support it this as not all do.Before starting a debug session I simply use the Set-Secret
command to store te required secrets in the vault and use them in my throw away / one time use PowerShell script Jevs-Playground.ps1
. For details on this script please check out my previous post Sleep Worry-Free: The best tips for Local Secrets Management
.
Check-out the next examples as these contain the snippets I used at one time or another for development and debugging.
Unlock the vault
Simply use Unlock-SecretStore
command, but make sure to provide path to your secure store password xml file.
Add secrets to the vault
Use the Set-Secret
command to add secrets to the vault.
Connect-AzAccount with vault secrets
Get the app id, app secret and the tenant id secrets and pass these into the Connect-AzAccount. The app secret does not need to be read as plain text and should be passed as System.Security.SecureString
directly.
Azure DevOps API with vault secrets
Get the PAT token from the vault, craft a authentication header using the token and simply execute Invoke-RestMethod
.
Wrapping up
I hope you enjoyed this post and now have a better understanding of the possibilities to manage secrets locally during debugging. If you are interested in the reference material used to make this post, please visit the following links. As always, a big thanks for reading this post. If you liked it, don’t be shy and have a look at my other posts .