GithubHelp home page GithubHelp logo

powershell / secretmanagement Goto Github PK

View Code? Open in Web Editor NEW
306.0 306.0 43.0 266 KB

PowerShell module to consistent usage of secrets through different extension vaults

License: MIT License

PowerShell 32.04% C# 67.96%

secretmanagement's Introduction

logo PowerShell

Welcome to the PowerShell GitHub Community! PowerShell is a cross-platform (Windows, Linux, and macOS) automation and configuration tool/framework that works well with your existing tools and is optimized for dealing with structured data (e.g. JSON, CSV, XML, etc.), REST APIs, and object models. It includes a command-line shell, an associated scripting language, and a framework for processing cmdlets.

Windows PowerShell vs. PowerShell Core

Although this repository started as a fork of the Windows PowerShell codebase, changes made in this repository are not automatically ported back to Windows PowerShell 5.1. This also means that issues tracked here are only for PowerShell Core 6 and higher. Windows PowerShell specific issues should be reported with the Feedback Hub app, by choosing "Apps > PowerShell" in the category.

New to PowerShell?

If you are new to PowerShell and want to learn more, we recommend reviewing the getting started documentation.

Get PowerShell

You can download and install a PowerShell package for any of the following platforms.

Supported Platform Download (LTS) Downloads (stable) Downloads (preview) How to Install
Windows (x64) .msi .msi .msi Instructions
Windows (x86) .msi .msi .msi Instructions
Ubuntu 22.04 .deb .deb .deb Instructions
Ubuntu 20.04 .deb .deb .deb Instructions
Ubuntu 18.04 .deb .deb .deb Instructions
Ubuntu 16.04 .deb N/A N/A Instructions
Debian 10 .deb .deb .deb Instructions
Debian 11 .deb .deb .deb
CentOS 7 .rpm .rpm .rpm Instructions
CentOS 8 .rpm .rpm .rpm
Red Hat Enterprise Linux 7 .rpm .rpm .rpm Instructions
openSUSE 42.3 .rpm .rpm .rpm Instructions
Fedora 35 .rpm .rpm .rpm Instructions
macOS 10.13+ (x64) .pkg .pkg .pkg Instructions
macOS 11+ (arm64) .pkg .pkg .pkg Instructions
Docker Instructions

You can download and install a PowerShell package for any of the following platforms, which are supported by the community.

Platform Downloads (stable) Downloads (preview) How to Install
Arch Linux Instructions
Kali Linux .deb .deb Instructions
Many Linux distributions Snapcraft Snapcraft

You can also download the PowerShell binary archives for Windows, macOS, and Linux.

Platform Downloads (stable) Downloads (preview) How to Install
Windows 32-bit/64-bit 32-bit/64-bit Instructions
macOS (x64) 64-bit 64-bit Instructions
macOS (arm64) 64-bit 64-bit Instructions
Linux 64-bit 64-bit Instructions
Windows (ARM) 64-bit (preview) 64-bit Instructions
Raspbian (ARM) 32-bit/64-bit 32-bit/64-bit Instructions

To install a specific version, visit releases.

Upgrading PowerShell

For best results when upgrading, you should use the same install method you used when you first installed PowerShell. The update method will be different for each platform and install method. For more information, see Installing PowerShell.

Community Dashboard

Dashboard with visualizations for community contributions and project status using PowerShell, Azure, and PowerBI.

For more information on how and why we built this dashboard, check out this blog post.

Discussions

GitHub Discussions is a feature to enable free and open discussions within the community for topics that are not related to code, unlike issues.

This is an experiment we are trying in our repositories, to see if it helps move discussions out of issues so that issues remain actionable by the team or members of the community. There should be no expectation that PowerShell team members are regular participants in these discussions. Individual PowerShell team members may choose to participate in discussions, but the expectation is that community members help drive discussions so that team members can focus on issues.

Create or join a discussion.

Chat

Want to chat with other members of the PowerShell community?

There are dozens of topic-specific channels on our community-driven PowerShell Virtual User Group, which you can join on:

Add-ons and libraries

Awesome PowerShell has a great curated list of add-ons and resources.

Building the Repository

Linux Windows macOS
Instructions Instructions Instructions

If you have any problems building, consult the developer FAQ.

Build status of nightly builds

Azure CI (Windows) Azure CI (Linux) Azure CI (macOS) CodeFactor Grade
windows-nightly-image linux-nightly-image macOS-nightly-image cf-image

