A better way to store application credentials using KeePass and Powershell
AWS has recently launched a new service offering called AWS Secrets Manager to help organisations with the challenge of storing secure credentials. This new service allows to store and retrieve passwords and any other sensitive credentials. Even more, it can also rotate and change those credentials automagically based on a predefined rotation interval.
This new service inspired this article about storing passwords and other secure credentials. The reality is that storing, processing and rotating password credentials have always been somewhat challenging: they are usually stored in configuration files as clear text, or worse they are stored in the application source code as clear text. This vulnerability could even be worse if you use one of those public source code repositories like GitHub, Bitbucket (or anything else) and now your passwords live happily ever after in the cloud...extra brownie points for you if the repository is a public one, which means basically anyone can read it :)
KeePass to the rescue
I'd like to introduce one of my favourite password management tool called KeePass. If you have not heard about KeePass it's an open source, free, light-weight and easy-to-use password manager. This is a somewhat "traditional" tool, it doesn't use any cloud services, as far as cloud concerned it's a beautiful sunny day and there are no clouds! Your KeePass files are stored where you want them, how you want them which has its own advantages and disadvantages as well. At least you don't need any additional firewall configurations, you don't have to have those conversations about 3rd party suppliers and 3rd party datacentres...this is a real blessing especially in a heavily process driven organisation.
So, let's take a closer look on how you could benefit from using KeePass. I'll use Powershell to illustrate but there's always more than one way to skin a cat...for you cat and animal lovers out there: There's more than one way to cook an egg...Come to think of this one it pretty much works with every other activity I can think of :) Anyway, my point is KeePass is written in .NET which means any .NET application is fair game, there are 3rd party libraries available for Java, Python. As always, your mileage may wary, do your research before you start using any one of these to make sure you keep the security gods happy :)
Meet PoshKeePass
In order to use KeePass with Powershell I'll be using PoshKeePass, one of many options available these days.
To get started let's install the PoshKeepass module (admin privileges are required):
Install-Module -Name PoshKeePass
At this stage I have to mention the module uses KeePassLib which is embedded in the Github repo and seems outdated . I recommend a manual update to make sure it's the latest and greatest :). In order to do that you have to figure out where the module is installed which is just one simple command away:
(Get-Module PoshKeePass).Path
In my case it's installed in C:\Program Files\WindowsPowerShell\Modules\PoShKeePass\2.0.4.3\PoShKeePass.psm1 and the DLL in question is KeePassLib.dll in the C:\Program Files\WindowsPowerShell\Modules\PoShKeePass\2.0.4.3\bin folder. With that in mind let's continue our journey. The next step is to import the module:
Import-Module PoShKeePass -Force
Let's see what commands are available to use after the module is imported:
Get-Command -Module PoShKeePass
PoshKeePass in action
As you can see we could create a KeePass database using PoshKeePass but I'll skip that for now, I'll be working with an existing database I've created using the KeePass application. First you need to create a database configuration profile in the script to specify the location of the KeePass password database, authentication settings and so on. In my example I'll be using Windows authentication (-UseNetworkAccount below) but this has obvious operational risks you need to factor in and choose the correct authentication method that fits your requirements for production.
New-KeePassDatabaseConfiguration -DatabaseProfileName 'SecretPasswords' -DatabasePath <PATH_TO_YOUR_KEEPASS_PASSWORD_DATABASE> -UseNetworkAccount
The profiles are saved so no need to create them again. To get a list of profiles just use the Get-KeePassDatabaseConfiguration cmdlet. And now let's get one of our password entries from the KeePass password vault:
Get-KeePassEntry -KeePassEntryGroupPath 'MyDB/ProdDB' -AsPlainText -DatabaseProfileName SecretPasswords
The KeePassEntryGroupPath is the location within the password database. This is the tree folder/container-like structure within the kdbx file you can observe when you open it with the KeePass application. The example above gets all the entries that are in the General container and it gets the entry in clear text which now you can use as you see fit. To make it easier here's how my test KeePass database looks like:
In terms of automatic credential rotation it's not supported by KeePass but there is good news. It doesn't mean you can't do it yourself either with Powershell/.NET or Java or python. The PoshKeePass module provides the Update-KeePassEntry cmdlet that makes it pretty easy. Let's store the KeePass entry we want to change in a variable:
$entry=Get-KeePassEntry -KeePassEntryGroupPath 'MyDB/ProdDB' -AsPlainText -DatabaseProfileName SecretPasswords
An then let's update the password in KeePass using the variable above. The following example will generate a new 20 character random password using the KeePass password generator engine so you don't have to worry about that either:
Update-KeePassEntry -KeePassEntry $entry -DatabaseProfileName 'SecretPasswords' -KeePassEntryGroupPath 'MyDB/ProdDB' -Title 'New Title' -KeePassPassword $(New-KeePassPassword -upper -lower -digits -length 20) -Force
So, that's all for now, we just only scratched the surface but it's a good start. Happy password management :)