HashiCorp Vault - LDAP Login

Octopus.Script exported 2022-09-18 by harrisonmeister belongs to ‘HashiCorp Vault’ category.

This step logs into a HashiCorp Vault server using the LDAP auth method.

The client_token from the response will be made available as a sensitive Output variable named LDAPAuthToken for use in other step templates.

This step template makes use of the Rest API, so no other dependencies are needed.

Required:

  • The Vault server must be unsealed.
  • You must supply the full path where the LDAP auth method is mounted.
  • You must supply both a Username and Password.

Optional:

  • 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.

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.LDAP.Login.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.LDAP.Login.ApiVersion = v1

All API routes are prefixed with a version e.g. /v1/.

See the API documentation for further details.

Namespace (Optional)

Vault.LDAP.Login.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 .

LDAP Auth Login path

Vault.LDAP.Login.AuthPath = /auth/ldap

The path that the LDAP method is mounted at. The default is /auth/ldap. If the LDAP auth method was enabled at a different path, for example my-path, then specify /my-path instead.

Username

Vault.LDAP.Login.Username =

The LDAP Username.

LDAP Password

Vault.LDAP.Login.Password =

The LDAP Password.

Script body

Steps based on this template will execute the following PowerShell script.

[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12

# Variables
$VAULT_LDAP_LOGIN_ADDRESS = $OctopusParameters["Vault.LDAP.Login.VaultAddress"]
$VAULT_LDAP_LOGIN_API_VERSION = $OctopusParameters["Vault.LDAP.Login.ApiVersion"]
$VAULT_LDAP_LOGIN_NAMESPACE = $OctopusParameters["Vault.LDAP.Login.Namespace"]
$VAULT_LDAP_LOGIN_AUTH_PATH = $OctopusParameters["Vault.LDAP.Login.AuthPath"]
$VAULT_LDAP_LOGIN_USERNAME = $OctopusParameters["Vault.LDAP.Login.Username"]
$VAULT_LDAP_LOGIN_PASSWORD = $OctopusParameters["Vault.LDAP.Login.Password"]

# Validation
if ([string]::IsNullOrWhiteSpace($VAULT_LDAP_LOGIN_ADDRESS)) {
    throw "Required parameter VAULT_LDAP_LOGIN_ADDRESS not specified"
}
if ([string]::IsNullOrWhiteSpace($VAULT_LDAP_LOGIN_API_VERSION)) {
    throw "Required parameter VAULT_LDAP_LOGIN_API_VERSION not specified"
}
if ([string]::IsNullOrWhiteSpace($VAULT_LDAP_LOGIN_AUTH_PATH)) {
    throw "Required parameter VAULT_LDAP_LOGIN_AUTH_PATH not specified"
}
if ([string]::IsNullOrWhiteSpace($VAULT_LDAP_LOGIN_USERNAME)) {
    throw "Required parameter VAULT_LDAP_LOGIN_USERNAME not specified"
}
if ([string]::IsNullOrWhiteSpace($VAULT_LDAP_LOGIN_PASSWORD)) {
    throw "Required parameter VAULT_LDAP_LOGIN_PASSWORD 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_LDAP_LOGIN_ADDRESS = $VAULT_LDAP_LOGIN_ADDRESS.TrimEnd('/')
$VAULT_LDAP_LOGIN_AUTH_PATH = $VAULT_LDAP_LOGIN_AUTH_PATH.TrimStart('/').TrimEnd('/')

# Local variables
$StepName = $OctopusParameters["Octopus.Step.Name"]

try {
    $payload = @{
        password = $VAULT_LDAP_LOGIN_PASSWORD
    }
    
    $Headers = @{}
    if (-not [string]::IsNullOrWhiteSpace($VAULT_LDAP_LOGIN_NAMESPACE)) {
        Write-Verbose "Setting 'X-Vault-Namespace' header to: $VAULT_LDAP_LOGIN_NAMESPACE"
        $Headers.Add("X-Vault-Namespace", $VAULT_LDAP_LOGIN_NAMESPACE)
    }
    
    $uri = "$VAULT_LDAP_LOGIN_ADDRESS/$VAULT_LDAP_LOGIN_API_VERSION/$VAULT_LDAP_LOGIN_AUTH_PATH/login/$([uri]::EscapeDataString($VAULT_LDAP_LOGIN_USERNAME))"
    Write-Verbose "Making request to $uri"
    $response = Invoke-RestMethod -Method Post -Uri $uri -Body ($payload | ConvertTo-Json -Depth 10) -Headers $Headers
    if ($null -ne $response) {
        Set-OctopusVariable -Name "LDAPAuthToken" -Value $response.auth.client_token -Sensitive
        Write-Host "Created output variable: ##{Octopus.Action[$StepName].Output.LDAPAuthToken}"
    }
    else {
        Write-Error "Null or Empty response returned from Vault server" -Category InvalidResult
    }
}
catch {
    $ExceptionMessage = $_.Exception.Message
    $ErrorBody = Get-WebRequestErrorBody -RequestError $_
    $Message = "An error occurred logging in with LDAP: $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.

Report an issue

To use this template in Octopus Deploy, copy the JSON below and paste it into the Library → Step templates → Import dialog.

{
  "Id": "de807003-3b05-4649-9af3-11a2c7722b3f",
  "Name": "HashiCorp Vault - LDAP Login",
  "Description": "This step logs into a HashiCorp Vault server using the [LDAP](https://www.vaultproject.io/docs/auth/ldap) auth method.\n\nThe `client_token` from the response will be made available as a sensitive [Output variable](https://octopus.com/docs/projects/variables/output-variables#sensitive-output-variables) named `LDAPAuthToken` for use in other step templates.\n\nThis step template makes use of the [Rest API](https://www.vaultproject.io/api/auth/ldap#login-with-ldap-user), so no other dependencies are needed. \n\n**Required:** \n- The Vault server must be [unsealed](https://www.vaultproject.io/docs/concepts/seal).\n- You must supply the full path where the LDAP auth method is mounted.\n- You must supply both a `Username` and `Password`.\n\n*Optional*:\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\nNotes:\n\n- Tested on Vault Server `1.11.3`.\n- Tested on both PowerShell Desktop and PowerShell Core.",
  "Version": 5,
  "ExportedAt": "2022-09-18T08:25:57.132Z",
  "ActionType": "Octopus.Script",
  "Author": "harrisonmeister",
  "Packages": [],
  "Parameters": [
    {
      "Id": "d0e95468-4f9e-4272-9dfa-d964c610a279",
      "Name": "Vault.LDAP.Login.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": "98d2a264-0466-4e0d-b5a3-4d172c81f405",
      "Name": "Vault.LDAP.Login.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": "74fa0a75-0ab4-4a9d-a417-c9b9b391c640",
      "Name": "Vault.LDAP.Login.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": "c56afe5a-6506-497f-99b0-ae8776f03269",
      "Name": "Vault.LDAP.Login.AuthPath",
      "Label": "LDAP Auth Login path",
      "HelpText": "The path that the LDAP method is mounted at. The default is `/auth/ldap`. If the LDAP auth method was enabled at a different path, for example `my-path`, then specify `/my-path` instead.\n",
      "DefaultValue": "/auth/ldap",
      "DisplaySettings": {
        "Octopus.ControlType": "SingleLineText"
      }
    },
    {
      "Id": "7803e08c-026f-4d59-b902-f75a0992be48",
      "Name": "Vault.LDAP.Login.Username",
      "Label": "Username",
      "HelpText": "The LDAP Username.",
      "DefaultValue": "",
      "DisplaySettings": {
        "Octopus.ControlType": "SingleLineText"
      }
    },
    {
      "Id": "7a00c426-43f1-4229-a036-37b018d089a6",
      "Name": "Vault.LDAP.Login.Password",
      "Label": "LDAP Password",
      "HelpText": "The LDAP Password.",
      "DefaultValue": "",
      "DisplaySettings": {
        "Octopus.ControlType": "Sensitive"
      }
    }
  ],
  "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_LDAP_LOGIN_ADDRESS = $OctopusParameters[\"Vault.LDAP.Login.VaultAddress\"]\n$VAULT_LDAP_LOGIN_API_VERSION = $OctopusParameters[\"Vault.LDAP.Login.ApiVersion\"]\n$VAULT_LDAP_LOGIN_NAMESPACE = $OctopusParameters[\"Vault.LDAP.Login.Namespace\"]\n$VAULT_LDAP_LOGIN_AUTH_PATH = $OctopusParameters[\"Vault.LDAP.Login.AuthPath\"]\n$VAULT_LDAP_LOGIN_USERNAME = $OctopusParameters[\"Vault.LDAP.Login.Username\"]\n$VAULT_LDAP_LOGIN_PASSWORD = $OctopusParameters[\"Vault.LDAP.Login.Password\"]\n\n# Validation\nif ([string]::IsNullOrWhiteSpace($VAULT_LDAP_LOGIN_ADDRESS)) {\n    throw \"Required parameter VAULT_LDAP_LOGIN_ADDRESS not specified\"\n}\nif ([string]::IsNullOrWhiteSpace($VAULT_LDAP_LOGIN_API_VERSION)) {\n    throw \"Required parameter VAULT_LDAP_LOGIN_API_VERSION not specified\"\n}\nif ([string]::IsNullOrWhiteSpace($VAULT_LDAP_LOGIN_AUTH_PATH)) {\n    throw \"Required parameter VAULT_LDAP_LOGIN_AUTH_PATH not specified\"\n}\nif ([string]::IsNullOrWhiteSpace($VAULT_LDAP_LOGIN_USERNAME)) {\n    throw \"Required parameter VAULT_LDAP_LOGIN_USERNAME not specified\"\n}\nif ([string]::IsNullOrWhiteSpace($VAULT_LDAP_LOGIN_PASSWORD)) {\n    throw \"Required parameter VAULT_LDAP_LOGIN_PASSWORD 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_LDAP_LOGIN_ADDRESS = $VAULT_LDAP_LOGIN_ADDRESS.TrimEnd('/')\n$VAULT_LDAP_LOGIN_AUTH_PATH = $VAULT_LDAP_LOGIN_AUTH_PATH.TrimStart('/').TrimEnd('/')\n\n# Local variables\n$StepName = $OctopusParameters[\"Octopus.Step.Name\"]\n\ntry {\n    $payload = @{\n        password = $VAULT_LDAP_LOGIN_PASSWORD\n    }\n    \n    $Headers = @{}\n    if (-not [string]::IsNullOrWhiteSpace($VAULT_LDAP_LOGIN_NAMESPACE)) {\n        Write-Verbose \"Setting 'X-Vault-Namespace' header to: $VAULT_LDAP_LOGIN_NAMESPACE\"\n        $Headers.Add(\"X-Vault-Namespace\", $VAULT_LDAP_LOGIN_NAMESPACE)\n    }\n    \n    $uri = \"$VAULT_LDAP_LOGIN_ADDRESS/$VAULT_LDAP_LOGIN_API_VERSION/$VAULT_LDAP_LOGIN_AUTH_PATH/login/$([uri]::EscapeDataString($VAULT_LDAP_LOGIN_USERNAME))\"\n    Write-Verbose \"Making request to $uri\"\n    $response = Invoke-RestMethod -Method Post -Uri $uri -Body ($payload | ConvertTo-Json -Depth 10) -Headers $Headers\n    if ($null -ne $response) {\n        Set-OctopusVariable -Name \"LDAPAuthToken\" -Value $response.auth.client_token -Sensitive\n        Write-Host \"Created output variable: ##{Octopus.Action[$StepName].Output.LDAPAuthToken}\"\n    }\n    else {\n        Write-Error \"Null or Empty response returned from Vault server\" -Category InvalidResult\n    }\n}\ncatch {\n    $ExceptionMessage = $_.Exception.Message\n    $ErrorBody = Get-WebRequestErrorBody -RequestError $_\n    $Message = \"An error occurred logging in with LDAP: $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-ldap-login.json",
  "Website": "/step-templates/de807003-3b05-4649-9af3-11a2c7722b3f",
  "Logo": "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",
  "$Meta": {
    "Type": "ActionTemplate"
  }
}

History

Page updated on Sunday, September 18, 2022