Downloading the Source Code

You can clone the repository:

git clone https://github.com/PowerShell/PowerShell.git

For more information, see working with the PowerShell repository.

Developing and Contributing

Please look into the Contribution Guide to know how to develop and contribute. If you are developing .NET Core C# applications targeting PowerShell Core, check out our FAQ to learn more about the PowerShell SDK NuGet package.

Also, make sure to check out our PowerShell-RFC repository for request-for-comments (RFC) documents to submit and give comments on proposed and future designs.

Support

For support, see the Support Section.

Legal and Licensing

PowerShell is licensed under the MIT license.

Windows Docker Files and Images

License: By requesting and using the Container OS Image for Windows containers, you acknowledge, understand, and consent to the Supplemental License Terms available on Docker Hub:

Telemetry

Please visit our about_Telemetry topic to read details about telemetry gathered by PowerShell.

Governance

The governance policy for the PowerShell project is described here.

This project has adopted the Microsoft Open Source Code of Conduct. For more information, see the Code of Conduct FAQ or contact [email protected] with any additional questions or comments.

secretmanagement's People

Contributors

410sean avatar andyleejordan avatar michaeltlombardi avatar paulhigin avatar sdwheeler avatar stevel-msft avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

secretmanagement's Issues

Pipeline support

Some examples:

Get-SecretInfo | Get-Secret

Get-SecretInfo | Set-Secret

Get-SecretInfo | Remove-Secret

Register-SecretVault : Cannot bind argument to parameter 'Path' because it is an empty string.

Trying to follow blog post. After installation:

Register-SecretVault -Name SecretStore -ModuleName Microsoft.PowerShell.SecretStore -DefaultVault
Register-SecretVault -Name SecretStore -ModuleName Microsoft.PowerShell.SecretStore -DefaultVault

Register-SecretVault : Cannot bind argument to parameter 'Path' because it is an empty string.
At line:1 char:1
+ Register-SecretVault -Name SecretStore -ModuleName Microsoft.PowerShe ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : InvalidData: (:) [Register-SecretVault], ParameterBindingValidationException
    + FullyQualifiedErrorId : ParameterArgumentValidationErrorEmptyStringNotAllowed,Microsoft.PowerShell.SecretManagement.RegisterSecretVaultCommand

Register-SecretVault should import a module with -Force

I'm working on crafting an extension and what's kinda annoying is having to create a new PowerShell session every time I make a change to my implmenting script extension.

I wish I could just run this:

Unregister-SecretVault -Name foo
Register-SecretVault -Name foo -ModuleName .

And be ready to go with out a restart of my PowerShell session.

Register-SecretVault positional parameters unintuitive

I tried to omit the parameter names when using Register-SecretVault, but the positions didn't work out as I expected (given the example in the blog post, and other cmdlets that accept a name/key and a value):

> Register-SecretVault SecretStore Microsoft.PowerShell.SecretStore -DefaultVault
Register-SecretVault: Could not load and retrieve module information for module: SecretStore with error : The specified module 'SecretStore' was not loaded because no valid module file was found in any module directory..

Keepass

Do you have an examples yet for implementing with keepass by anychance? Thanks

Needs better documentation about `-SecureStringSecret` in `Set-Secret`

This is the syntax of Set-Secret:

SYNTAX
    Set-Secret [-Name] <String> [-Secret] <Object> [[-Vault] <String>] [-NoClobber] [<CommonParameters>]

    Set-Secret [-Name] <String> [-SecureStringSecret] <SecureString> [[-Vault] <String>] [-NoClobber] [<CommonParameters>]

And this is the current documentation about -Secret and -SecureStringSecret:

    -Secret <Object>
        A secret value to be added. The object type must be one of the supported types.

        Required?                    true
        Position?                    1
        Default value                None
        Accept pipeline input?       True (ByValue)
        Accept wildcard characters?  false

    -SecureStringSecret <SecureString>
        A secret SecretString object to be added.

        Required?                    true
        Position?                    1
        Default value                None
        Accept pipeline input?       True (ByValue)
        Accept wildcard characters?  false

The parameter -Secret is able to accept SecureString object, so it's not clear when should a user uses -SecureStringSecret.
@PaulHigin's clarification on this is:

-SecureStringSecret is the default parameter set and when no parameter is supplied will prompt the user to safely type in a secret string

