Octopus.Script exported 2022-09-18 by harrisonmeister belongs to ‘HashiCorp Vault’ category.
This step retrieves (and unwraps) a Secret ID for an AppRole using a wrapped auth token from a HashiCorp Vault server.
One property from the response will be made available as a sensitive Output variable:
data.secret_id
- This is the unwrapped Secret ID from Vault. The output variable name will beUnwrappedSecretID
.
This step template makes use of the Rest API, so no other dependencies are needed.
Required:
- The Vault server must be unsealed.
- The wrapped auth token used to retrieve the unwrapped Secret ID.
Optional
- The creation path of the wrapped token. If this parameter value is provided, the step template will perform a wrapping lookup to validate no malfeasance has occurred.
- A Vault namespace to use. Nested namespaces can also be supplied, e.g.
ns1/ns2
. Note: This field is only supported on Vault Enterprise.
Notes:
- Tested on Vault Server
1.11.3
. - Tested on both PowerShell Desktop and PowerShell Core.
- See the HashiCorp AppRole patterns documentation for further information.
Parameters
When steps based on the template are included in a project’s deployment process, the parameters below can be set.
Vault Server URL
Vault.AppRole.UnwrapSecretID.VaultAddress =
The URL of the Vault instance you are connecting to. Port should be included (The default is 8200
). For example:
https://myvault.local:8200/
API version
Vault.AppRole.UnwrapSecretID.ApiVersion = v1
All API routes are prefixed with a version e.g. /v1/
.
See the API documentation for further details.
Namespace (Optional)
Vault.AppRole.UnwrapSecretID.Namespace =
The optional namespace to use. Nested namespaces can also be supplied, e.g. ns1/ns2
.
Note: This field is only supported on Vault Enterprise .
Wrapped Token
Vault.AppRole.UnwrapSecretID.WrappedToken =
This is the wrapped token used to retrieve the actual Secret ID from Vault.
Token Creation Path
Vault.AppRole.UnwrapSecretID.WrappedTokenCreationPath =
Optional - the creation path of the wrapped token. If this parameter value is provided, the step template will perform a wrapping lookup to validate no malfeasance has occurred.
Script body
Steps based on this template will execute the following PowerShell script.
[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12
# Variables
$VAULT_APPROLE_UNWRAP_SECRETID_ADDRESS = $OctopusParameters["Vault.AppRole.UnwrapSecretID.VaultAddress"]
$VAULT_APPROLE_UNWRAP_SECRETID_API_VERSION = $OctopusParameters["Vault.AppRole.UnwrapSecretID.ApiVersion"]
$VAULT_APPROLE_UNWRAP_SECRETID_TOKEN = $OctopusParameters["Vault.AppRole.UnwrapSecretID.WrappedToken"]
# Optional Variables
$VAULT_APPROLE_UNWRAP_SECRETID_NAMESPACE = $OctopusParameters["Vault.AppRole.UnwrapSecretID.Namespace"]
$VAULT_APPROLE_UNWRAP_SECRETID_TOKEN_CREATION_PATH = $OctopusParameters["Vault.AppRole.UnwrapSecretID.WrappedTokenCreationPath"]
# Validation
if ([string]::IsNullOrWhiteSpace($VAULT_APPROLE_UNWRAP_SECRETID_ADDRESS)) {
throw "Required parameter VAULT_APPROLE_UNWRAP_SECRETID_ADDRESS not specified"
}
if ([string]::IsNullOrWhiteSpace($VAULT_APPROLE_UNWRAP_SECRETID_API_VERSION)) {
throw "Required parameter VAULT_APPROLE_UNWRAP_SECRETID_API_VERSION not specified"
}
if ([string]::IsNullOrWhiteSpace($VAULT_APPROLE_UNWRAP_SECRETID_TOKEN)) {
throw "Required parameter VAULT_APPROLE_UNWRAP_SECRETID_TOKEN not specified"
}
# Helper functions
###############################################################################
function Get-WebRequestErrorBody {
param (
$RequestError
)
# Powershell < 6 you can read the Exception
if ($PSVersionTable.PSVersion.Major -lt 6) {
if ($RequestError.Exception.Response) {
$reader = New-Object System.IO.StreamReader($RequestError.Exception.Response.GetResponseStream())
$reader.BaseStream.Position = 0
$reader.DiscardBufferedData()
$rawResponse = $reader.ReadToEnd()
$response = ""
try { $response = $rawResponse | ConvertFrom-Json } catch { $response = $rawResponse }
return $response
}
}
else {
return $RequestError.ErrorDetails.Message
}
}
###############################################################################
$VAULT_APPROLE_UNWRAP_SECRETID_ADDRESS = $VAULT_APPROLE_UNWRAP_SECRETID_ADDRESS.TrimEnd('/')
# Local variables
$StepName = $OctopusParameters["Octopus.Step.Name"]
try {
Write-Verbose "X-Vault-Namespace header: $VAULT_APPROLE_UNWRAP_SECRETID_NAMESPACE"
# Should we validate lookup token's creation path?
if (![string]::IsNullOrWhiteSpace($VAULT_APPROLE_UNWRAP_SECRETID_TOKEN_CREATION_PATH)) {
$uri = "$VAULT_APPROLE_UNWRAP_SECRETID_ADDRESS/$VAULT_APPROLE_UNWRAP_SECRETID_API_VERSION/sys/wrapping/lookup"
$payload = @{
token = $VAULT_APPROLE_UNWRAP_SECRETID_TOKEN
}
$Headers = @{}
if (-not [string]::IsNullOrWhiteSpace($VAULT_APPROLE_UNWRAP_SECRETID_NAMESPACE)) {
$Headers.Add("X-Vault-Namespace", $VAULT_APPROLE_UNWRAP_SECRETID_NAMESPACE)
}
Write-Verbose "Making Post request to $uri"
$response = Invoke-RestMethod -Uri $uri -Method Post -Body ($payload | ConvertTo-Json -Depth 10) -Headers $Headers
if ($null -ne $response) {
Write-Verbose "Validating Wrapped token creation path."
$Lookup_CreationPath = $response.data.creation_path
if ($VAULT_APPROLE_UNWRAP_SECRETID_TOKEN_CREATION_PATH -ne $Lookup_CreationPath) {
throw "Supplied Wrapped token creation path failed lookup validation. Check the creation path value and retry."
}
}
else {
Write-Error "Null or Empty response returned from Vault server lookup" -Category InvalidResult
}
}
# Call to unwrap secret id from wrapped token.
$Headers = @{
"X-Vault-Token" = $VAULT_APPROLE_UNWRAP_SECRETID_TOKEN
}
if (-not [string]::IsNullOrWhiteSpace($VAULT_APPROLE_UNWRAP_SECRETID_NAMESPACE)) {
$Headers.Add("X-Vault-Namespace", $VAULT_APPROLE_UNWRAP_SECRETID_NAMESPACE)
}
$uri = "$VAULT_APPROLE_UNWRAP_SECRETID_ADDRESS/$VAULT_APPROLE_UNWRAP_SECRETID_API_VERSION/sys/wrapping/unwrap"
Write-Verbose "Making Post request to $uri"
$response = Invoke-RestMethod -Uri $uri -Headers $Headers -Method Post
if ($null -ne $response) {
Set-OctopusVariable -Name "UnwrappedSecretID" -Value $response.data.secret_id -Sensitive
Write-Host "Created output variable: ##{Octopus.Action[$StepName].Output.UnwrappedSecretID}"
}
else {
Write-Error "Null or Empty response returned from Vault server unwrap" -Category InvalidResult
}
}
catch {
$ExceptionMessage = $_.Exception.Message
$ErrorBody = Get-WebRequestErrorBody -RequestError $_
$Message = "An error occurred unwrapping secretid: $ExceptionMessage"
$AdditionalDetail = ""
if (![string]::IsNullOrWhiteSpace($ErrorBody)) {
if ($null -ne $ErrorBody.errors) {
$AdditionalDetail = $ErrorBody.errors -Join ","
}
else {
$errorDetails = $null
try { $errorDetails = ConvertFrom-Json $ErrorBody } catch {}
$AdditionalDetail += if ($null -ne $errorDetails) { $errorDetails.errors -Join "," } else { $ErrorBody }
}
}
if (![string]::IsNullOrWhiteSpace($AdditionalDetail)) {
$Message += "`n`tDetail: $AdditionalDetail"
}
Write-Error $Message -Category ConnectionError
}
Provided under the Apache License version 2.0.
To use this template in Octopus Deploy, copy the JSON below and paste it into the Library → Step templates → Import dialog.
{
"Id": "c1f56030-0bcd-458d-bc70-b4f43ec0d30f",
"Name": "HashiCorp Vault - AppRole Unwrap Secret ID",
"Description": "This step retrieves (and unwraps) a Secret ID for an [AppRole](https://www.vaultproject.io/docs/auth/approle) using a wrapped auth token from a HashiCorp Vault server.\n\n---\n\nOne property from the response will be made available as a [sensitive Output variable](https://octopus.com/docs/projects/variables/output-variables#sensitive-output-variables):\n\n- `data.secret_id` - This is the unwrapped Secret ID from Vault. The output variable name will be `UnwrappedSecretID`.\n\nThis step template makes use of the [Rest API](https://www.vaultproject.io/api-docs/auth/approle#login-with-approle), so no other dependencies are needed. \n\n---\n\n**Required:** \n- The Vault server must be [unsealed](https://www.vaultproject.io/docs/concepts/seal).\n- The wrapped [auth token](https://www.vaultproject.io/docs/auth/token) used to retrieve the unwrapped Secret ID. \n\n---\n\n*Optional*\n- The creation path of the wrapped token. If this parameter value is provided, the step template will perform a [wrapping lookup](https://www.vaultproject.io/api-docs/system/wrapping-lookup) to [validate no malfeasance](https://www.vaultproject.io/docs/concepts/response-wrapping#response-wrapping-token-validation) has occurred.\n- A Vault [namespace](https://www.vaultproject.io/docs/enterprise/namespaces) to use. Nested namespaces can also be supplied, e.g. `ns1/ns2`. **Note:** This field is only supported on [Vault Enterprise](https://www.hashicorp.com/products/vault).\n\n---\n\nNotes:\n\n- Tested on Vault Server `1.11.3`.\n- Tested on both PowerShell Desktop and PowerShell Core.\n- See the HashiCorp [AppRole patterns documentation](https://learn.hashicorp.com/tutorials/vault/pattern-approle?in=vault/recommended-patterns#vault-returns-a-token) for further information.",
"Version": 4,
"ExportedAt": "2022-09-18T09:22:26.156Z",
"ActionType": "Octopus.Script",
"Author": "harrisonmeister",
"Packages": [],
"Parameters": [
{
"Id": "b30bafd3-a5b6-4c26-8eea-af938f5ba7da",
"Name": "Vault.AppRole.UnwrapSecretID.VaultAddress",
"Label": "Vault Server URL",
"HelpText": "The URL of the Vault instance you are connecting to. Port should be included (The default is `8200`). For example:\n\n\n`https://myvault.local:8200/`",
"DefaultValue": "",
"DisplaySettings": {
"Octopus.ControlType": "SingleLineText"
}
},
{
"Id": "a810fce1-3180-4eb8-b342-8b2d76a39667",
"Name": "Vault.AppRole.UnwrapSecretID.ApiVersion",
"Label": "API version",
"HelpText": "All API routes are prefixed with a version e.g. `/v1/`.\n\nSee the [API documentation](https://www.vaultproject.io/api-docs) for further details.",
"DefaultValue": "v1",
"DisplaySettings": {
"Octopus.ControlType": "Select",
"Octopus.SelectOptions": "v1|v1"
}
},
{
"Id": "e60b5c0b-dacc-4a99-8907-82e57eb9f573",
"Name": "Vault.AppRole.UnwrapSecretID.Namespace",
"Label": "Namespace (Optional)",
"HelpText": "The _optional_ [namespace](https://www.vaultproject.io/docs/enterprise/namespaces) to use. Nested namespaces can also be supplied, e.g. `ns1/ns2`.\n\n**Note:** This field is only supported on [Vault Enterprise](https://www.hashicorp.com/products/vault) .",
"DefaultValue": "",
"DisplaySettings": {
"Octopus.ControlType": "SingleLineText"
}
},
{
"Id": "6fd2fe01-9600-4ccc-a3f2-f733af79a255",
"Name": "Vault.AppRole.UnwrapSecretID.WrappedToken",
"Label": "Wrapped Token",
"HelpText": "This is the wrapped token used to retrieve the actual Secret ID from Vault.",
"DefaultValue": "",
"DisplaySettings": {
"Octopus.ControlType": "Sensitive"
}
},
{
"Id": "6dc8f829-c89c-403f-805c-350710d8d855",
"Name": "Vault.AppRole.UnwrapSecretID.WrappedTokenCreationPath",
"Label": "Token Creation Path",
"HelpText": "*Optional* - the creation path of the wrapped token. If this parameter value is provided, the step template will perform a [wrapping lookup](https://www.vaultproject.io/api-docs/system/wrapping-lookup) to [validate no malfeasance](https://www.vaultproject.io/docs/concepts/response-wrapping#response-wrapping-token-validation) has occurred.",
"DefaultValue": "",
"DisplaySettings": {
"Octopus.ControlType": "SingleLineText"
}
}
],
"Properties": {
"Octopus.Action.Script.ScriptSource": "Inline",
"Octopus.Action.Script.Syntax": "PowerShell",
"Octopus.Action.Script.ScriptBody": "[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12\n\n# Variables\n$VAULT_APPROLE_UNWRAP_SECRETID_ADDRESS = $OctopusParameters[\"Vault.AppRole.UnwrapSecretID.VaultAddress\"]\n$VAULT_APPROLE_UNWRAP_SECRETID_API_VERSION = $OctopusParameters[\"Vault.AppRole.UnwrapSecretID.ApiVersion\"]\n$VAULT_APPROLE_UNWRAP_SECRETID_TOKEN = $OctopusParameters[\"Vault.AppRole.UnwrapSecretID.WrappedToken\"]\n\n# Optional Variables\n$VAULT_APPROLE_UNWRAP_SECRETID_NAMESPACE = $OctopusParameters[\"Vault.AppRole.UnwrapSecretID.Namespace\"]\n$VAULT_APPROLE_UNWRAP_SECRETID_TOKEN_CREATION_PATH = $OctopusParameters[\"Vault.AppRole.UnwrapSecretID.WrappedTokenCreationPath\"]\n\n# Validation\nif ([string]::IsNullOrWhiteSpace($VAULT_APPROLE_UNWRAP_SECRETID_ADDRESS)) {\n throw \"Required parameter VAULT_APPROLE_UNWRAP_SECRETID_ADDRESS not specified\"\n}\nif ([string]::IsNullOrWhiteSpace($VAULT_APPROLE_UNWRAP_SECRETID_API_VERSION)) {\n throw \"Required parameter VAULT_APPROLE_UNWRAP_SECRETID_API_VERSION not specified\"\n}\n\nif ([string]::IsNullOrWhiteSpace($VAULT_APPROLE_UNWRAP_SECRETID_TOKEN)) {\n throw \"Required parameter VAULT_APPROLE_UNWRAP_SECRETID_TOKEN not specified\"\n}\n\n# Helper functions\n###############################################################################\nfunction Get-WebRequestErrorBody {\n param (\n $RequestError\n )\n\n # Powershell < 6 you can read the Exception\n if ($PSVersionTable.PSVersion.Major -lt 6) {\n if ($RequestError.Exception.Response) {\n $reader = New-Object System.IO.StreamReader($RequestError.Exception.Response.GetResponseStream())\n $reader.BaseStream.Position = 0\n $reader.DiscardBufferedData()\n $rawResponse = $reader.ReadToEnd()\n $response = \"\"\n try { $response = $rawResponse | ConvertFrom-Json } catch { $response = $rawResponse }\n return $response\n }\n }\n else {\n return $RequestError.ErrorDetails.Message\n }\n}\n###############################################################################\n\n$VAULT_APPROLE_UNWRAP_SECRETID_ADDRESS = $VAULT_APPROLE_UNWRAP_SECRETID_ADDRESS.TrimEnd('/')\n\n# Local variables\n$StepName = $OctopusParameters[\"Octopus.Step.Name\"]\n\ntry {\n\n Write-Verbose \"X-Vault-Namespace header: $VAULT_APPROLE_UNWRAP_SECRETID_NAMESPACE\"\n\n # Should we validate lookup token's creation path?\n if (![string]::IsNullOrWhiteSpace($VAULT_APPROLE_UNWRAP_SECRETID_TOKEN_CREATION_PATH)) {\n $uri = \"$VAULT_APPROLE_UNWRAP_SECRETID_ADDRESS/$VAULT_APPROLE_UNWRAP_SECRETID_API_VERSION/sys/wrapping/lookup\" \n $payload = @{\n token = $VAULT_APPROLE_UNWRAP_SECRETID_TOKEN\n }\n\n $Headers = @{}\n if (-not [string]::IsNullOrWhiteSpace($VAULT_APPROLE_UNWRAP_SECRETID_NAMESPACE)) {\n $Headers.Add(\"X-Vault-Namespace\", $VAULT_APPROLE_UNWRAP_SECRETID_NAMESPACE)\n }\n\n Write-Verbose \"Making Post request to $uri\"\n $response = Invoke-RestMethod -Uri $uri -Method Post -Body ($payload | ConvertTo-Json -Depth 10) -Headers $Headers\n\n if ($null -ne $response) {\n Write-Verbose \"Validating Wrapped token creation path.\"\n $Lookup_CreationPath = $response.data.creation_path\n if ($VAULT_APPROLE_UNWRAP_SECRETID_TOKEN_CREATION_PATH -ne $Lookup_CreationPath) {\n throw \"Supplied Wrapped token creation path failed lookup validation. Check the creation path value and retry.\"\n }\n }\n else {\n Write-Error \"Null or Empty response returned from Vault server lookup\" -Category InvalidResult\n }\n }\n\n # Call to unwrap secret id from wrapped token.\n $Headers = @{\n \"X-Vault-Token\" = $VAULT_APPROLE_UNWRAP_SECRETID_TOKEN\n }\n\n if (-not [string]::IsNullOrWhiteSpace($VAULT_APPROLE_UNWRAP_SECRETID_NAMESPACE)) {\n $Headers.Add(\"X-Vault-Namespace\", $VAULT_APPROLE_UNWRAP_SECRETID_NAMESPACE)\n }\n \n $uri = \"$VAULT_APPROLE_UNWRAP_SECRETID_ADDRESS/$VAULT_APPROLE_UNWRAP_SECRETID_API_VERSION/sys/wrapping/unwrap\"\n Write-Verbose \"Making Post request to $uri\"\n $response = Invoke-RestMethod -Uri $uri -Headers $Headers -Method Post\n \n if ($null -ne $response) {\n Set-OctopusVariable -Name \"UnwrappedSecretID\" -Value $response.data.secret_id -Sensitive\n Write-Host \"Created output variable: ##{Octopus.Action[$StepName].Output.UnwrappedSecretID}\"\n }\n else {\n Write-Error \"Null or Empty response returned from Vault server unwrap\" -Category InvalidResult\n }\n}\ncatch {\n $ExceptionMessage = $_.Exception.Message\n $ErrorBody = Get-WebRequestErrorBody -RequestError $_\n $Message = \"An error occurred unwrapping secretid: $ExceptionMessage\"\n $AdditionalDetail = \"\"\n if (![string]::IsNullOrWhiteSpace($ErrorBody)) {\n if ($null -ne $ErrorBody.errors) {\n $AdditionalDetail = $ErrorBody.errors -Join \",\" \n }\n else {\n $errorDetails = $null\n try { $errorDetails = ConvertFrom-Json $ErrorBody } catch {}\n $AdditionalDetail += if ($null -ne $errorDetails) { $errorDetails.errors -Join \",\" } else { $ErrorBody } \n }\n }\n \n if (![string]::IsNullOrWhiteSpace($AdditionalDetail)) {\n $Message += \"`n`tDetail: $AdditionalDetail\"\n }\n\n Write-Error $Message -Category ConnectionError\n}"
},
"Category": "HashiCorp Vault",
"HistoryUrl": "https://github.com/OctopusDeploy/Library/commits/master/step-templates//opt/buildagent/work/75443764cd38076d/step-templates/hashicorp-vault-approle-unwrap-secretid.json",
"Website": "/step-templates/c1f56030-0bcd-458d-bc70-b4f43ec0d30f",
"Logo": "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",
"$Meta": {
"Type": "ActionTemplate"
}
}
Page updated on Sunday, September 18, 2022