VaultTools.psm1

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
function New-VaultToken {
<#
.SYNOPSIS
Command to get a new token that represents a approle secret ID
.EXAMPLE
New-VaultToken -LdapCredential (Get-Credential) -Vault_Address 'https://vault' -Vault_Rolename 'some_role'
#>

    [CmdletBinding()]
    Param(
        [Parameter(Mandatory=$true)]
        [System.Management.Automation.PSCredential]$LdapCredential,

        [Parameter(Mandatory=$true)]
        [ValidateScript({$_ -match '^https'})]
        [ValidateScript({$_ -notmatch '/$' -and $_ -notmatch '/v1$'})]
        [string]$Vault_Address,

        [Parameter(Mandatory=$true)]
        [string]$Vault_Rolename
    )

    #Stop when an error comes up
    $ErrorActionPreference='Stop'

    #Addresses
    $VAULT_ROOT          = $Vault_Address + '/v1'
    $VAULT_LOGIN_LDAP    = $VAULT_ROOT+'/auth/ldap/login'
    $VAULT_LOGIN_APPROLE = $VAULT_ROOT+'/auth/approle/login'
    $VAULT_AUTH_APPROLE  = $VAULT_ROOT+'/auth/approle/role'
    $VAULT_ROLEID        = "$VAULT_AUTH_APPROLE/$Vault_RoleName/role-id"
    $VAULT_SECRETID      = "$VAULT_AUTH_APPROLE/$Vault_RoleName/secret-id"

    #Get token equivalent of $LdapCredential
    $Username = $LdapCredential.GetNetworkCredential().UserName
    $PlainPassword = $LdapCredential.GetNetworkCredential().Password
    $JsonBody = @{password = $PlainPassword} | ConvertTo-Json
    Write-Verbose "Authenticating $Username to $Vault_Address"
    $UserToken = (Invoke-RestMethod -Method 'Post' -Uri "$VAULT_LOGIN_LDAP/$Username" -Body $JsonBody).auth.client_token

    #Get Role ID of $Vault_RoleName
    $RoleID = (Invoke-RestMethod -Headers @{"X-Vault-Token"="$UserToken"} -Uri $VAULT_ROLEID).data.role_id

    #Get Secret ID of $Vault_RoleName
    $SecretID = (Invoke-RestMethod -Method 'Post' -Headers @{"X-Vault-Token"="$UserToken"} -Uri $VAULT_SECRETID).data.secret_id

    #Send the role ID and the secret ID and receive a new token for the secret ID of $Vault_RoleName
    $JsonBody = @{role_id=$RoleID;secret_id=$SecretID} | ConvertTo-Json
    [ValidateNotNullOrEmpty()]$Output = (Invoke-RestMethod -Method 'Post' -Uri "$VAULT_LOGIN_APPROLE" -Body $JsonBody).auth.client_token

    #Output
    $Output
}
function Save-VaultToken {
<#
.SYNOPSIS
Command to save a token representation of a approle secret ID to local encrypted file
.DESCRIPTION
This function retrieves a token representation of the secret ID for a vault rolename
The function then outputs the token into an encrypted file.
The file can only be opened on the computer and user account where it was created.
.EXAMPLE
Save-VaultToken -LdapCredential (Get-Credential) -Vault_Address 'https://vault' -Vault_Rolename 'some_role' -OutputPath 'c:\some_role_token.dat'
#>

    [CmdletBinding()]
    Param(
        [Parameter(Mandatory=$true)]
        [System.Management.Automation.PSCredential]$LdapCredential,

        [Parameter(Mandatory=$true)]
        [ValidateScript({$_ -match '^https'})]
        [ValidateScript({$_ -notmatch '/$' -and $_ -notmatch '/v1$'})]
        [string]$Vault_Address,

        [Parameter(Mandatory=$true)]
        [string]$Vault_Rolename,

        [Parameter(Mandatory=$true)]
        [string]$OutputPath
    )

    $ErrorActionPreference='Stop'
    $Verbose = $VerbosePreference -ne 'SilentlyContinue'

    #Get Token
    $OutputToken = New-VaultToken -LdapCredential $LdapCredential -Vault_Address $Vault_Address -Vault_Rolename $Vault_Rolename -Verbose:$Verbose

    #Output the token as encrypted file
    $SecureStringOutputToken = ConvertTo-SecureString -String $OutputToken -AsPlainText -Force
    [System.Management.Automation.PSCredential]::New('na',$SecureStringOutputToken) | Export-Clixml -Path $OutputPath
    Write-Verbose "Token saved to $OutputPath"
}
function Get-VaultValue {
<#
.SYNOPSIS
function to get a value for a key from the Vault Address
.DESCRIPTION
function to get a value for a key from the Vault Address
.PARAMETER Vault_Full_Address
The complete address to where the key is stored.
Example: https://myvault.com/v1/secret/data/mypath
.PARAMETER Vault_SavedTokenPath
The path to the saved token (OutputPath from Save-VaultToken function)
.PARAMETER Vault_Key
The name of the key you are trying to get the value from.
.EXAMPLE
Save-VaultToken -LdapCredential (Get-Credential) -Vault_Address 'https://myvault.com' -Vault_Rolename 'some_role' -OutputPath 'c:\some_role_token.dat'
Get-VaultValue -Vault_Full_Address 'https://myvault.com/v1/secret/data/mypath' -Vault_SavedTokenPath 'c:\some_role_token.dat' -Vault_Key 'mykey'
.EXAMPLE
$NewToken=New-VaultToken -LdapCredential (Get-Credential) -Vault_Address 'https://vault' -Vault_Rolename 'some_role'
Get-VaultValue -Vault_Full_Address 'https://myvault.com/v1/secret/data/mypath' -Vault_Token $NewToken -Vault_Key 'mykey'
#>

    [CmdletBinding()]
    Param(
        [Parameter(Mandatory=$true)]
        [ValidateScript({$_ -match '^https'})]
        [string]$Vault_Full_Address,

        [Parameter(Mandatory=$true,ParameterSetname='SavedToken')]
        [ValidateScript({Test-Path -Path $_})]
        [string]$Vault_SavedTokenPath,

        [Parameter(Mandatory=$true,ParameterSetName='NewToken')]
        [string]$Vault_Token,

        [Parameter(Mandatory=$true)]
        [string]$Vault_Key
    )

    $ErrorActionPreference = 'Stop'

    #Get Vault Token from locally encrypted dat file, otherwise it came from Param block
    if ($Vault_SavedTokenPath) {
        [ValidateNotNullOrEmpty()]$Vault_Token=(Import-CliXml -Path $Vault_SavedTokenPath).GetNetworkCredential().Password
    }

    #Get the Value that is associated with $Vault_Key from $Vault_Full_Address
    $InvokeRestMethodParams = @{
        Uri = $Vault_Full_Address
        Headers = @{"X-Vault-Token"="$Vault_Token"}
    }
    [ValidateNotNullOrEmpty()]$Output = (Invoke-RestMethod @InvokeRestMethodParams).data.data |
                                        Select-Object -ExpandProperty $Vault_Key

    #Output
    Return $Output
    Write-Verbose "Successfully retrieved value for $Vault_Key from $Vault_Full_Address"
}