We probably need better documentation about -SecureStringSecret so it's less confusing to users.

Just a bunch of questions

When searching for a way to secure credentials passwords which must be used within a Powershell/APi module to do sensitive work, I passed by this repository. First of all, this looks awesome. But it raises some questions

  • How can we change the locations of the store and the key files?
  • Is it possible to put a store and a key file in a Azure Devops pipeline to deploy them?
  • If we can only deploy the Store, do we need to install both modules?

These are the questions for now. Thanks in advance for answering them.

Discussion: Should extensions just handle opaque strings?

While writing an extension for KeyChain, the bulk of my code is to handle the various supported types and convert them to a string so that I can store the in KeyChain using the security command line tool. I would think that many if not most extensions don't do anything special with the various types and just transform them to a string form to store.

Perhaps a flag in the extension module manifest can declare that the extension only handles opaque strings and then Set-Secret and Get-Secret within the extension only handles a string. SecretManagement itself can encode the string to know the original type and handle the conversion to and from without the extension knowing anything about that. The additional benefit is that if additional types are supported in the future, only SecretManagment needs to handle them and not the extension.

Also, in this model, the extension would not implement Get-SecretInfo as the info (like Type) is embedded within the string, so SecretManagement just needs a way to enumerate all secrets from the extension and handle creating the SecretInformation objects.

registering a second vault may imply a different store

at least that's what I thought would happen. Here's a transcript:

S /> set-secret -name test1                                                                                                                                                                                                                                                                                cmdlet Set-Secret at command pipeline position 1                                                                                                      Supply values for the following parameters:                                                                                                           
SecureStringSecret: *************
Creating a new SecretStore vault. A password is required by the current store configuration.
Enter password:

Enter password again for verification:

PS /> get-secret test1
System.Security.SecureString
PS /> get-secret test1 -as
lsjkflkjsdlkf
PS /> get-secretinfo

Name          Type VaultName
----          ---- ---------
test1 SecureString SecretStore

PS /> Register-SecretVault -Name ss2 -ModuleName Microsoft.PowerShell.SecretStore                      
PS /> get-secretinfo                                                             

Name          Type VaultName
----          ---- ---------
test1 SecureString SecretStore
test1 SecureString ss2

I thought I was creating a second store, but it's the same. Is there a way to create a second vault with the same module?

Extensions should be able to hook into `Register-SecretVault`

Feature request.
We have a hook into Unregister thanks to this request.

I would like a way to have my extension perform some validation or other actions before registering the vault.

Use cases relevant to me :

  • Implemented module require some parameters to work properly. Validation could be done in the hook and prevent the registration if mandatory conditions are not met.

Az.keyvault is a good example of this. It requires SubscriptionId and VaultName to identify which Azure keyvault is targeted by the registration.

  • Implemented module require some action to be performed prior the registration.

--

I had such a use case while looking at using SecretManagement for a CMS implementation that require :

  • A mandatory vault parameter (for which I would issue a warning and prevent registration if not provided)
  • The creation of a self-signed certificate and adding that newly created certificate to the user certificates.

A Register-SecretVault hook (before registration) would be complimentary to the recently added Unregister-SecretVault hook and also definitely have valid use cases (Validation & performing any relevant actions ).

Thank you for considering this.

TypeInitializationException

If I try this Module on a Windows 2016 Server, I'm always getting the following error.

Test-SecretVault

Test-SecretVault : Der Typeninitialisierer für "Microsoft.PowerShell.SecretManagement.RegisteredVaultCache" hat eine
Ausnahme verursacht.
In Zeile:1 Zeichen:1

  • Test-SecretVault
  •   + CategoryInfo          : NotSpecified: (:) [Test-SecretVault], TypeInitializationException
      + FullyQualifiedErrorId : System.TypeInitializationException,Microsoft.PowerShell.SecretManagement.TestSecretVault
     Command
    
    

Maybe it could be interesting for the further development. If you need any Information about this error, feel free to contact me.

Request: Register-SecretVault should have ModuleName as Position 0 Parameter and Name Optional

For a ease of use improvement, if ModuleName is in Position 0 and Name is optional, then the vault name should be the same as the ModuleName by default if one isn't supplied, facilitating easier and more terse usage if a user doesn't want a custom Vault Name.

For instance:

Register-SecretVault Keepass #Implies -ModuleName KeePass
#Will Create a vault named 'KeePass' that can be referenced easily
Set-Secret -VaultName KeePass -Name MySecret -Secret 'ok'

