Refactor secret management providers and introduce unified handling
- Removed KeePass and SecretStore provider implementations. - Integrated KeePass and SecretStore as vaults under the SecretManagement provider. - Added new functions: Get-DSCConfigurationDataCredentialProvider and Set-DSCConfigurationDataCredentialProvider for managing credential providers. - Implemented Unlock-ConfigurationDataSecretManagementVault to handle vault unlocking with master passwords. - Updated README to reflect changes in provider usage and examples. - Enhanced error handling and validation for vault registration and settings.
This commit is contained in:
@@ -1,10 +1,19 @@
|
||||
function Register-DSCConfigurationDataCredentialProvider {
|
||||
[CmdletBinding(SupportsShouldProcess=$true)]
|
||||
Param(
|
||||
[Parameter(Mandatory=$true)]
|
||||
[Parameter(Mandatory=$true, Position=1)]
|
||||
[string]
|
||||
$Vault,
|
||||
|
||||
[Parameter(Mandatory=$false)]
|
||||
[ValidateSet("Generic", "KeePass")]
|
||||
[string]
|
||||
$VaultType = "Generic",
|
||||
|
||||
[Parameter(Mandatory=$false)]
|
||||
[string]
|
||||
$DatabasePath,
|
||||
|
||||
[Parameter(Mandatory=$false)]
|
||||
[string]
|
||||
$KeyPath,
|
||||
@@ -13,10 +22,6 @@ function Register-DSCConfigurationDataCredentialProvider {
|
||||
[string]
|
||||
$SettingsPath,
|
||||
|
||||
[Parameter(Mandatory=$false)]
|
||||
[System.Security.SecureString]
|
||||
$MasterKey,
|
||||
|
||||
[Parameter(Mandatory=$false)]
|
||||
[string]
|
||||
$ModuleName,
|
||||
@@ -25,14 +30,6 @@ function Register-DSCConfigurationDataCredentialProvider {
|
||||
[hashtable]
|
||||
$VaultParameters = @{},
|
||||
|
||||
[Parameter(Mandatory=$false)]
|
||||
[string]
|
||||
$SubscriptionId,
|
||||
|
||||
[Parameter(Mandatory=$false)]
|
||||
[string]
|
||||
$TenantId,
|
||||
|
||||
[Parameter(Mandatory=$false)]
|
||||
[switch]
|
||||
$RegisterVault,
|
||||
@@ -47,25 +44,17 @@ function Register-DSCConfigurationDataCredentialProvider {
|
||||
|
||||
[Parameter(Mandatory=$false)]
|
||||
[switch]
|
||||
$ConfigureSecretStore,
|
||||
|
||||
[Parameter(Mandatory=$false)]
|
||||
[ValidateSet("None", "Password")]
|
||||
[string]
|
||||
$Authentication = "None",
|
||||
|
||||
[Parameter(Mandatory=$false)]
|
||||
[ValidateSet("None", "Prompt")]
|
||||
[string]
|
||||
$Interaction = "None",
|
||||
$UseMasterPassword,
|
||||
|
||||
[Parameter(Mandatory=$false)]
|
||||
[Alias("MasterKey")]
|
||||
[System.Security.SecureString]
|
||||
$Password,
|
||||
$MasterPassword,
|
||||
|
||||
[Parameter(Mandatory=$false)]
|
||||
[int]
|
||||
$PasswordTimeout,
|
||||
[Alias("MasterKeyPath")]
|
||||
[string]
|
||||
$MasterPasswordKeyPath,
|
||||
|
||||
[Parameter(Mandatory=$false)]
|
||||
[switch]
|
||||
@@ -120,63 +109,98 @@ function Register-DSCConfigurationDataCredentialProvider {
|
||||
|
||||
process {
|
||||
switch($Provider){
|
||||
"KeePass" {
|
||||
if([string]::IsNullOrWhiteSpace($KeyPath)){
|
||||
throw "Provider [KeePass] requires [KeyPath]."
|
||||
}
|
||||
|
||||
if($null -eq $MasterKey){
|
||||
$MasterKey = Read-Host -Prompt "KeePass MasterKey for vault [$Vault]" -AsSecureString
|
||||
}
|
||||
|
||||
if($PSCmdlet.ShouldProcess($SettingsPath, "Create provider settings for [$Provider]")){
|
||||
$Key = New-ConfigurationDataAesKeyFile -Path $KeyPath -Force:$Force
|
||||
$ProtectedValue = $MasterKey | ConvertFrom-SecureString -Key $Key
|
||||
|
||||
$ProviderSettings = [ordered]@{
|
||||
KeePass = [ordered]@{
|
||||
DefaultVault = $Vault
|
||||
MasterKey = [ordered]@{
|
||||
ProtectedValue = $ProtectedValue
|
||||
KeyPath = $KeyPath
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Export-PowerShellDataFile -InputObject $ProviderSettings -Path $SettingsPath -Force:$Force
|
||||
|
||||
if($PassThru){
|
||||
return $ProviderSettings
|
||||
}
|
||||
|
||||
Write-Verbose "Provider settings written to [$SettingsPath]."
|
||||
}
|
||||
}
|
||||
"SecretManagement" {
|
||||
if([string]::IsNullOrWhiteSpace($ModuleName)){
|
||||
$ModuleName = "Microsoft.PowerShell.SecretStore"
|
||||
if($VaultType -eq "KeePass"){
|
||||
$ModuleName = "SecretManagement.KeePass"
|
||||
}else{
|
||||
$ModuleName = "Microsoft.PowerShell.SecretStore"
|
||||
}
|
||||
}
|
||||
|
||||
if($RegisterVault -or $PSBoundParameters.ContainsKey("ModuleName")){
|
||||
$CommandParameters = @{
|
||||
Name = $Vault
|
||||
ModuleName = $ModuleName
|
||||
$ShouldRegisterVault = $RegisterVault -or $PSBoundParameters.ContainsKey("ModuleName")
|
||||
|
||||
if($VaultType -eq "KeePass" -and $ShouldRegisterVault){
|
||||
if([string]::IsNullOrWhiteSpace($DatabasePath) -and -not $VaultParameters.ContainsKey("Path")){
|
||||
throw "SecretManagement KeePass vault registration requires [DatabasePath] or VaultParameters['Path']."
|
||||
}
|
||||
|
||||
if($VaultParameters.Count -gt 0){
|
||||
$CommandParameters["VaultParameters"] = $VaultParameters
|
||||
if(-not [string]::IsNullOrWhiteSpace($DatabasePath)){
|
||||
$VaultParameters["Path"] = $DatabasePath
|
||||
}
|
||||
|
||||
if($DefaultVault){
|
||||
$CommandParameters["DefaultVault"] = $true
|
||||
if(-not [string]::IsNullOrWhiteSpace($KeyPath)){
|
||||
$VaultParameters["KeyPath"] = $KeyPath
|
||||
}
|
||||
|
||||
if($AllowClobber){
|
||||
$CommandParameters["AllowClobber"] = $true
|
||||
if($UseMasterPassword){
|
||||
$VaultParameters["UseMasterPassword"] = $true
|
||||
}
|
||||
}
|
||||
|
||||
if($PSCmdlet.ShouldProcess($Vault, "Register SecretManagement vault [$ModuleName]")){
|
||||
Register-SecretVault @CommandParameters
|
||||
if($ShouldRegisterVault){
|
||||
if($VaultType -eq "KeePass"){
|
||||
$KeePassModule = Get-Module -Name SecretManagement.KeePass -ListAvailable | Sort-Object -Property Version -Descending | Select-Object -First 1
|
||||
if($null -eq $KeePassModule){
|
||||
throw "SecretManagement KeePass vault registration requires module [SecretManagement.KeePass]."
|
||||
}
|
||||
|
||||
$ModuleReference = $KeePassModule.Name
|
||||
if(-not [string]::IsNullOrWhiteSpace($KeePassModule.Path)){
|
||||
$ModuleReference = $KeePassModule.Path
|
||||
}
|
||||
|
||||
$CommandParameters = @{
|
||||
Name = $Vault
|
||||
ModuleName = $ModuleReference
|
||||
VaultParameters = @{
|
||||
Path = $VaultParameters["Path"]
|
||||
UseMasterPassword = $false
|
||||
UseWindowsAccount = $false
|
||||
KeyPath = $null
|
||||
ShowFullTitle = $false
|
||||
ShowRecycleBin = $false
|
||||
}
|
||||
}
|
||||
|
||||
foreach($Key in @("KeyPath", "UseMasterPassword", "UseWindowsAccount", "ShowFullTitle", "ShowRecycleBin", "SkipValidate")){
|
||||
if($VaultParameters.ContainsKey($Key)){
|
||||
$CommandParameters.VaultParameters[$Key] = $VaultParameters[$Key]
|
||||
}
|
||||
}
|
||||
|
||||
if($DefaultVault){
|
||||
$CommandParameters["DefaultVault"] = $true
|
||||
}
|
||||
|
||||
if($AllowClobber){
|
||||
$CommandParameters["AllowClobber"] = $true
|
||||
}
|
||||
|
||||
if($PSCmdlet.ShouldProcess($Vault, "Register KeePass SecretManagement vault [$ModuleReference]")){
|
||||
Register-SecretVault @CommandParameters
|
||||
}
|
||||
}else{
|
||||
$CommandParameters = @{
|
||||
Name = $Vault
|
||||
ModuleName = $ModuleName
|
||||
}
|
||||
|
||||
if($VaultParameters.Count -gt 0){
|
||||
$CommandParameters["VaultParameters"] = $VaultParameters
|
||||
}
|
||||
|
||||
if($DefaultVault){
|
||||
$CommandParameters["DefaultVault"] = $true
|
||||
}
|
||||
|
||||
if($AllowClobber){
|
||||
$CommandParameters["AllowClobber"] = $true
|
||||
}
|
||||
|
||||
if($PSCmdlet.ShouldProcess($Vault, "Register SecretManagement vault [$ModuleName]")){
|
||||
Register-SecretVault @CommandParameters
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -186,80 +210,21 @@ function Register-DSCConfigurationDataCredentialProvider {
|
||||
}
|
||||
}
|
||||
|
||||
if($PSCmdlet.ShouldProcess($SettingsPath, "Create provider settings for [$Provider]")){
|
||||
Export-PowerShellDataFile -InputObject $ProviderSettings -Path $SettingsPath -Force:$Force
|
||||
if($VaultType -ne "Generic"){
|
||||
$ProviderSettings.SecretManagement["VaultType"] = $VaultType
|
||||
}
|
||||
|
||||
if($PassThru){
|
||||
return $ProviderSettings
|
||||
}
|
||||
}
|
||||
"SecretStore" {
|
||||
if($ConfigureSecretStore){
|
||||
$CommandParameters = @{
|
||||
Authentication = $Authentication
|
||||
Interaction = $Interaction
|
||||
if($null -ne $MasterPassword){
|
||||
if([string]::IsNullOrWhiteSpace($MasterPasswordKeyPath)){
|
||||
throw "MasterPassword requires [MasterPasswordKeyPath]."
|
||||
}
|
||||
|
||||
if($null -ne $Password){
|
||||
$CommandParameters["Password"] = $Password
|
||||
$Key = New-ConfigurationDataAesKeyFile -Path $MasterPasswordKeyPath -Force:$Force
|
||||
$ProtectedValue = $MasterPassword | ConvertFrom-SecureString -Key $Key
|
||||
$ProviderSettings.SecretManagement["MasterPassword"] = [ordered]@{
|
||||
ProtectedValue = $ProtectedValue
|
||||
KeyPath = $MasterPasswordKeyPath
|
||||
}
|
||||
|
||||
if($PasswordTimeout -gt 0){
|
||||
$CommandParameters["PasswordTimeout"] = $PasswordTimeout
|
||||
}
|
||||
|
||||
if($PSCmdlet.ShouldProcess("SecretStore", "Configure local SecretStore")){
|
||||
Set-SecretStoreConfiguration @CommandParameters -Confirm:$false
|
||||
}
|
||||
}
|
||||
|
||||
if($RegisterVault){
|
||||
$CommandParameters = @{
|
||||
Name = $Vault
|
||||
ModuleName = "Microsoft.PowerShell.SecretStore"
|
||||
}
|
||||
|
||||
if($DefaultVault){
|
||||
$CommandParameters["DefaultVault"] = $true
|
||||
}
|
||||
|
||||
if($AllowClobber){
|
||||
$CommandParameters["AllowClobber"] = $true
|
||||
}
|
||||
|
||||
if($PSCmdlet.ShouldProcess($Vault, "Register SecretStore vault")){
|
||||
Register-SecretVault @CommandParameters
|
||||
}
|
||||
}
|
||||
|
||||
$ProviderSettings = [ordered]@{
|
||||
SecretStore = [ordered]@{
|
||||
DefaultVault = $Vault
|
||||
}
|
||||
}
|
||||
|
||||
if($PSCmdlet.ShouldProcess($SettingsPath, "Create provider settings for [$Provider]")){
|
||||
Export-PowerShellDataFile -InputObject $ProviderSettings -Path $SettingsPath -Force:$Force
|
||||
}
|
||||
|
||||
if($PassThru){
|
||||
return $ProviderSettings
|
||||
}
|
||||
}
|
||||
"AzureKeyVault" {
|
||||
$ProviderSettings = [ordered]@{
|
||||
AzureKeyVault = [ordered]@{
|
||||
DefaultVault = $Vault
|
||||
}
|
||||
}
|
||||
|
||||
if(-not [string]::IsNullOrWhiteSpace($SubscriptionId)){
|
||||
$ProviderSettings["AzureKeyVault"]["SubscriptionId"] = $SubscriptionId
|
||||
}
|
||||
|
||||
if(-not [string]::IsNullOrWhiteSpace($TenantId)){
|
||||
$ProviderSettings["AzureKeyVault"]["TenantId"] = $TenantId
|
||||
}
|
||||
|
||||
if($PSCmdlet.ShouldProcess($SettingsPath, "Create provider settings for [$Provider]")){
|
||||
|
||||
Reference in New Issue
Block a user