PowerShell / SecretManagement

PowerShell module to consistent usage of secrets through different extension vaults
MIT License
328 stars 46 forks source link

VaultName doesn't always make sense - user experience and expectations discussion. #114

Open techthoughts2 opened 3 years ago

techthoughts2 commented 3 years ago

This isn't an issue or feature request but more of a discussion topic as we explore vault creation on various platforms.

I'm finding that in certain scenarios that the concept of a 'Vault Name' doesn't perfectly align.

In situations where authentication is one to many named vaults the concept of $VaultName works well. Authentication is performed, and the specific vault can be engaged by name.

For some projects, this makes a lot of sense:

But for some projects, this doesn't make sense. Authentication to the platform gets you a lump set of secrets with no name space. In these projects, the $VaultName parameter isn't even used.

Lets explore two popular cloud providers to see how this can impact the user experience when engaging the capabilities of PowerShell SecretManagement.

So in the AWS example, we see that it's authentication that drives the return from the platform. If the user has their default profile set to account 1, they will have access to the secrets in account 1. If the user is instead authenticated with their default profile to account 2, they will have access to that set of secrets.

Is there an expectation or standard we would like to see established for the user experience when engaging SecretManagement?

Mainly around registering a new vault. In the AWS scenario, a Secrets Manager Vault module could be created. Then the user could register that named vault: MyAWSSecrets.

But while that registered vault has a name - the users authentication profile will give them access to a very different set of secrets depending on which account they are authenticated to.

JustinGrote commented 3 years ago

Disclaimer: Not a MSFT employee

I think you're reading too much into it, it's just a label to reference different vault registrations. By default it's the same name as the vault.

So, in keepass's place, you can have a vault labeled "Personal" thats a personal vault, "Work" that's another, etc.

In your Azure Example, I would probably name each vault after the vault name in Azure, e.g. MyKeyVault1 would be either MyKeyVault1 or maybe paired with subscription or RG name, e.g. MySubscription/MyKeyVault1

In your AWS example (for which I don't think a vault extension exists yet), The vault name might simply reference the entire account, and the individual secrets will be referenced as secrets, e.g. MyAWSAccount as the vault name, and Get-Secret 'tutorials/MyFirstSecret' would fetch that individual secret. It's a very broad abstraction that can be implemented however the extension author wants, however what i laid out in this paragraph is what I think most users would expect. Your AWS example, again, could require a VaultParameter with the accountName to pin it to a specific auth profile, so it would always query against that auth profile.

So vaultname could allow you to reference different vaults from different pinned account contexts, or it can just be a free-roaming one that uses your existing context. It's all in the implementation, and can be toggleable with vault registration parameters. It's entirely up to the extension author.

The issues you bring up can be solved it seems with a proper vault extension implementation (I wrote the keepass, chromium, and credmgr extensions), so in my mind, this should be the de-facto pattern and practice for vaultname

  1. The vaultname should be the name of the module by default if a name isn't specified and reference the users "current context" or require authentication (whatever that means to the extension)
  2. The vaultname is always just a label, it doesn't carry with it any meaningful context beyond what the user wants to call it to make it easy for them to remember, and does not influence the operation of the extension vault whatsoever.
  3. Behavior of a vault (account to connect to, etc.) should be done via the VaultParameters parameter, either directly or via a friendly wrapper command (See Register-ChromiumSecretVault)
  4. Scripts should generally not reference the secretmanagement syntax directly, but instead take the normal types such as PSCredential, SecureString, etc. as parameters. The user can then opt to supply the secret via secretManagement as a subexpression to your parameter (or not use secretmanagement at all). The exception to this would be if either the secret requires a specific vault for whatever reason, or you want to offer convenient integration as a separate parameter set. Powershell is about choice, and forcing a user to use secretmanagement when they may have a better way to supply the secret is anti-pattern (maybe the only way they can supply the secret is from an API that doesn't have an extension vault yet, for example)
  5. When referencing a secret in a script meant to be portable, you should not reference a VaultName if at all possible. This allows the user to set their own "default" secretvault and fetch the secret you want to have in your script however they want to.
  6. A script should allow for the secret name and vault to be a configurable specification, but in some circumstances could be hardcoded to enforce some sort of contract I suppose.