Get-Secret not supporting wildcard characters yet preventing their uses as regular characters.

if (WildcardPattern.ContainsWildcardCharacters(Name))

        // Wild card characters are not supported in this cmdlet.

The current Get-Secret implementation do not support wildcards.
This is perfectly fine.

String should be interpreted literally when querying the secret name.
So :

  • "MySecret*xy"
  • "MySecret [Id: 1029301]"

should fetch the corresponding secrets with that literal name.

The current behavior is weird.
If the cmdlet is not supporting wildcards, I don't expect it to throw an error.
I expect it to process the string literally, which it is what it does, despite the error.

The error is unwanted here.

See: Using SecretManagement.Lastpass module, I get the result properly, as wildcards are not supported.
Unlike any other cmdlet not supporting wildcards, I would expect NOT to have an error here.
image

Edit:
Also, escaping the wildcard (like if it was a wildcard function) will not produce the error but will be passed down literally.

Related Issue:
TylerLeonhardt/SecretManagement.LastPass#5

Designdoc - Verbose implementation.

I was looking at the changelog and saw something was done for verbose.

Can't the flag be passed down normally through the calling cmdlet ?
For instance,

Get-Secret -Name 'SuperSecret' -AsPlainText -vault MyVault -Verbose

I would expect that verbose flag to be passed down to the implementing module, not a flag that need to be defined in VaultParameters. (And following that logic, it should be possible to pass the -debug flag in the same manner).

With #66 , it seems that I need to unregister the vault, then register it again with verbose, then unregister / re-register it again when done. It feels like we're going the long way around.

No BuiltInLocalVault when installing version 0.5.2-preview3

Installed Microsoft.PowerShell.SecretManagement from Powershell Gallery with:
Install-Module -Name Microsoft.PowerShell.SecretManagement -AllowPrerelease
And the BuiltInLocalVault didn't get created.
PS C:\> Get-SecretVault PS C:\>
Uninstalling the latest version and installing version 0.2.1-alpha1 created the BuildInLocalVault.

Edition Windows 10 Enterprise
Version 20H2
Installed on ‎2020-‎03-‎03
OS build 19042.508
Experience Windows Feature Experience Pack 120.2212.31.0

Unable to find dependent module(s) (Microsoft.PowerShell.SecretManagement)

If I use the parameter "-Force" when installing the SecretStore it fails with error message :

"Unable to find dependent module(s) (Microsoft.PowerShell.SecretManagement)" but IF I leave the "-Force" off

it will prompt me with:

Untrusted repository
You are installing the modules from an untrusted repository. If you trust this repository, change its
InstallationPolicy value by running the Set-PSRepository cmdlet. Are you sure you want to install the modules from
'PSGallery'?
[Y] Yes  [A] Yes to All  [N] No  [L] No to All  [S] Suspend  [?] Help (default is "N"):

and I can proceed with "A" and install it.

`Set-DefaultVault` doesn't have the same prefix as other cmdlets

It's best practice for a module to have the same prefix for every cmdlet in a module so that users know that a cmdlet comes from a module... Or use a prefix that gives context to the user on what they are doing.

Set-DefaultVault doesn't have the prefix that the others do and I worry that it could stomp on an existing cmdlet since Vault is fairly overloaded in the key store space.

This cmdlet should either be Set-SecretDefaultVault or Set-SecretVaultDefault.

Cannot install the SecretStore module

I've gotta be doing something wrong but I've tried a couple times.

PS C:\Users\adamr> Install-Module Microsoft.PowerShell.SecretManagement -AllowPrerelease -Scope CurrentUser -Force
PS C:\Users\adamr> Install-Module Microsoft.PowerShell.SecretStore -AllowPrerelease -Scope CurrentUser -Force
Install-Package: C:\Users\adamr\Documents\PowerShell\Modules\PowerShellGet\2.2.4.1\PSModule.psm1:9709
Line |
9709 |  … talledPackages = PackageManagement\Install-Package @PSBoundParameters
     |                     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
     | Unable to find dependent module(s) (Microsoft.PowerShell.SecretManagement)
PS C:\Users\adamr> get-module Microsoft.PowerShell.SecretManagement -list


    Directory: C:\Users\adamr\Documents\PowerShell\Modules

