PowerShell / Modules

MIT License
111 stars 25 forks source link

[SecretManagement] Get-Secret / Set-Secret hooks support #94

Open itfranck opened 4 years ago

itfranck commented 4 years ago

Additional optional vault parameters to support hooks :

The Flow of operations would be :

The idea is to overhaul existing providers with additional features without creating a custom implementation and / or having to use a second function to pre-process / post-process a secret before using the Get/Set secret.

Some potential uses

Main advantage The main benefit of having those options as scriptblock defined in the vault registration is that it is would be embedded into that vault, meaning if you want to use Protect-CMS before sending your secret into the vault, you'd have to do it manually and every time. Furthermore, you'd have to to the reverse operation every time after getting your secret back.

The idea of hook streamline that process by embedding further capabilities directly into Get-Secret / Set-Secret managed directly and transparently through the vault registration.

Example 1 : Double encryption

$Params = @{
    'AffterGet' = { $_ | Unprotect-CmsMessage "*youralias@emailaddress.com*" }
    'BeforeSet' = { $_ | Protect-CmsMessage -To "*youralias@emailaddress.com*" }
}

Register-SecretVault -Name 'DoubleEncryptionVault' -VaultParameters $params

Example 2 : I opened these issues regarding Az.Keyvault implementation, which only support SecureString. With hooks, I could easily had registered my vault with Scriptblock to manage conversion from other supported type to SecureString before Set-Secret set the actual secret in the vault and back from the SecureString to the desired type. It would have allowed me to workaround the Az.Keyvault limitation, which might or might not be fixed anytime soon.

https://github.com/PowerShell/Modules/issues/93 https://github.com/Azure/azure-powershell/issues/12190

Example 3: This ultimately will fail. PSCustomObject and classes are not supported. However, with hooks, I could manage the conversion of the unknown object to something manageable by the Set-Secret accepted type and even enforce specific types.

$CustomObject = [PSCustomObject]@{
    'Hello' = 'World'
    'Foo' = 'Bar'
}

$CustomObject.GetType()

Set-Secret -Vault BuiltInLocalVault -Name test -Secret $CustomObject
JustinGrote commented 4 years ago

@itfranck while I totally get it, wouldn't it generally be easier to just either:

  1. Just have some prior code to convert the custom object into the correct format prior to set-secret
  2. In the case of a broken module, just modify it yourself and reimport it?
itfranck commented 4 years ago

@JustinGrote

I like the purity of having Get-Secret / Set-Secret for all the implementing type. All the external providers going through secret management use those without exposing any other cmdlets.

The idea here is that I don't want to add additional functions to workaround issues on other providers but I'd rather just use the basic cmdlets.

Get-Secret would apply a custom logic found in the vault registration itself (if any). Same for Set-Secret.

No additional pre-process / post-process functions I have to import everywhere and not forget about using them.

Rather, the logic stays embedded within the one-time vault registration and everything going in and out the secret vault go through it (if defined)

In that sense, I think hooks would be simpler than always calling the pre-process / post-process functions themselves (which I'd then need to import and / or include in all my script using that vault)

Regarding fixing the broken module, I wouldn't (other than for testing) touch any external modules since as soon as I update them, my changes would be lost. Also, if I need them on multiple machines, this becomes less than ideal. Using a custom module / custom repo. would requires me to work a lot harder to get my custom module up-to-date with the original one when changes arises.

tl;dr In my point of view, hooks would be simpler than using custom code everywhere for the reasons mentionned above. Modifying the external module provider is not a viable option I would consider.