PowerShell / Modules

MIT License
111 stars 25 forks source link

WIP: Explore cross-platform local store #86

Open PaulHigin opened 4 years ago

PaulHigin commented 4 years ago

This PR replaces the Windows platform only CredMan local store with a .NET based cross-platform local store using optional password.

JustinGrote commented 4 years ago

A thought, and I may have missed this, but couldn't you still keep the encryption key in the Windows Credential store and continue a "promptless" method of access on Windows?

PaulHigin commented 4 years ago

@iSazonov, @JustinGrote Thanks for your input. I forgot to include the WIP tag in the title. This PR explores the possibility of a cross-platform, .NET based local secure store. There are a number of significant problems with CredMan. The main problem is its Windows platform only. But in addition it only works for interactive log-in accounts, so it won't work with Windows built-in accounts or over PS remoting, and this greatly reduces the usefulness of SecretManagement module.

The main good thing about this solution is that it provides a uniform experience over all platforms. It is also arguably more secure with password protection (with sudo like timeout) than CredMan SSO.

We have not decided if this is the right direction to take, and would like to get community opinions. Also I'll work on publishing the design spec for this, which talks more about motivation.

PaulHigin commented 4 years ago

@JustinGrote The only way to use this "promptless" is to configure the local store without password, or with "DoNotPrompt" but pass in a SecureString password in script using SecretManagement. The no password option is obviously less secure, and relies on file system protections. But this is arguably roughly as secure as CredMan with SSO.

iSazonov commented 4 years ago

We have not decided if this is the right direction to take, and would like to get community opinions.

Looks good. Perhaps we could keep Windows Secure Store as an option.

For experience reference https://www.nuget.org/packages/SecureStore/

JustinGrote commented 4 years ago

@PaulHigin I was thinking more that whatever the xplat store becomes, I assume it's going to be effectively like KeePass and you'll have a passphrase to unlock the encryption. What I'm saying is that there could be an option to save the passphrase in credential manager, and then when unlocking the vault, have it first check if there's an available passphrase in credential manager to match.

Basically, rather than having credential manager be the metavault as it is now, instead it can be a key repository to unlock the xplat metavault. If you're not on Windows, then it's passphrase as usual (and perhaps automatic integration with various keyring tools to store the passphrase in the future), but it's no longer used to store the actual metainfo. Make sense what I'm saying?

Of course I can do this outside of the module, but it would reduce user friction to have it baked in, especially for automation scenarios like scheduled tasks.

PaulHigin commented 4 years ago

@JustinGrote I see what you are saying, but at this point I feel it is something that should be performed outside SecretManagement, i.e., something a user does manually. One concern is inadvertently opening up a security hole. But it is something that can be considered later.

Note that even with the store configured without password, the secret data is still encrypted with a key, but the key is protected only by the file system. Arguably, this is as secure as a SSO solution like CredMan. Both are tied to current user account, and vulnerable to admin/root attacks.

JustinGrote commented 4 years ago

@PaulHigin there is one massive difference. With the file system permissions method the key is still not encrypted-at-rest, which a lot of compliance (HIPAA ,etc.) will not accept. Keeping the key in windows credential manager, the key is at least encrypted at rest such that if someone stole the computer and dumped the hard drive, they can't just get the cleartext key to the secrets. They would need a valid windows login credential to still decrypt it. This is the whole reason the cryptoAPI was developed and so it's still valid.

Still, if you're set on not having that handled natively, it wouldn't be a big deal to make a helper module that stored the key this way and then called secretsmanagement or used parameter completion to supply the key.

EDIT: I also acknowledge that your method is the same one used for SSH private keys on most Linux systems, but those keys are also encrypted at rest in addition to the restricted permissions.

PaulHigin commented 4 years ago

Agreed, in this case you need to use a password for local store to protect at rest data. I was thinking more in terms of protecting against admin/root attacks. SSO is vulnerable during user account lifetime, and integrating it with the local store password weakens it in my opinion. JIT password with timeout (e.g. sudo) seems stronger for dynamic scenarios.

Again, I see this as a possible nice to have, opt-in feature, and something we may want to add later.