ModuleType Version    PreRelease Name                                PSEdition ExportedCommands
---------- -------    ---------- ----                                --------- ----------------
Binary     0.5.2      preview3   Microsoft.PowerShell.SecretManagem… Core      {Register-SecretVault, Unregister-Secre…

still prompted when I provide a securestring with default store

PS> $ss = read-host -AsSecureString 
***********
PS> Set-Secret -Name TestSecret -SecureStringSecret $ss
Creating a new SecretStore vault. A password is required by the current store configuration.
Enter password:

It seems like if I provide a secure string, it shouldn't prompt

Request: Register-SecretVault should call Test-SecretVault of the implementing extension in host UI Thread

Register-SecretVault does not appear to currently call any validation to the extension to make sure the VaultParameters are correct, for instance if a file path is correct. This also would give the extension the opportunity to do any registration of the vault if required, such as fetching an API key, etc.

EDIT: From what I'm seeing it does actually call it, but it calls it in a separate C# invocation, which disables all the host UI and other items that could be part of a test (e.g. prompting for the database path if one wasn't supplied). Further, Test-SecretVault are difficult to debug since no stacktrace is provided, only $error[0].exception.innerexception to maybe hint at what went wrong.

Feature Request: Extensible "Description" property on [SecretInformation]

Carried over from PowerShell/Modules#31

Summary of the new feature/enhancement

As a powershell user, I sometimes want some more information about what a secret is for, and a provider may be able to provide that additional information in a way that I can programatically query/filter that information.

For example:

  • Azure Key Vault could have the description of a byte[] secret as an X509 certificate, when it was modified
  • Keepass may provide a folder structure for where the secret resides, or a flag that a string is an SSH key for use in an SSH agent.

Proposed technical implementation details (optional)

Add a [Object] property to Get-SecretInfo output

Some name possibilities: Notes, Description, Metadata

The provider can populate this property with additional information about the secret. This information would be provider specific and the provider can supply any type of object as long as it has a clean ToString() method to convert it. Most providers may just do a simple string description, others may submit a nested hashtable with properties like created, modified, etc.

Future:
Some natural commonalities like "LastModified","Comment" may become common and should be added to the [SecretInformation] class designation to standardize them, however this property allows providers to deliver their own extensible information that's important to their provider.

Verbose / Debug flags should be passed down to the implementing module

Verbose / Debug from the Microsoft.Powershell.SecretManagement module get printed all right but are not passed down to the implementing module.

If I had these two lines at the top of the Get-SecretInfo implementation, here is what I get when I call Get-SecretInfo -Verbose

# Forcing verbose on purpose so I can see the value.
Write-verbose -message ($PsboundParameters | out-string) -verbose
write-verbose -message "`$VerbosePreference: $VerbosePreference" -verbose

image

Observed here:
TylerLeonhardt/SecretManagement.LastPass#4

Tab completion everywhere

This should work:

Get-SecretInfo -Vault <TAB>
Get-Secret -Name <TAB>

And complete based on the vaults that are available. Should be very simple to do with an argument completer.

Request: Vault Extension Module Path Should be VaultName.SecretManagementExtension

@PaulHigin Great job on the thorough blog posts, it's most helpful.

I think that we should support module authors to be able to have a Secret Management Extension as part of their original module rather than having to spin it off as a separate module, similar to how DSC resources can exist in the same module as the main implementing module. This will reduce the proliferation of modules that have to be downloaded and simplify developers not needing to maintain multiple repositories.

However, the existing VaultName.Extension nomenclature is too vague for this use case. Someone coming across the repository will not know this is specially a implementation of a secret vault, so the path should also support something more specific, such as VaultName.SecretManagementExtension or VaultName.SecretManagementVault or something to clearly denote the code is for the secretmanagement vault extension implementation, since this is hardcoded and not configurable.

Example

For a module named KeePass that implements a vault, the folder structure should allow for KeePass.SecretManagementExtension subfolder, then the user has a very simply starting flow:

Install-Module KeePass #Also gets the regular powershell keepass commands
Register-SecretVault MyKeepass -Module Keepass
#etc...

Recommended Alternative

Consider a new PSData attribute in the psd1 to specify the path or name where the secret vault is located. This would have the additonal benefit to make them far more discoverable, for example something like Get-SecretVault -ListAvailable could search the modules and find which ones have the SecretManagementVault psdata attribute and return a list.

Awareness of current vault name.

Suggestion.
Can we get an awareness of the current vault name ?
Currently, we have the vault parameters available through $AdditionalParameters.

The use case is for any additional functions shipped with the module.
For instance, the module I am currently working on: , SecretManagement.LastPass

Get-Secret will do attempt to authenticate the user if not connected but if everything fail, it will throw an error

 Error: Could not find decryption key. Perhaps you need to login with Connect-LastPass

Connect-LastPass is a complimentary function shipping with the module so the user do not have to make or know the underlying call. It uses $Vault parameter, even though in the root module so it can get vault parameters and respect the registered vault implementation.

What I'd really want to throw from Get-Secret is :

# The current vault name  is not available from within cmdlets so I cannot indicate it from within.
 Error: Could not find decryption key. Perhaps you need to login with Connect-LastPass -Vault 'CurrentVaultName'

That would requires me to be aware of which vault I am in when I throw the error from within Get-Secret and not just the $AdditionalParameters

The Register-SecretVault cmdlet violates PowerShell’s best-practice coding rules.

When strict mode is on, the Register-SecretVault cmdlet -- even though it completes what it is supposed to do -- generates a terminating error (“The property 'Path' cannot be found on this object. Verify that the property exists.”). Firstly, I would expect the Microsoft.PowerShell.SecretStore cmdlets to respect PowerShell’s best-practice coding rules and, secondly, if an error occurs anyway, the error to be non-terminating.

Set-StrictMode -Version Latest
try{
  Register-SecretVault -Name ‘MSStore' -ModuleName 'Microsoft.PowerShell.SecretStore'
  Register-SecretVault -Name 'KPStore' -ModuleName 'SecretManagement.Keepass'
} catch { $_ }

Test-SecretVault does not take wildcards for -Name parameter

It is not easy to test all the secret vaults as the name parameter does not take wildcards. Get-SecretVault does take wildcards for name which set the expectation that Test-SecretVault will accept it too.

Current state:

PS /> Get-SecretVault

Name ModuleName IsDefaultVault


SecretStore Microsoft.PowerShell.SecretStore False
SecretStore2 Microsoft.PowerShell.SecretStore True

Actual

PS /> Test-SecretVault -name *
Test-SecretVault: Vault not found in registry: *

Expected

Should test all registered secret vaults.

Workaround

Get-SecretVault -Name * | Test-SecretVault

-AsPlainText with PSCredential secrets... is this a layering problem?

image

Right now, it doesn't do anything.

It makes sense because it's returning a PSCredential which can only be represented by a string username and SecureString password...

So either we leave it as is and -AsPlainText only works for some secret types... or

  1. We have some way to "show" the password of a PSCredential (maybe we attach a Note property or just return a username,password pscustomobject...)
  2. We remove -AsPlainText because ConvertFrom-SecureString is already available for this usecase

Set-AuthenticodeSignature should support Key Vault certificates

Today, signing PowerShell scripts/modules requires a certificate to be present in the certificate store or via a PFX file.

There's a growing number of situations where these are not available -- for example, if the key is stored in Key Vault an RSA-HSM key. There's no way to get a private key out.

There should be a way for PowerShell code signing to either use the KeyVault SignAsync API directly or at least have an extension mechanism where the sign digest can be externalized and someone else can write an adapter.

This also has the added benefit of working cross platform as the crypto itself is done in the HSM.

Have a way to view available additional parameters for a vault.

This is a suggestion.

For me, SecretManagement is about having a consistent way to access a ton of different providers in a consistend manner.
(Get-Secret / Set-Secret)

My only "pain point" is when it come to the registration of the vault.
I can try as is, but more often then not, I will need to check the documentation to determine what parameter can be used.

What if ...

There was something such as Get-SecretVaultRegistrationParameters that the implemented module could use to return a list of the available additional parameters ?

Example scenario
Example end user call:
(to determine how to register it)

Get-SecretVaultRegistrationParameters -ModuleName 'SecretManagement.AzKeyvault'

image

I would use that pretty much anytime before I register a vault since there's a lot of variation per module on that level.

Pre-requisites
The module creator wanting to provide this insight to the users would need to expose the optional Get-SecretVaultRegistrationParameters function and add the return values.

function Get-SecretVaultRegistrationParameters() {
    return @(
        [SecretParameterInfos]::new('SubscriptionId', 'Azure subscription id', $true)
        [SecretParameterInfos]::new('VaultName', 'Azure vault name', $true)
        [SecretParameterInfos]::new('SessionTimeout', "Determine the session timeout for the user.`nIf set to 0, default will be used", $false,'60 minutes')
    )    
}

If not implemented, then it could return a Not implemented exception and / or display a warning so a distinction can be made between not implemented or the fact there is just no parameter to configure.

Complete sample




# Example class for the purpose of this example... Although I am well aware c# would be used for that part.
class SecretParameterInfos {
    [String]$Name
    [String]$Description
    [bool]$Mandatory
    [String]$Default

    SecretParameterInfos($Name, $Description) {
        $this.Name = $Name
        $this.Description = $Description
    }

    SecretParameterInfos($Name, $Description, $Mandatory) {
        $this.Name = $Name
        $this.Description = $Description
        $this.Mandatory = $Mandatory
    }

    SecretParameterInfos($Name, $Description, $Mandatory,$Default) {
        $this.Name = $Name
        $this.Description = $Description
        $this.Mandatory = $Mandatory
        $this.Default = $Default
    }
}




#Declared in SecretManagement.MyModule.psm1 
function Get-SecretVaultRegistrationParameters() {
    return @(
        [SecretParameterInfos]::new('SubscriptionId', 'Azure subscription id', $true)
        [SecretParameterInfos]::new('VaultName', 'Azure vault name', $true)
        [SecretParameterInfos]::new('SessionTimeout', "Determine the session timeout for the user.`nIf set to 0, default will be used", $false,'60 minutes')
    )    
}

#End user that want to register a vault but want to know if there are available parameters to him
Get-SecretVaultRegistrationParameters -ModuleName 'SecretManagement.MyModule'

If you were to go even deeper, you could also imagine the main module using that list and making the registration fail if it have elements listed as Required but not provided by the user automatically.

That being said, the core of this suggestion is to have that piece of information embedded (provided the module owner implement it) and readily available without having to do back and forth always with the implemented modules documentations.

Thank you for considering this.

Passing SecureStringSecret to extensions from Set-Secret

When passing SeureStringSecrets to the SecretStore, the secret is placed in the SecretStore. What is passed from the Set-Secret cmdlet to the extension? I want to pick up the SecureString in my extension, but what should I expect?

Extensions should be able to hook into `Unregister-SecretVault`

Would like a way to have my extension called when Unregister-SecretVault is used with my extension. The scenario is I may want to clean up all the secrets stored via my vault from PowerShell.

KeyChain, for example, allows me to create a new keychain just for my extension that wouldn't be mixed with other secrets already stored in keychain for a user. If they unregister my extension, it would mean they no longer need to use it so I should clean out their secrets.

We would also need to decide if the user opts in or out of cleaning out those secrets by default.

Vaultparameters hashtable should be case insensitive.

Most of Powershell is case insensitive.
VaultParameters is taking in a Powershell hashtable but it is not case insensitive.

This will succed:

Register-SecretVault -ModuleName Az.Keyvault -VaultParameters @{ AZKVaultName= 'devops-cicd'; SubscriptionId = '<ID>' }

This will fail:

Register-SecretVault -ModuleName Az.Keyvault -VaultParameters @{ AZKVaultName= 'devops-cicd'; subscriptionId = '<ID>' }

will fail.

(If you're looking for the issue, "Subscriptionid" in the failing registration have its first 'S' in lower case.


# .Net C# code for SecretManagement
$SensitiveHT = [hashtable]::new()
$SensitiveHT.HELLO = 'WORLD'

#Return Null  :( 
$SensitiveHT.hello 

$PowershellHT = @{'HELLO'='WORLD'}
# Do not care about what anyone think (Insensitive)
# Return WORLD
$PowershellHT.hello 

# Expected .Net C# hashtable generation
$InsensitiveHT = [hashtable]::new([System.StringComparer]::CurrentCultureIgnoreCase)
$InsensitiveHT.HELLO = 'WORLD'

#Return WORLD
$InsensitiveHT.hello

Feature Request: VaultParameters as dynamic Parameters

A secret module could expose the common parameters it uses via a typed hashtable or even as dynamic params, and SecretManagement could present the parameters dynamically once the vaultname is selected.

For instance, if a KeePass extension defined a Path and MasterKey VaultParameters, then the following could be possible to do temporary overrides of the existing vault configuration, which could be more intuitive for specifying noninteractive parameters such as credentials.

Get-Secret -VaultName KeePass -Name MySecret -Path my\special\path -MasterKey (Get-Credential)

See InvokeBuild for an example of this in action, parameters defined in the build script are available to the Invoke-Build command.
https://github.com/nightroman/Invoke-Build/wiki/Script-Tutorial#script-parameters-for-tasks

Unregister-SecretVault : Item has already been added. Key in dictionary: 'verbose' Key being added: Verbose

image

There seems to be a bug with the implementation of #66.

Steps to reproduce :

Register-SecretVault -ModuleName secretmanagement.lastpass -VaultParameters @{lpassCommand = 'wsl'; verbose = $true } -Name 'lpt10'
Unregister-SecretVault -Name lpt10 

I used SecretManagement.Lastpass but I assume the actual module implementation is relevant and any valid module could be put in there

Issue:
I cannot unregister that keyvault anymore.

(In the end, I was able to remove the vault manually by tracking down the secretregistryvault location in the filesystem )

Import-module failes on WS2016

Import-module failes running PS 5.1 on Windows Server 2016.
I don't know if this is just my machine or related to WS2016.

PS H:\> import-module Microsoft.PowerShell.SecretManagement
import-module : Could not load file or assembly 'netstandard, Version=2.0.0.0, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51' or one of its dependencies. The system cannot find the file specified. At line:1 char:1 import-module Microsoft.PowerShell.SecretManagement CategoryInfo : NotSpecified: (:) [Import-Module], FileNotFoundException FullyQualifiedErrorId : System.IO.FileNotFoundException,Microsoft.PowerShell.Commands.ImportModuleCommand

PS H:\> $PSversiontable
Name Value PSVersion 5.1.14393.3471 PSEdition Desktop PSCompatibleVersions {1.0, 2.0, 3.0, 4.0...} BuildVersion 10.0.14393.3471 CLRVersion 4.0.30319.42000 WSManStackVersion 3.0 PSRemotingProtocolVersion 2.3 SerializationVersion 1.1.0.1

PS H:\> get-module Microsoft.PowerShell.SecretManagement -ListAvailable
Directory: C:\Program Files\WindowsPowerShell\Modules ModuleType Version Name ExportedCommands Binary 0.5.3 Microsoft.PowerShell.SecretManag... {Register-SecretVault, Unregister-SecretVault, Get-SecretV...

image

The single only available secret vault should be made default automatically

The single only available secret vault should be made default automatically.

When running Register-SecretVault -Name MyStore -ModuleName Microsoft.PowerShell.SecretStore or Unregister-SecretVault SecretStore, if the action results in only a single vault being present, then that vault should be made 'Default' automatically.

This will make the following scenario much intuitive:

## Register the very first vault

PS> Register-SecretVault -Name MyStore -ModuleName Microsoft.PowerShell.SecretStore
PS> Set-Secret -Name nuget -Secret abc
Set-Secret: Unable to set secret because no vault was provided and there is no default vault designated.

Should Register-SecretVault lock in the ModulePath where the ModuleName resides?

While doing development on a SecretManagement extension, a different instance of my module kept getting imported into my session and executed, rather than the one I placed earlier in the $PSModulePath. I finally figured out that the ModulePath property was saved with my registered secret vault, and that instance had priority running.

I did an Unregister-SecretVault & Register-SecretVault, which reset the ModulePath based on $PSModulePath and solved the strange import behavior.

My mindset was that the Register-SecretVault was semi-permanent and would not have to be reissued periodically.

Of course, having discovered this behavior, hopefully I'll recognize the symptoms if it crops up again.

Install-Module for SecretStore fails if using -Force

I want to add SecretManagement to a Linux Docker container running PS Core 7.0.3. Since I'm using a dockerfile to build the image, I need to use the -Force parameter to bypass the "Are you sure" question prompt.

The SecretManagement module installs just fine with -Force, but installing SecretStore throws the following error:

PS /nectar10> Install-Module Microsoft.PowerShell.SecretStore -AllowPrerelease -Force Install-Package: /opt/microsoft/powershell/7/Modules/PowerShellGet/PSModule.psm1:9709 Line | 9709 | … talledPackages = PackageManagement\Install-Package @PSBoundParameters | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
| Unable to find dependent module(s) (Microsoft.PowerShell.SecretManagement)

I get the same issue when running the container interactively. However, if I remove the -Force parameter, the module installs just fine after I press Y.

I can work around the issue by trusting the PSGallery store.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.