From 2434afca5cc0f5f78057a97d32a70ae1f9468ad7 Mon Sep 17 00:00:00 2001 From: "Thomas Farray (tfarray)" Date: Thu, 23 Sep 2021 11:45:33 +0200 Subject: [PATCH 01/12] indenting alignement --- CyberarkConjur.psm1 | 258 ++++++++++++++++++-------------------------- 1 file changed, 103 insertions(+), 155 deletions(-) diff --git a/CyberarkConjur.psm1 b/CyberarkConjur.psm1 index 89f418e..4b6d757 100644 --- a/CyberarkConjur.psm1 +++ b/CyberarkConjur.psm1 @@ -1,50 +1,36 @@ -Function Write-Log -{ - param( - $Message, - $Level = "INFO" - ) - Write-Verbose "$Level :: $Message" +############################### +# Funcitons +############################### + +Function Disable-SslVerification { + try { + + add-type " + using System.Net; + using System.Security.Cryptography.X509Certificates; + + public class IDontCarePolicy : ICertificatePolicy { + public IDontCarePolicy() {} + public bool CheckValidationResult( + ServicePoint sPoint, X509Certificate cert, + WebRequest wRequest, int certProb) { + return true; + } + }" + [System.Net.ServicePointManager]::CertificatePolicy = new-object IDontCarePolicy + [Net.ServicePointManager]::SecurityProtocol = [Net.ServicePointManager]::SecurityProtocol -bor [Net.SecurityProtocolType]::Tls12 + } + catch { } } -Function Disable-SslVerification -{ -try -{ - -add-type @" - using System.Net; - using System.Security.Cryptography.X509Certificates; - - public class IDontCarePolicy : ICertificatePolicy { - public IDontCarePolicy() {} - public bool CheckValidationResult( - ServicePoint sPoint, X509Certificate cert, - WebRequest wRequest, int certProb) { - return true; - } - } -"@ - [System.Net.ServicePointManager]::CertificatePolicy = new-object IDontCarePolicy - [Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12 - -} -catch -{ -# Ignore if error is thrown, an error is thrown if we Disaable-SSL twice in the same pwoershell session -} -} - -Function Get-ResponseBodyFromException() -{ +Function Get-ResponseBodyFromException() { param( $Exception ) $responseBody = $null - if ($Exception.Response -ne $null) - { + if ($Exception.Response -ne $null) { $result = $Exception.Response.GetResponseStream() $reader = New-Object System.IO.StreamReader($result) $reader.BaseStream.Position = 0 @@ -55,27 +41,21 @@ Function Get-ResponseBodyFromException() return $responseBody; } -Function Get-HeaderAsString() -{ +Function Get-HeaderAsString() { param( $Header ) - $headerAsString = "" - if ($Header -ne $null) - { - foreach ($kv in $Header.GetEnumerator()) - { + if ($Header -ne $null) { + foreach ($kv in $Header.GetEnumerator()) { $headerAsString += "$($kv.Name)=$($kv.Value);" } } - return $headerAsString } -Function Send-HttpMethod() -{ +Function Send-HttpMethod() { param( $Url, $Method, @@ -84,111 +64,99 @@ Function Send-HttpMethod() $LogResponse = $true, $Certificate = $null ) - Write-Log "URL: $Url" - Write-Log "Method: $Method" - Write-Log "Default Header: $(Get-HeaderAsString -Header $Header)" - Write-Log "Body: $Body" + Write-Verbose "URL: $Url" + Write-Verbose "Method: $Method" + Write-Verbose "Default Header: $(Get-HeaderAsString -Header $Header)" + Write-Verbose "Body: $Body" $res = $null - try - { - if ($Certificate -eq $null) - { - if ($body -eq $null) - { + try { + if ($Certificate -eq $null) { + if ($body -eq $null) { $res = Invoke-RestMethod -Uri $url -Method $method -Header $header - } - else - { + } else { $res = Invoke-RestMethod -Uri $url -Method $method -Header $header -Body $body } - } - else - { - if ($body -eq $null) - { + } else { + if ($body -eq $null) { $res = Invoke-RestMethod -Uri $url -Method $method -Header $header -Certificate $Certificate -CertificateThumbprint $Certificate.Thumbprint - } - else - { + } else { $res = Invoke-RestMethod -Uri $url -Method $method -Header $header -Body $body -Certificate $Certificate -CertificateThumbprint $Certificate.Thumbprint } } } - catch - { + catch { $exception = $_.Exception $responseBody = Get-ResponseBodyFromException($exception) - Write-Log -Message "Response Body: `n $($responseBody | ConvertFrom-Json | ConvertTo-Json)" -Level "ERROR" + Write-Verbose -Message "Response Body: `n $($responseBody | ConvertFrom-Json | ConvertTo-Json)" -Level "ERROR" throw $_ break } - if ($LogResponse) - { - Write-Log "HTTP Response: $($res | ConvertTo-Json)" + if ($LogResponse) { + Write-Verbose "HTTP Response: $($res | ConvertTo-Json)" } return $res } -Function Test-MandatoryParameter -{ +Function Test-MandatoryParameter { param( $EnvironmentVariableName, $Value, $Ignore = $false ) - if ([string]::IsNullOrWhiteSpace($Value)) - { - if (-Not ($Ignore)) - { + if ([string]::IsNullOrWhiteSpace($Value)) { + if (-Not ($Ignore)) { Write-Host -ForegroundColor RED "Mandatory parameter is empty or missing: $EnvironmentVariableName" } - return $false - } - else - { - Write-Log "$EnvironmentVariableName=$Value" + } else { + Write-Verbose "$EnvironmentVariableName=$Value" } return $true } -Function Test-MandatoryParameters -{ +Function Test-MandatoryParameters { param ( $OmitEnvironmentVariables = @() ) - if (!(Test-MandatoryParameter -EnvironmentVariableName "CONJUR_ACCOUNT" -Value $ConjurAccount)) { return $false; } - if (!(Test-MandatoryParameter -EnvironmentVariableName "CONJUR_AUTHN_LOGIN" -Value $ConjurUsername)) { return $false; } - if (!(Test-MandatoryParameter -EnvironmentVariableName "CONJUR_AUTHN_API_KEY" -Value $ConjurPassword)) { return $false; } - if (!(Test-MandatoryParameter -EnvironmentVariableName "CONJUR_APPLIANCE_URL" -Value $ConjurApplianceUrl)) { return $false; } - # if (!(Test-MandatoryParameter -EnvironmentVariableName "CONJUR_CERT" -Value $ConjurCert)) { return $false; } - return $true + if (!(Test-MandatoryParameter -EnvironmentVariableName "CONJUR_ACCOUNT" -Value $ConjurAccount)) { return $false; + } elseif (!(Test-MandatoryParameter -EnvironmentVariableName "CONJUR_AUTHN_LOGIN" -Value $ConjurUsername)) { + return $false; + } elseif (!(Test-MandatoryParameter -EnvironmentVariableName "CONJUR_AUTHN_API_KEY" -Value $ConjurPassword)) { + return $false; + } elseif (!(Test-MandatoryParameter -EnvironmentVariableName "CONJUR_APPLIANCE_URL" -Value $ConjurApplianceUrl)) { + return $false; + } else { + return $true + } } -Function Test-MandatoryParametersIam -{ +Function Test-MandatoryParametersIam { param ( $OmitEnvironmentVariables = @() ) - if (!(Test-MandatoryParameter -EnvironmentVariableName "CONJUR_ACCOUNT" -Value $ConjurAccount)) { return $false; } - if (!(Test-MandatoryParameter -EnvironmentVariableName "CONJUR_AUTHN_LOGIN" -Value $ConjurUsername)) { return $false; } - if (!(Test-MandatoryParameter -EnvironmentVariableName "CONJUR_IAM_AUTHN_BRANCH" -Value $ConjurPassword)) { return $false; } - if (!(Test-MandatoryParameter -EnvironmentVariableName "CONJUR_APPLIANCE_URL" -Value $ConjurApplianceUrl)) { return $false; } - # if (!(Test-MandatoryParameter -EnvironmentVariableName "CONJUR_CERT" -Value $ConjurCert)) { return $false; } - return $true + if (!(Test-MandatoryParameter -EnvironmentVariableName "CONJUR_ACCOUNT" -Value $ConjurAccount)) { + return $false; + } elseif (!(Test-MandatoryParameter -EnvironmentVariableName "CONJUR_AUTHN_LOGIN" -Value $ConjurUsername)) { + return $false; + } elseif (!(Test-MandatoryParameter -EnvironmentVariableName "CONJUR_IAM_AUTHN_BRANCH" -Value $ConjurPassword)) { + return $false; + } elseif (!(Test-MandatoryParameter -EnvironmentVariableName "CONJUR_APPLIANCE_URL" -Value $ConjurApplianceUrl)) { + return $false; + } else { + return $true + } } -Function Get-SessionTokenHeader -{ +Function Get-SessionTokenHeader { param( $SessionToken ) @@ -197,32 +165,24 @@ Function Get-SessionTokenHeader return $header } -$api_authn_iam_branch = "prod" -$host_id = "host/949316202723/Conjur-EC2-Test" - -$region = "us-east-1" -$sts_host = "sts.amazonaws.com" -$service = "sts" - -#Add-Type -TypeDefinition $helperClass -Language CSharp Function Enable-HelperNamespace{ -add-type @" +add-type " namespace HelperNamespace { public static class HelperClass { public static string ToHexString(byte[] array) { var hex = new System.Text.StringBuilder(array.Length * 2); foreach(byte b in array) { - hex.AppendFormat("{0:x2}", b); + hex.AppendFormat(""{0:x2}"", b); } return hex.ToString(); } public static byte[] GetSignatureKey(string key, string dateStamp, string regionName, string serviceName) { - byte[] kDate = HmacSHA256(System.Text.Encoding.UTF8.GetBytes("AWS4" + key), dateStamp); + byte[] kDate = HmacSHA256(System.Text.Encoding.UTF8.GetBytes(""AWS4"" + key), dateStamp); byte[] kRegion = HmacSHA256(kDate, regionName); byte[] kService = HmacSHA256(kRegion, serviceName); - byte[] kSigning = HmacSHA256(kService, "aws4_request"); + byte[] kSigning = HmacSHA256(kService, ""aws4_request""); return kSigning; } @@ -232,20 +192,19 @@ add-type @" return hashAlgorithm.ComputeHash(System.Text.Encoding.UTF8.GetBytes(data)); } } - } -"@ + }" } function Get-IamAuthorizationHeader { - param ( - $cHost, - $cDate, - $cToken, - $cRegion, - $cService, - $cAccessKeyId, - $cSecretAccessKey - ) + param ( + $cHost, + $cDate, + $cToken, + $cRegion, + $cService, + $cAccessKeyId, + $cSecretAccessKey + ) Enable-HelperNamespace $empty_body_hash = "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" @@ -313,8 +272,7 @@ Function Get-IamConjurApiKey { return $conjurToken } -Function Get-ConjurApiKey -{ +Function Get-ConjurApiKey { param( $ConjurAccount = $env:CONJUR_ACCOUNT, $ConjurUsername = $env:CONJUR_AUTHN_LOGIN, @@ -326,14 +284,11 @@ Function Get-ConjurApiKey $iamAuthn = Test-MandatoryParameter -EnvironmentVariableName "CONJUR_IAM_AUTHN_BRANCH" -Value $IamAuthnBranch -Ignore $true - if ($iamAuthn) - { + if ($iamAuthn) { if (!(Test-MandatoryParametersIam)) { return } if (($IgnoreSsl)) { Disable-SslVerification } return Get-IamConjurApiKey - } - else - { + } else { if (!(Test-MandatoryParameters)) { return } if (($IgnoreSsl)) { Disable-SslVerification } $url = "$ConjurApplianceUrl/authn/$ConjurAccount/login" @@ -342,11 +297,10 @@ Function Get-ConjurApiKey $basicAuthHeader = @{"Authorization"="Basic $base64"} return Send-HttpMethod -Url $url -Method GET -Header $basicAuthHeader } - } # This is required because powershell will automatically decode %2F to / to avoid that we must run this method on the uri that contains %2F -function FixUri($uri){ +function FixUri($uri) { $UnEscapeDotsAndSlashes = 0x2000000; $SimpleUserSyntax = 0x20000; @@ -363,8 +317,10 @@ function FixUri($uri){ $fieldInfo.SetValue($uriParser, $uriSyntaxFlags); } -Function Get-ConjurSessionToken -{ +############################### +# Exported ModuleMember +############################### +Function Get-ConjurSessionToken { param( $ConjurAccount = $env:CONJUR_ACCOUNT, $ConjurUsername = $env:CONJUR_AUTHN_LOGIN, @@ -381,8 +337,7 @@ Function Get-ConjurSessionToken $url = ([uri]"$ConjurApplianceUrl/authn/$ConjurAccount/$ConjurUsername/authenticate") - if ($iamAuthn) - { + if ($iamAuthn) { $url = ([uri]"$ConjurApplianceUrl/authn-iam/$IamAuthnBranch/$ConjurAccount/$ConjurUsername/authenticate") } @@ -422,8 +377,7 @@ https://www.conjur.org/api.html#health-get-health #> -Function Get-ConjurHealth -{ +Function Get-ConjurHealth { param( $ConjurAccount = $env:CONJUR_ACCOUNT, $ConjurUsername = $env:CONJUR_AUTHN_LOGIN, @@ -472,8 +426,7 @@ https://www.conjur.org/api.html#secrets-retrieve-a-secret-get #> -Function Get-ConjurSecret() -{ +Function Get-ConjurSecret() { param( [Parameter(Position=0,mandatory=$true)] [string]$SecretIdentifier, @@ -531,8 +484,7 @@ https://www.conjur.org/api.html#secrets-add-a-secret-post #> -Function Set-ConjurSecret -{ +Function Set-ConjurSecret { param( [Parameter(Position=0,mandatory=$true)] [string]$SecretIdentifier, @@ -594,8 +546,7 @@ https://www.conjur.org/api.html#policies-update-a-policy-patch #> -Function Update-ConjurPolicy -{ +Function Update-ConjurPolicy { param( [Parameter(Position=0,mandatory=$true)] [string]$PolicyIdentifier, @@ -656,8 +607,7 @@ https://www.conjur.org/api.html#policies-replace-a-policy #> -Function Replace-ConjurPolicy -{ +Function Replace-ConjurPolicy { param( [Parameter(Position=0,mandatory=$true)] [string]$PolicyIdentifier, @@ -719,8 +669,7 @@ https://www.conjur.org/api.html#policies-append-to-a-policy #> -Function Append-ConjurPolicy -{ +Function Append-ConjurPolicy { param( [Parameter(Position=0,mandatory=$true)] [string]$PolicyIdentifier, @@ -779,8 +728,7 @@ https://www.conjur.org/api.html#role-based-access-control-list-resources-get #> -Function Get-ConjurResources -{ +Function Get-ConjurResources { param( $ConjurAccount = $env:CONJUR_ACCOUNT, $ConjurUsername = $env:CONJUR_AUTHN_LOGIN, From 82ebc82cb0079d2f40dae8004637c4d53584ebf0 Mon Sep 17 00:00:00 2001 From: "Thomas Farray (tfarray)" Date: Thu, 23 Sep 2021 19:39:09 +0200 Subject: [PATCH 02/12] major rewrite done. Most functionalities are up --- CyberarkConjur.psd1 | Bin 0 -> 1764 bytes CyberarkConjur.psm1 | 648 +++++++++++++++++++++++--------------------- 2 files changed, 336 insertions(+), 312 deletions(-) create mode 100644 CyberarkConjur.psd1 diff --git a/CyberarkConjur.psd1 b/CyberarkConjur.psd1 new file mode 100644 index 0000000000000000000000000000000000000000..7542339324418a216dcc5db5ca27c96cdde0cd05 GIT binary patch literal 1764 zcmbuATTk0S5QWckrTzy?dFVwVq)>W!s6<2>h|~+BE$@jPL)rvKu_>Ucf4%KDYp?BX zLqQCNz{A=sBEc##@haA7} z!yvSCTl9A>qL%-R>_qUeiV7oatgJp``eLjTcqW`&plKPoE-zhIuO05&{nFrB@9pZb zo;W$5ljc6;lY(YFdp9oL`mnOnpsZ(cNX^ak9d8RTBmA}9*!gM|YSGAB*|Ip8T)QqK z?w6d#STgoy)MoTyw00V8263|d8H)^k^E$7i8FCxc%*t67_SXTrb6AW(O|ccx)kl2! zY+v6|9c2F2_PXnk1|X$yvB_%Hw1m5z%;@FFVcYbJ;jrMbS(mu@wR^pc&`tf`#m+}^ zW3$?_l&~vnu*}r|c$|Z288|^>1P?#`HiFnk%rA?w=igLv=w&&%y*F(Q|3A=V<7ZIi M;k>&0+_Sp=1A$%{)Bpeg literal 0 HcmV?d00001 diff --git a/CyberarkConjur.psm1 b/CyberarkConjur.psm1 index 4b6d757..e4bdc29 100644 --- a/CyberarkConjur.psm1 +++ b/CyberarkConjur.psm1 @@ -1,36 +1,241 @@ -############################### -# Funcitons + +############################### +# Module Variables ############################### -Function Disable-SslVerification { - try { +$CCConfig = @{ + AWS_MetaData = "169.254.169.254" + CONJUR_ACCOUNT = $null + CONJUR_AUTHAURITY_NAME = $null + CONJUR_AUTHAURITY_NAME_WR = $null + CONJUR_IAM_AUTHN_BRANCH = $null + Certificate = $null # This has not been explained in the former Module + Token = $null + TokenTTL = 6 * 60 + # maybe this can be fetched : https://docs.cyberark.com/Product-Doc/OnlineHelp/AAM-DAP/Latest/en/Content/Developer/Conjur_API_whoami.htm?tocpath=Developer%7CREST%C2%A0APIs%7C_____3 + Credential = $null + TokenExpireDate = $null +} - add-type " - using System.Net; - using System.Security.Cryptography.X509Certificates; +############################### +# Invoke & Config Conjur +############################### +Function Invoke-Conjur { + [CmdletBinding()] + param( + [Parameter(Position=0,Mandatory)][string]$API, + [Parameter(Position=1)][string]$Command, + [Parameter(Position=2)][string]$Body, + [string]$Method = "GET" + ) + process { + ############################## + # Initialization + ############################## + $CalledBy = (Get-PSCallStack)[1].command + if(!$PsBoundParameters.containskey("Method")) { + switch -regex ($CalledBy) { + "^Remove-" { $method = "DELETE" } + "^Update-" { $method = "PATCH" } + # "^(Set|add)-" { $method = "PUT" } + "^(Set|New|Submit|Write)-" { $method = "POST" } + } + } + + $Authority = $CCConfig.CONJUR_AUTHAURITY_NAME + if ($Method -notlike "GET" -and $CCConfig.CONJUR_AUTHAURITY_NAME_WR) { + Write-verbose "Switching to WRITE" + $Authority = $CCConfig.CONJUR_AUTHAURITY_NAME_WR + } + + if ($API -match "WhoAmI|health") { + $URL = ($Authority,$API) -join "/" + } else { + $URL = ($Authority,$API,$CCConfig.CONJUR_ACCOUNT,$Command ) -join "/" + } + $URL = "https://" + ($URL -replace "//+","/" -replace '/$') + + + $RestMethod = @{ + Method = $Method + Headers = @{} + URI = [uri]$URL + } + + if ($Command -match "^authn") { fixUri $RestMethod.URI } + + ############################## + # Authentication verification + ############################## + if ((!$CCConfig.Token -or ((get-date) -gt $CCConfig.TokenExpireDate))-and $API -notmatch 'authn') { + Write-Verbose "Invoke-Conjur : Authentication verification called by $CalledBy" + $ConjurUsername = [uri]::EscapeDataString($CCConfig.Credential.username) + + # Checking inputs + $MissingConfig = @() + "CONJUR_ACCOUNT","CONJUR_AUTHAURITY_NAME","Credential" | % { + if (!$CCConfig[$_]) { $MissingConfig += $_ } + } + if ($MissingConfig) { + write-Warning "The Conjur Module is not configured. Please run the [Initialize-ConjurConfiguration] command to configure the module. You can also run [get-help Initialize-ConjurConfiguration] for more information." + return + } + + # Getting the API Key + $StartTime = Get-date + if ($CCConfig.CONJUR_IAM_AUTHN_BRANCH) { + Get-IamConjurApiKey + } else { + $ApiKey = Invoke-Conjur authn login -verbose + Write-Verbose "API key = $ApiKey" # $($API.SubString(0,10))..." + } + + if (!$ApiKey) { + write-Warning "The Conjur Module was not able retrieve the API Key. Please run the [Initialize-ConjurConfiguration] command to configure the module. You can also run [get-help Initialize-ConjurConfiguration] for more information." + throw "failed" + } + + # Getting the Token + $TokenAPI = "authn" + $TokenCommand = "" + if ($CCConfig.CONJUR_IAM_AUTHN_BRANCH) { + $TokenAPI = "authn-iam" + $TokenCommand += "$($CCConfig.CONJUR_IAM_AUTHN_BRANCH)/" + } + $TokenCommand += "$ConjurUsername/authenticate" + write-verbose "TokenCommand : $TokenCommand" + $CCConfig.Token = Invoke-Conjur $TokenAPI $TokenCommand -Body $apiKey -Method POST + if (!$CCConfig.Token) { + write-Warning "The Conjur Module was not able to authenticate. Please run the [Initialize-ConjurConfiguration] command to configure the module. You can also run [get-help Initialize-ConjurConfiguration] for more information." + return + } + $CCConfig.TokenExpireDate = $StartTime.AddSeconds($CCConfig.TokenTTL) + } + + ############################## + # Headers + ############################## + if ($API -match 'authn') { + Write-Verbose "Generating Headers for $($CCConfig.Credential.UserName) " + $base64 = [Convert]::ToBase64String([Text.Encoding]::ASCII.GetBytes(("{0}:{1}" -f $CCConfig.Credential.UserName, $CCConfig.Credential.GetNetworkCredential().password))) + $RestMethod.Headers.add("Authorization","Basic $base64") + } else { + $base64 = [Convert]::ToBase64String([Text.Encoding]::ASCII.GetBytes((($CCConfig.Token | ConvertTo-Json)))) + $RestMethod.Headers.add("Authorization","Token token=""$base64""") + } + + ############################## + # Additional parameters + ############################## + Switch ($PsBoundParameters.keys) { + "Body" { $RestMethod.add("body",$body) } + } + + if ($CCConfig.Certificate) { + $RestMethod.add("Certificate",$CCConfig.Certificate) + $RestMethod.add("CertificateThumbprint",$CCConfig.Certificate.Thumbprint) + } - public class IDontCarePolicy : ICertificatePolicy { - public IDontCarePolicy() {} - public bool CheckValidationResult( - ServicePoint sPoint, X509Certificate cert, - WebRequest wRequest, int certProb) { - return true; + ############################## + # Sending Rest API Request + ############################## + Write-verbose ($RestMethod | out-string -Width ($host.UI.RawUI.BufferSize.Width -2 )) + # Write-verbose ($RestMethod["Headers"] | out-string -Width ($host.UI.RawUI.BufferSize.Width -2 )) + + # Write-Verbose "Invoke-Conjur : URL : $URL" + try { + $Result = Invoke-RestMethod @RestMethod + } catch { + $exception = $_.Exception + $responseBody = Get-ResponseBodyFromException($exception) + Write-Verbose -Message "Response Body: `n $($responseBody | out-string)" + # Write-Verbose -Message "Response Body: `n $($responseBody | ConvertFrom-Json | ConvertTo-Json)" + throw $_ + break + } + + return $Result + } +} +Export-ModuleMember -Function Invoke-Conjur + +Function Initialize-Conjur { + [CmdletBinding(DefaultParameterSetName="Credential")] + Param( + [string]$CONJUR_ACCOUNT, + [parameter(ParameterSetName='Login',mandatory)][string]$CONJUR_AUTHN_LOGIN, + [parameter(ParameterSetName='Login',mandatory)][string]$CONJUR_AUTHN_API_KEY, + [parameter(ParameterSetName='Credential')][PSCredential]$Credential, + [string]$CONJUR_AUTHAURITY_NAME, + [string]$CONJUR_AUTHAURITY_NAME_WR, + [string]$CONJUR_IAM_AUTHN_BRANCH, + [string]$AWS_MetaData, + [Switch]$IgnoreSsl + ) + Process { + $ParamatersToIgnore = ([System.Management.Automation.PSCmdlet]::CommonParameters + [System.Management.Automation.PSCmdlet]::OptionalCommonParameters) + $ParamatersToIgnore += @('CONJUR_AUTHN_LOGIN','CONJUR_AUTHN_API_KEY',"IgnoreSsl") + + $PsBoundParameters.keys | ? { $_ -notin $ParamatersToIgnore } | % { + Switch ($_) { + "IgnoreSsl" { + try { + add-type " + using System.Net; + using System.Security.Cryptography.X509Certificates; + + public class IDontCarePolicy : ICertificatePolicy { + public IDontCarePolicy() {} + public bool CheckValidationResult( + ServicePoint sPoint, X509Certificate cert, + WebRequest wRequest, int certProb) { + return true; + } + }" + [System.Net.ServicePointManager]::CertificatePolicy = new-object IDontCarePolicy + [Net.ServicePointManager]::SecurityProtocol = [Net.ServicePointManager]::SecurityProtocol -bor [Net.SecurityProtocolType]::Tls12 + } catch { } + } + CONJUR_IAM_AUTHN_BRANCH { + $CCConfig[$_] = $PsBoundParameters.item($_) + $CCConfig["Credential"] = $null + } + CONJUR_AUTHAURITY_NAME{ + $CCConfig[$_] = $PsBoundParameters.item($_) -replace "http.://" + } + + + default { + $CCConfig[$_] = $PsBoundParameters.item($_) + } } - }" - [System.Net.ServicePointManager]::CertificatePolicy = new-object IDontCarePolicy - [Net.ServicePointManager]::SecurityProtocol = [Net.ServicePointManager]::SecurityProtocol -bor [Net.SecurityProtocolType]::Tls12 + } + + if ($PsCmdlet.ParameterSetName -like "Login") { + write-warning "Please note that manipulating Credential object is always more secure. Please consider using the -Credential $CredObject instead" + [securestring]$SS = ConvertTo-SecureString $CONJUR_AUTHN_API_KEY -AsPlainText -Force + + $CCConfig["Credential"] = New-Object System.Management.Automation.PSCredential ($CONJUR_AUTHN_LOGIN, $SS) + $CCConfig["CONJUR_IAM_AUTHN_BRANCH"] = $null + } } - catch { } } +Export-ModuleMember -Function Initialize-Conjur + -Function Get-ResponseBodyFromException() { - param( +############################### +# Internal Functions +############################### + +Function Get-ResponseBodyFromException { + [CmdletBinding()] + param( $Exception ) $responseBody = $null - if ($Exception.Response -ne $null) { + if ($Exception.Response) { $result = $Exception.Response.GetResponseStream() $reader = New-Object System.IO.StreamReader($result) $reader.BaseStream.Position = 0 @@ -38,11 +243,12 @@ Function Get-ResponseBodyFromException() { $responseBody = $reader.ReadToEnd(); } - return $responseBody; + return $responseBody } Function Get-HeaderAsString() { - param( + [CmdletBinding()] + param( $Header ) $headerAsString = "" @@ -55,61 +261,17 @@ Function Get-HeaderAsString() { return $headerAsString } -Function Send-HttpMethod() { - param( - $Url, - $Method, - $Header, - $Body = $null, - $LogResponse = $true, - $Certificate = $null - ) - Write-Verbose "URL: $Url" - Write-Verbose "Method: $Method" - Write-Verbose "Default Header: $(Get-HeaderAsString -Header $Header)" - Write-Verbose "Body: $Body" - $res = $null - - - try { - if ($Certificate -eq $null) { - if ($body -eq $null) { - $res = Invoke-RestMethod -Uri $url -Method $method -Header $header - } else { - $res = Invoke-RestMethod -Uri $url -Method $method -Header $header -Body $body - } - } else { - if ($body -eq $null) { - $res = Invoke-RestMethod -Uri $url -Method $method -Header $header -Certificate $Certificate -CertificateThumbprint $Certificate.Thumbprint - } else { - $res = Invoke-RestMethod -Uri $url -Method $method -Header $header -Body $body -Certificate $Certificate -CertificateThumbprint $Certificate.Thumbprint - } - } - } - catch { - $exception = $_.Exception - $responseBody = Get-ResponseBodyFromException($exception) - Write-Verbose -Message "Response Body: `n $($responseBody | ConvertFrom-Json | ConvertTo-Json)" -Level "ERROR" - throw $_ - break - } - - if ($LogResponse) { - Write-Verbose "HTTP Response: $($res | ConvertTo-Json)" - } - - return $res -} Function Test-MandatoryParameter { - param( + [CmdletBinding()] + param( $EnvironmentVariableName, $Value, $Ignore = $false ) if ([string]::IsNullOrWhiteSpace($Value)) { - if (-Not ($Ignore)) { + if (!$Ignore) { Write-Host -ForegroundColor RED "Mandatory parameter is empty or missing: $EnvironmentVariableName" } return $false @@ -120,54 +282,44 @@ Function Test-MandatoryParameter { return $true } -Function Test-MandatoryParameters { - param ( - $OmitEnvironmentVariables = @() - ) - - if (!(Test-MandatoryParameter -EnvironmentVariableName "CONJUR_ACCOUNT" -Value $ConjurAccount)) { return $false; - } elseif (!(Test-MandatoryParameter -EnvironmentVariableName "CONJUR_AUTHN_LOGIN" -Value $ConjurUsername)) { - return $false; - } elseif (!(Test-MandatoryParameter -EnvironmentVariableName "CONJUR_AUTHN_API_KEY" -Value $ConjurPassword)) { - return $false; - } elseif (!(Test-MandatoryParameter -EnvironmentVariableName "CONJUR_APPLIANCE_URL" -Value $ConjurApplianceUrl)) { - return $false; - } else { - return $true - } -} - -Function Test-MandatoryParametersIam { - param ( - $OmitEnvironmentVariables = @() - ) - - if (!(Test-MandatoryParameter -EnvironmentVariableName "CONJUR_ACCOUNT" -Value $ConjurAccount)) { - return $false; - } elseif (!(Test-MandatoryParameter -EnvironmentVariableName "CONJUR_AUTHN_LOGIN" -Value $ConjurUsername)) { - return $false; - } elseif (!(Test-MandatoryParameter -EnvironmentVariableName "CONJUR_IAM_AUTHN_BRANCH" -Value $ConjurPassword)) { - return $false; - } elseif (!(Test-MandatoryParameter -EnvironmentVariableName "CONJUR_APPLIANCE_URL" -Value $ConjurApplianceUrl)) { - return $false; - } else { - return $true - } -} - +############################### +# Internal IAM Functions +############################### -Function Get-SessionTokenHeader { - param( - $SessionToken - ) - $base64 = [Convert]::ToBase64String([Text.Encoding]::ASCII.GetBytes((($SessionToken | ConvertTo-Json)))) - $header = @{"Authorization"= "Token token=`"$base64`""} - return $header +Function Invoke-ConjurIam { + [CmdletBinding()] + param( + [Parameter(Position=0, Mandatory=$true)][string]$Command, + [string]$Method = "get", + [string]$Body + + ) + process { + $URL = + + $RestMethod = @{ + Method = $Method + URI = "http://$($CCConfig.AWS_MetaData)/" + $Command + } + + try { + $Result = Invoke-RestMethod @RestMethod + } catch { + $exception = $_.Exception + $responseBody = Get-ResponseBodyFromException($exception) + Write-Verbose -Message "Response Body: `n $($responseBody | ConvertFrom-Json | ConvertTo-Json)" -Level "ERROR" + throw $_ + break + } + + return $Result + } } - Function Enable-HelperNamespace{ -add-type " + [CmdletBinding()] + param() + add-type " namespace HelperNamespace { public static class HelperClass { public static string ToHexString(byte[] array) { @@ -196,6 +348,7 @@ add-type " } function Get-IamAuthorizationHeader { + [CmdletBinding()] param ( $cHost, $cDate, @@ -234,28 +387,24 @@ function Get-IamAuthorizationHeader { $signature = [HelperNamespace.HelperClass]::ToHexString([HelperNamespace.HelperClass]::HmacSHA256($signing_key, $string_to_sign)) - "$($algorithm) Credential=$($cAccessKeyId)/$($cred_scope), SignedHeaders=$($signed_headers), Signature=$($signature)" -} - -function Get-AwsRegion { - $region = Invoke-RestMethod -Uri "http://169.254.169.254/latest/meta-data/placement/availability-zone" - return $region.Substring(0, $region.Length -1) + return "$($algorithm) Credential=$($cAccessKeyId)/$($cred_scope), SignedHeaders=$($signed_headers), Signature=$($signature)" } Function Get-IamConjurApiKey { - $region = Get-AwsRegion - - $t = [DateTimeOffset]::UtcNow - $x_amz_date = $t.ToString("yyyyMMddTHHmmssZ") + [CmdletBinding()] + param() + + $region = Invoke-ConjurIam -command "latest/meta-data/placement/availability-zone" + $role = Invoke-ConjurIam "/latest/meta-data/iam/security-credentials" + $cred_results = Invoke-Conjur "latest/meta-data/iam/security-credentials/$role" - $uri_role = "http://169.254.169.254/latest/meta-data/iam/security-credentials" - $role = Send-HttpMethod -Url $uri_role -Method GET - $uri_creds = "http://169.254.169.254/latest/meta-data/iam/security-credentials/$role" - $cred_results = Send-HttpMethod -Url $uri_creds -Method GET - $access_key_id = $cred_results.AccessKeyId - $secret_access_key = $cred_results.SecretAccessKey - $x_amz_security_token = $cred_results.Token + $region = $region.Substring(0, $region.Length -1) + $t = [DateTimeOffset]::UtcNow + $x_amz_date = $t.ToString("yyyyMMddTHHmmssZ") + $access_key_id = $cred_results.AccessKeyId + $secret_access_key = $cred_results.SecretAccessKey + $x_amz_security_token = $cred_results.Token $output = Get-IamAuthorizationHeader $sts_host $x_amz_date $x_amz_security_token $region $service $access_key_id $secret_access_key @@ -272,36 +421,13 @@ Function Get-IamConjurApiKey { return $conjurToken } -Function Get-ConjurApiKey { - param( - $ConjurAccount = $env:CONJUR_ACCOUNT, - $ConjurUsername = $env:CONJUR_AUTHN_LOGIN, - $ConjurPassword = $env:CONJUR_AUTHN_API_KEY, - $ConjurApplianceUrl = $env:CONJUR_APPLIANCE_URL, - $IamAuthnBranch = $env:CONJUR_IAM_AUTHN_BRANCH, - $IgnoreSsl = $false - ) - - $iamAuthn = Test-MandatoryParameter -EnvironmentVariableName "CONJUR_IAM_AUTHN_BRANCH" -Value $IamAuthnBranch -Ignore $true - - if ($iamAuthn) { - if (!(Test-MandatoryParametersIam)) { return } - if (($IgnoreSsl)) { Disable-SslVerification } - return Get-IamConjurApiKey - } else { - if (!(Test-MandatoryParameters)) { return } - if (($IgnoreSsl)) { Disable-SslVerification } - $url = "$ConjurApplianceUrl/authn/$ConjurAccount/login" - - $base64 = [Convert]::ToBase64String([Text.Encoding]::ASCII.GetBytes(("{0}:{1}" -f $ConjurUsername, $ConjurPassword))) - $basicAuthHeader = @{"Authorization"="Basic $base64"} - return Send-HttpMethod -Url $url -Method GET -Header $basicAuthHeader - } -} - + # This is required because powershell will automatically decode %2F to / to avoid that we must run this method on the uri that contains %2F -function FixUri($uri) { - $UnEscapeDotsAndSlashes = 0x2000000; +function FixUri { + [CmdletBinding()] + param($uri) + + $UnEscapeDotsAndSlashes = 0x2000000; $SimpleUserSyntax = 0x20000; $type = $uri.GetType(); @@ -318,33 +444,8 @@ function FixUri($uri) { } ############################### -# Exported ModuleMember +# Exported Functions ############################### -Function Get-ConjurSessionToken { - param( - $ConjurAccount = $env:CONJUR_ACCOUNT, - $ConjurUsername = $env:CONJUR_AUTHN_LOGIN, - $ConjurPassword = $env:CONJUR_AUTHN_API_KEY, - $ConjurApplianceUrl = $env:CONJUR_APPLIANCE_URL, - $IamAuthnBranch = $env:CONJUR_IAM_AUTHN_BRANCH, - $IgnoreSsl = $false - ) - - $apiKey = Get-ConjurApiKey -ConjurAccount $ConjurAccount -ConjurUsername $ConjurUsername -ConjurPassword $ConjurPassword -ConjurApplianceUrl $ConjurApplianceUrl -IamAuthnBranch $IamAuthnBranch -IgnoreSsl $IgnoreSsl - - $iamAuthn = Test-MandatoryParameter -EnvironmentVariableName "CONJUR_IAM_AUTHN_BRANCH" -Value $IamAuthnBranch -Ignore $true - $ConjurUsername = [uri]::EscapeDataString($ConjurUsername) - - $url = ([uri]"$ConjurApplianceUrl/authn/$ConjurAccount/$ConjurUsername/authenticate") - - if ($iamAuthn) { - $url = ([uri]"$ConjurApplianceUrl/authn-iam/$IamAuthnBranch/$ConjurAccount/$ConjurUsername/authenticate") - } - - fixuri $url - - return Send-HttpMethod -Url $url -Method POST -Body $apiKey -} <# .SYNOPSIS @@ -378,21 +479,11 @@ https://www.conjur.org/api.html#health-get-health #> Function Get-ConjurHealth { - param( - $ConjurAccount = $env:CONJUR_ACCOUNT, - $ConjurUsername = $env:CONJUR_AUTHN_LOGIN, - $ConjurPassword = $env:CONJUR_AUTHN_API_KEY, - $ConjurApplianceUrl = $env:CONJUR_APPLIANCE_URL, - # $ConjurCert = $env:CONJUR_CERT, - $IgnoreSsl = $false - ) - - if (!(Test-MandatoryParameters)) { return } - if (($IgnoreSsl)) { Disable-SslVerification } - - $url = "$ConjurApplianceUrl/health" - return Send-HttpMethod -Url $url -Method "GET" + [CmdletBinding()] + param( ) + return Invoke-Conjur health } +Export-ModuleMember -Function Get-ConjurHealth <# .SYNOPSIS @@ -426,28 +517,15 @@ https://www.conjur.org/api.html#secrets-retrieve-a-secret-get #> -Function Get-ConjurSecret() { - param( - [Parameter(Position=0,mandatory=$true)] - [string]$SecretIdentifier, - $ConjurAccount = $env:CONJUR_ACCOUNT, - $ConjurUsername = $env:CONJUR_AUTHN_LOGIN, - $ConjurPassword = $env:CONJUR_AUTHN_API_KEY, - $ConjurApplianceUrl = $env:CONJUR_APPLIANCE_URL, - $IamAuthnBranch = $env:CONJUR_IAM_AUTHN_BRANCH, - [Switch] - $IgnoreSsl, +Function Get-ConjurSecret { + [CmdletBinding()] + param( + [Parameter(Position=0,mandatory=$true)][string]$SecretIdentifier, $SecretKind = "variable" ) - - $sessionToken = Get-ConjurSessionToken -ConjurAccount $ConjurAccount -ConjurUsername $ConjurUsername -ConjurPassword $ConjurPassword -ConjurApplianceUrl $ConjurApplianceUrl -IamAuthnBranch $IamAuthnBranch -IgnoreSsl $IgnoreSsl - $header = Get-SessionTokenHeader -SessionToken $sessionToken - # $SecretIdentifier = [uri]::EscapeDataString($SecretIdentifier) - $url = "$ConjurApplianceUrl/secrets/$ConjurAccount/$SecretKind/$SecretIdentifier" - # FixUri $url - - return Send-HttpMethod -Url $url -Method GET -Header $header + return Invoke-Conjur secrets "$SecretKind/$SecretIdentifier" } +Export-ModuleMember -Function Get-ConjurSecret <# .SYNOPSIS @@ -485,27 +563,15 @@ https://www.conjur.org/api.html#secrets-add-a-secret-post #> Function Set-ConjurSecret { - param( - [Parameter(Position=0,mandatory=$true)] - [string]$SecretIdentifier, - [Parameter(Position=1,mandatory=$true)] - [string]$SecretValue, - $ConjurAccount = $env:CONJUR_ACCOUNT, - $ConjurUsername = $env:CONJUR_AUTHN_LOGIN, - $ConjurPassword = $env:CONJUR_AUTHN_API_KEY, - $ConjurApplianceUrl = $env:CONJUR_APPLIANCE_URL, - $IamAuthnBranch = $env:CONJUR_IAM_AUTHN_BRANCH, - [Switch] - $IgnoreSsl, - $SecretKind = "variable" + [CmdletBinding()] + param( + [Parameter(Position=0,mandatory)][string]$SecretIdentifier, + [Parameter(Position=1,mandatory)][string]$SecretValue, + [Parameter(Position=2)][string]$SecretKind = "variable" ) - - $sessionToken = Get-ConjurSessionToken -ConjurAccount $ConjurAccount -ConjurUsername $ConjurUsername -ConjurPassword $ConjurPassword -ConjurApplianceUrl $ConjurApplianceUrl -IamAuthnBranch $IamAuthnBranch -IgnoreSsl $IgnoreSsl - $header = Get-SessionTokenHeader -SessionToken $sessionToken - $url = "$ConjurApplianceUrl/secrets/$ConjurAccount/$SecretKind/$SecretIdentifier" - - return Send-HttpMethod -Url $url -Method POST -Header $header -Body $SecretValue + return Invoke-Conjur secrets "$SecretKind/$SecretIdentifier" -Body $SecretValue } +Export-ModuleMember -Function Set-ConjurSecret <# .SYNOPSIS @@ -547,27 +613,19 @@ https://www.conjur.org/api.html#policies-update-a-policy-patch #> Function Update-ConjurPolicy { - param( - [Parameter(Position=0,mandatory=$true)] - [string]$PolicyIdentifier, - [Parameter(Position=1,mandatory=$true)] - [string]$PolicyFilePath, - $ConjurAccount = $env:CONJUR_ACCOUNT, - $ConjurUsername = $env:CONJUR_AUTHN_LOGIN, - $ConjurPassword = $env:CONJUR_AUTHN_API_KEY, - $ConjurApplianceUrl = $env:CONJUR_APPLIANCE_URL, - $IamAuthnBranch = $env:CONJUR_IAM_AUTHN_BRANCH, - [Switch] - $IgnoreSsl + [CmdletBinding()] + param( + [Parameter(Position=0,mandatory=$true)][string]$PolicyIdentifier, + [Parameter(Position=1,mandatory=$true)][string]$PolicyFilePath ) - $sessionToken = Get-ConjurSessionToken -ConjurAccount $ConjurAccount -ConjurUsername $ConjurUsername -ConjurPassword $ConjurPassword -ConjurApplianceUrl $ConjurApplianceUrl -IamAuthnBranch $IamAuthnBranch -IgnoreSsl $IgnoreSsl - $header = Get-SessionTokenHeader -SessionToken $sessionToken - $url = "$ConjurApplianceUrl/policies/$ConjurAccount/policy/$PolicyIdentifier" + + $url = "policies/$($CCConfig.CONJUR_ACCOUNT)/policy/$PolicyIdentifier" $policyContent = Get-Content -Path $PolicyFilePath -Raw - return Send-HttpMethod -Url $url -Header $header -Method PATCH -Body $policyContent + return Invoke-Conjur policies "policy/$PolicyIdentifier" -Body $policyContent } +Export-ModuleMember -Function Update-ConjurPolicy <# .SYNOPSIS @@ -607,29 +665,17 @@ https://www.conjur.org/api.html#policies-replace-a-policy #> -Function Replace-ConjurPolicy { - param( - [Parameter(Position=0,mandatory=$true)] - [string]$PolicyIdentifier, - [Parameter(Position=1,mandatory=$true)] - [string]$PolicyFilePath, - $ConjurAccount = $env:CONJUR_ACCOUNT, - $ConjurUsername = $env:CONJUR_AUTHN_LOGIN, - $ConjurPassword = $env:CONJUR_AUTHN_API_KEY, - $ConjurApplianceUrl = $env:CONJUR_APPLIANCE_URL, - $IamAuthnBranch = $env:CONJUR_IAM_AUTHN_BRANCH, - [Switch] - $IgnoreSsl +Function Set-ConjurPolicy { + [CmdletBinding()] + param( + [Parameter(Position=0,mandatory=$true)][string]$PolicyIdentifier, + [Parameter(Position=1,mandatory=$true)][string]$PolicyFilePath ) - - $sessionToken = Get-ConjurSessionToken -ConjurAccount $ConjurAccount -ConjurUsername $ConjurUsername -ConjurPassword $ConjurPassword -ConjurApplianceUrl $ConjurApplianceUrl -IamAuthnBranch $IamAuthnBranch -IgnoreSsl $IgnoreSsl - $header = Get-SessionTokenHeader -SessionToken $sessionToken - $url = "$ConjurApplianceUrl/policies/$ConjurAccount/policy/$PolicyIdentifier" $policyContent = Get-Content -Path $PolicyFilePath -Raw - - return Send-HttpMethod -Url $url -Header $header -Method PUT -Body $policyContent + return Invoke-Conjur policies "policy/$PolicyIdentifier" -Method PUT -Body $policyContent } - +New-Alias Replace-ConjurPolicy Set-ConjurPolicy +Export-ModuleMember -Function Set-ConjurPolicy -Alias Replace-ConjurPolicy <# .SYNOPSIS @@ -669,30 +715,20 @@ https://www.conjur.org/api.html#policies-append-to-a-policy #> -Function Append-ConjurPolicy { - param( - [Parameter(Position=0,mandatory=$true)] - [string]$PolicyIdentifier, - [Parameter(Position=1,mandatory=$true)] - [string]$PolicyFilePath, - $ConjurAccount = $env:CONJUR_ACCOUNT, - $ConjurUsername = $env:CONJUR_AUTHN_LOGIN, - $ConjurPassword = $env:CONJUR_AUTHN_API_KEY, - $ConjurApplianceUrl = $env:CONJUR_APPLIANCE_URL, - $IamAuthnBranch = $env:CONJUR_IAM_AUTHN_BRANCH, - [Switch] - $IgnoreSsl +Function Write-ConjurPolicy { + [CmdletBinding()] + param( + [Parameter(Position=0,mandatory=$true)][string]$PolicyIdentifier, + [Parameter(Position=1,mandatory=$true)][string]$PolicyFilePath ) - $sessionToken = Get-ConjurSessionToken -ConjurAccount $ConjurAccount -ConjurUsername $ConjurUsername -ConjurPassword $ConjurPassword -ConjurApplianceUrl $ConjurApplianceUrl -IamAuthnBranch $IamAuthnBranch -IgnoreSsl $IgnoreSsl - $header = Get-SessionTokenHeader -SessionToken $sessionToken - $url = "$ConjurApplianceUrl/policies/$ConjurAccount/policy/$PolicyIdentifier" + $url = "$ConjurApplianceUrl/policies/$($CCConfig.CONJUR_ACCOUNT)/policy/$PolicyIdentifier" $policyContent = Get-Content -Path $PolicyFilePath -Raw - return Send-HttpMethod -Url $url -Header $header -Method POST -Body $policyContent + return Invoke-Conjur policies "policy/$PolicyIdentifier" -Url $url -Header $header -Method POST -Body $policyContent } - - +New-Alias Append-ConjurPolicy Write-ConjurPolicy +Export-ModuleMember -Function Write-ConjurPolicy -Alias Append-ConjurPolicy <# .SYNOPSIS @@ -729,28 +765,16 @@ https://www.conjur.org/api.html#role-based-access-control-list-resources-get #> Function Get-ConjurResources { - param( - $ConjurAccount = $env:CONJUR_ACCOUNT, - $ConjurUsername = $env:CONJUR_AUTHN_LOGIN, - $ConjurPassword = $env:CONJUR_AUTHN_API_KEY, - $ConjurApplianceUrl = $env:CONJUR_APPLIANCE_URL, - $IamAuthnBranch = $env:CONJUR_IAM_AUTHN_BRANCH, - [Switch] - $IgnoreSsl - ) + [CmdletBinding()] + Param() + return Invoke-Conjur resources +} +Export-ModuleMember -Function Get-ConjurResources + + - $sessionToken = Get-ConjurSessionToken -ConjurAccount $ConjurAccount -ConjurUsername $ConjurUsername -ConjurPassword $ConjurPassword -ConjurApplianceUrl $ConjurApplianceUrl -IamAuthnBranch $IamAuthnBranch -IgnoreSsl $IgnoreSsl - $header = Get-SessionTokenHeader -SessionToken $sessionToken - $url = "$ConjurApplianceUrl/resources/$ConjurAccount" - return Send-HttpMethod -Url $url -Header $header -Method GET -} -Export-ModuleMember -Function Get-ConjurHealth -Export-ModuleMember -Function Get-ConjurSecret -Export-ModuleMember -Function Set-ConjurSecret -Export-ModuleMember -Function Update-ConjurPolicy Export-ModuleMember -Function Replace-ConjurPolicy -Export-ModuleMember -Function Append-ConjurPolicy -Export-ModuleMember -Function Get-ConjurResources + From 41374f564d13db1a98fa531e2c08cb857c66c284 Mon Sep 17 00:00:00 2001 From: "Thomas Farray (tfarray)" Date: Fri, 24 Sep 2021 15:04:59 +0200 Subject: [PATCH 03/12] so many changes !!! I am not sure I can explain them all --- CyberarkConjur.psm1 | 621 ++++++++++++++++++++++++++++++-------------- README.md | 129 ++++++--- 2 files changed, 524 insertions(+), 226 deletions(-) diff --git a/CyberarkConjur.psm1 b/CyberarkConjur.psm1 index e4bdc29..935796d 100644 --- a/CyberarkConjur.psm1 +++ b/CyberarkConjur.psm1 @@ -4,17 +4,17 @@ ############################### $CCConfig = @{ - AWS_MetaData = "169.254.169.254" - CONJUR_ACCOUNT = $null - CONJUR_AUTHAURITY_NAME = $null - CONJUR_AUTHAURITY_NAME_WR = $null - CONJUR_IAM_AUTHN_BRANCH = $null - Certificate = $null # This has not been explained in the former Module - Token = $null - TokenTTL = 6 * 60 - # maybe this can be fetched : https://docs.cyberark.com/Product-Doc/OnlineHelp/AAM-DAP/Latest/en/Content/Developer/Conjur_API_whoami.htm?tocpath=Developer%7CREST%C2%A0APIs%7C_____3 - Credential = $null - TokenExpireDate = $null + AWS_MetaData = "169.254.169.254" + Account = $null + AuthaurityName = $null + AuthaurityName_WR = $null + IamAuthnBranch = $null + Certificate = $null # This has not been explained in the former Module + Token = $null + APIKey = $null + TokenTTL = 6 * 60 + Credential = $null + TokenExpireDate = $null } ############################### @@ -24,11 +24,15 @@ Function Invoke-Conjur { [CmdletBinding()] param( [Parameter(Position=0,Mandatory)][string]$API, - [Parameter(Position=1)][string]$Command, - [Parameter(Position=2)][string]$Body, - [string]$Method = "GET" + [Parameter(Position=1)][string[]]$Command, + [Parameter(Position=2)][string[]]$Search, + [Parameter(Position=3)][string]$Body, + [string]$Method = "GET", + # [Hashtable]$Headers = @{ "Content-Type" = "application/json" }, + [Hashtable]$Headers = @{ }, + [switch]$FixUri ) - process { + process { ############################## # Initialization ############################## @@ -37,89 +41,81 @@ Function Invoke-Conjur { switch -regex ($CalledBy) { "^Remove-" { $method = "DELETE" } "^Update-" { $method = "PATCH" } - # "^(Set|add)-" { $method = "PUT" } - "^(Set|New|Submit|Write)-" { $method = "POST" } + "^(add|Update)-" { $method = "POST" } + "^(Set|New|Submit|Write)-" { $method = "PUT" } } } - $Authority = $CCConfig.CONJUR_AUTHAURITY_NAME - if ($Method -notlike "GET" -and $CCConfig.CONJUR_AUTHAURITY_NAME_WR) { + $Authority = $CCConfig.AuthaurityName + if ($Method -notlike "GET" -and $CCConfig.AuthaurityName_WR -and $API -notmatch 'authn') { Write-verbose "Switching to WRITE" - $Authority = $CCConfig.CONJUR_AUTHAURITY_NAME_WR - } + $Authority = $CCConfig.AuthaurityName_WR + } - if ($API -match "WhoAmI|health") { - $URL = ($Authority,$API) -join "/" - } else { - $URL = ($Authority,$API,$CCConfig.CONJUR_ACCOUNT,$Command ) -join "/" + $Commands = (@($Authority,$API) + $Command) | ? { $_ } + Write-verbose "#### $($commands -join '||')" + $Commands = ( $Commands -join "/") -replace "//+","/" -replace '/$' + $Commands = $Commands -replace "/!a","/$($CCConfig.Account)" + if ($PsBoundParameters.containskey("search")) { + $commands = ($Commands -replace '/?$' ) + "?" + ($Search -join ',') } - $URL = "https://" + ($URL -replace "//+","/" -replace '/$') + $URL = "https://$Commands" $RestMethod = @{ Method = $Method - Headers = @{} + Headers = $Headers URI = [uri]$URL } - if ($Command -match "^authn") { fixUri $RestMethod.URI } - ############################## - # Authentication verification + # Fixing URI the URI contains \ that should not be interpreted as URI path but as data ############################## - if ((!$CCConfig.Token -or ((get-date) -gt $CCConfig.TokenExpireDate))-and $API -notmatch 'authn') { - Write-Verbose "Invoke-Conjur : Authentication verification called by $CalledBy" - $ConjurUsername = [uri]::EscapeDataString($CCConfig.Credential.username) + if ($PsBoundParameters.containskey("FixUri")) { + $UnEscapeDotsAndSlashes = 0x2000000; + $SimpleUserSyntax = 0x20000; - # Checking inputs - $MissingConfig = @() - "CONJUR_ACCOUNT","CONJUR_AUTHAURITY_NAME","Credential" | % { - if (!$CCConfig[$_]) { $MissingConfig += $_ } - } - if ($MissingConfig) { - write-Warning "The Conjur Module is not configured. Please run the [Initialize-ConjurConfiguration] command to configure the module. You can also run [get-help Initialize-ConjurConfiguration] for more information." - return - } - - # Getting the API Key - $StartTime = Get-date - if ($CCConfig.CONJUR_IAM_AUTHN_BRANCH) { - Get-IamConjurApiKey + $type = $RestMethod.uri.GetType(); + $fieldInfo = $type.GetField("m_Syntax", ([System.Reflection.BindingFlags]::Instance -bor [System.Reflection.BindingFlags]::NonPublic)); + + $uriParser = $fieldInfo.GetValue($RestMethod.uri); + $typeUriParser = $uriParser.GetType().BaseType; + $fieldInfo = $typeUriParser.GetField("m_Flags", ([System.Reflection.BindingFlags]::Instance -bor [System.Reflection.BindingFlags]::NonPublic -bor [System.Reflection.BindingFlags]::FlattenHierarchy)); + $uriSyntaxFlags = $fieldInfo.GetValue($uriParser); + + $uriSyntaxFlags = $uriSyntaxFlags -band (-bnot $UnEscapeDotsAndSlashes); + $uriSyntaxFlags = $uriSyntaxFlags -band (-bnot $SimpleUserSyntax); + $fieldInfo.SetValue($uriParser, $uriSyntaxFlags); + } + + ############################## + # Authentication verification + ############################## + + if ( $API -notmatch 'authn') { + if ($CCConfig.IamAuthnBranch) { + $ApiKey = Get-IamConjurApiKey } else { - $ApiKey = Invoke-Conjur authn login -verbose - Write-Verbose "API key = $ApiKey" # $($API.SubString(0,10))..." + $ApiKey = Receive-ConjurLogin } - if (!$ApiKey) { - write-Warning "The Conjur Module was not able retrieve the API Key. Please run the [Initialize-ConjurConfiguration] command to configure the module. You can also run [get-help Initialize-ConjurConfiguration] for more information." - throw "failed" + if (!$ApiKey) { throw "CyberArkConjour Module Failed to retrieve an API Key" } + if ($CCConfig.IamAuthnBranch) { + # $TokenAPI = "authn-iam" + # $TokenCommand += "$($CCConfig.IamAuthnBranch)/" + # $TokenCommand += "$ConjurUsername/authenticate" + } else { + $Auth = Receive-ConjurAuthenticate -ApiKey $ApiKey } - - # Getting the Token - $TokenAPI = "authn" - $TokenCommand = "" - if ($CCConfig.CONJUR_IAM_AUTHN_BRANCH) { - $TokenAPI = "authn-iam" - $TokenCommand += "$($CCConfig.CONJUR_IAM_AUTHN_BRANCH)/" - } - $TokenCommand += "$ConjurUsername/authenticate" - write-verbose "TokenCommand : $TokenCommand" - $CCConfig.Token = Invoke-Conjur $TokenAPI $TokenCommand -Body $apiKey -Method POST - if (!$CCConfig.Token) { - write-Warning "The Conjur Module was not able to authenticate. Please run the [Initialize-ConjurConfiguration] command to configure the module. You can also run [get-help Initialize-ConjurConfiguration] for more information." - return + if (!$Auth) { + throw "CyberArkConjour Module Failed to Authenticate (the API Key was generated)" } - $CCConfig.TokenExpireDate = $StartTime.AddSeconds($CCConfig.TokenTTL) } ############################## - # Headers + # Headers (Token) ############################## - if ($API -match 'authn') { - Write-Verbose "Generating Headers for $($CCConfig.Credential.UserName) " - $base64 = [Convert]::ToBase64String([Text.Encoding]::ASCII.GetBytes(("{0}:{1}" -f $CCConfig.Credential.UserName, $CCConfig.Credential.GetNetworkCredential().password))) - $RestMethod.Headers.add("Authorization","Basic $base64") - } else { + if (!$PsBoundParameters.containskey("Headers")) { $base64 = [Convert]::ToBase64String([Text.Encoding]::ASCII.GetBytes((($CCConfig.Token | ConvertTo-Json)))) $RestMethod.Headers.add("Authorization","Token token=""$base64""") } @@ -162,19 +158,19 @@ Export-ModuleMember -Function Invoke-Conjur Function Initialize-Conjur { [CmdletBinding(DefaultParameterSetName="Credential")] Param( - [string]$CONJUR_ACCOUNT, - [parameter(ParameterSetName='Login',mandatory)][string]$CONJUR_AUTHN_LOGIN, - [parameter(ParameterSetName='Login',mandatory)][string]$CONJUR_AUTHN_API_KEY, + [string]$Account, + [parameter(ParameterSetName='Login',mandatory)][string]$AuthnLogin, + [parameter(ParameterSetName='Login',mandatory)][string]$AuthnApiKey, [parameter(ParameterSetName='Credential')][PSCredential]$Credential, - [string]$CONJUR_AUTHAURITY_NAME, - [string]$CONJUR_AUTHAURITY_NAME_WR, - [string]$CONJUR_IAM_AUTHN_BRANCH, + [string]$AuthaurityName, + [string]$AuthaurityName_WR, + [string]$IamAuthnBranch, [string]$AWS_MetaData, [Switch]$IgnoreSsl ) Process { $ParamatersToIgnore = ([System.Management.Automation.PSCmdlet]::CommonParameters + [System.Management.Automation.PSCmdlet]::OptionalCommonParameters) - $ParamatersToIgnore += @('CONJUR_AUTHN_LOGIN','CONJUR_AUTHN_API_KEY',"IgnoreSsl") + $ParamatersToIgnore += @('AuthnLogin','AuthnApiKey',"IgnoreSsl") $PsBoundParameters.keys | ? { $_ -notin $ParamatersToIgnore } | % { Switch ($_) { @@ -196,11 +192,11 @@ Function Initialize-Conjur { [Net.ServicePointManager]::SecurityProtocol = [Net.ServicePointManager]::SecurityProtocol -bor [Net.SecurityProtocolType]::Tls12 } catch { } } - CONJUR_IAM_AUTHN_BRANCH { + IamAuthnBranch { $CCConfig[$_] = $PsBoundParameters.item($_) $CCConfig["Credential"] = $null } - CONJUR_AUTHAURITY_NAME{ + AuthaurityName{ $CCConfig[$_] = $PsBoundParameters.item($_) -replace "http.://" } @@ -213,15 +209,20 @@ Function Initialize-Conjur { if ($PsCmdlet.ParameterSetName -like "Login") { write-warning "Please note that manipulating Credential object is always more secure. Please consider using the -Credential $CredObject instead" - [securestring]$SS = ConvertTo-SecureString $CONJUR_AUTHN_API_KEY -AsPlainText -Force + [securestring]$SS = ConvertTo-SecureString $AuthnApiKey -AsPlainText -Force - $CCConfig["Credential"] = New-Object System.Management.Automation.PSCredential ($CONJUR_AUTHN_LOGIN, $SS) - $CCConfig["CONJUR_IAM_AUTHN_BRANCH"] = $null + $CCConfig["Credential"] = New-Object System.Management.Automation.PSCredential ($AuthnLogin, $SS) + $CCConfig["IamAuthnBranch"] = $null } } } Export-ModuleMember -Function Initialize-Conjur +Function Show-ConjurConfiguration { + return $CCConfig +} +Export-ModuleMember -Function Show-ConjurConfiguration + ############################### # Internal Functions @@ -246,41 +247,7 @@ Function Get-ResponseBodyFromException { return $responseBody } -Function Get-HeaderAsString() { - [CmdletBinding()] - param( - $Header - ) - $headerAsString = "" - - if ($Header -ne $null) { - foreach ($kv in $Header.GetEnumerator()) { - $headerAsString += "$($kv.Name)=$($kv.Value);" - } - } - return $headerAsString -} - -Function Test-MandatoryParameter { - [CmdletBinding()] - param( - $EnvironmentVariableName, - $Value, - $Ignore = $false - ) - - if ([string]::IsNullOrWhiteSpace($Value)) { - if (!$Ignore) { - Write-Host -ForegroundColor RED "Mandatory parameter is empty or missing: $EnvironmentVariableName" - } - return $false - } else { - Write-Verbose "$EnvironmentVariableName=$Value" - } - - return $true -} ############################### # Internal IAM Functions @@ -390,7 +357,7 @@ function Get-IamAuthorizationHeader { return "$($algorithm) Credential=$($cAccessKeyId)/$($cred_scope), SignedHeaders=$($signed_headers), Signature=$($signature)" } -Function Get-IamConjurApiKey { +Function Receive-ConjurIamLogin { [CmdletBinding()] param() @@ -399,10 +366,10 @@ Function Get-IamConjurApiKey { $cred_results = Invoke-Conjur "latest/meta-data/iam/security-credentials/$role" - $region = $region.Substring(0, $region.Length -1) - $t = [DateTimeOffset]::UtcNow - $x_amz_date = $t.ToString("yyyyMMddTHHmmssZ") - $access_key_id = $cred_results.AccessKeyId + $region = $region.Substring(0, $region.Length -1) + $t = [DateTimeOffset]::UtcNow + $x_amz_date = $t.ToString("yyyyMMddTHHmmssZ") + $access_key_id = $cred_results.AccessKeyId $secret_access_key = $cred_results.SecretAccessKey $x_amz_security_token = $cred_results.Token @@ -420,32 +387,216 @@ Function Get-IamConjurApiKey { return $conjurToken } - +set-alias Get-IamConjurApiKey Receive-ConjurIamLogin -# This is required because powershell will automatically decode %2F to / to avoid that we must run this method on the uri that contains %2F -function FixUri { - [CmdletBinding()] - param($uri) + + +############################### +# Exported Functions +############################### +<# +.SYNOPSIS + +Gets the API key of a user given the username and password via HTTP Basic Authentication & Stores the information in memory. + +.DESCRIPTION + +Passwords are stored in the Conjur database using bcrypt with a work factor of 12. Therefore, login is a fairly expensive operation. However, once the API key is obtained, it may be used to inexpensively obtain access tokens by calling the Authenticate method. An access token is required to use most other parts of the Conjur API. + +Your HTTP/REST client probably provides HTTP basic authentication support. For example, curl and all of the Conjur client libraries provide this. + +.PARAMETER Force +Will force to renew the APIKey, even if it has already been stored in memory. + +.PARAMETER Silent +Will not return the APIKey, but will store it in memory. + +.INPUTS + +None. You cannot pipe objects to Receive-ConjurLogin. + +.OUTPUTS + +String. The API key. + +.EXAMPLE + +PS> $APIKey = Receive-ConjurLogin + + +.LINK + +https://docs.conjur.org/Latest/en/Content/Developer/Conjur_API_Login.htm + + +#> +Function Receive-ConjurLogin { + [CmdletBinding()] + param( + [switch]$Force + ) + process { + if ( !$CCConfig.APIKey -or $PsBoundParameters.containskey("force") ) { + $MissingConfig = "Account","AuthaurityName","Credential" | ? { !$CCConfig[$_] } + if ($MissingConfig) { + write-Warning "The Conjur Module is is missing information : [$($MissingConfig -join ',')] . Please run the [Initialize-ConjurConfiguration] command with the above switches. You can also run [get-help Initialize-ConjurConfiguration] for more information." + return + } + $base64 = [Convert]::ToBase64String([Text.Encoding]::ASCII.GetBytes(("{0}:{1}" -f $CCConfig.Credential.UserName, $CCConfig.Credential.GetNetworkCredential().password))) + $CCConfig.APIKey = Invoke-Conjur authn !a,login -headers @{ Authorization = "Basic $base64" } + } + return $CCConfig.APIKey + } +} +Export-ModuleMember -Function Receive-ConjurLogin + +<# +.SYNOPSIS + +Gets a short-lived access token, which is required in the header of most subsequent API requests. A client can obtain an access token by presenting a valid login name and API key. + + + +.DESCRIPTION + +The access token is used to communicate to the REST API that the bearer of the token has been authorized to access the API and perform specific actions specified by the scope that was granted during authorization. + +The login must be URL encoded. For example, alice@devops must be encoded as alice%40devops. + +For host authentication, the login is the host ID with the prefix host/. For example, the host webserver would login as host/webserver, and would be encoded as host%2Fwebserver. + + +.INPUTS + +None. You cannot pipe objects to Receive-ConjurAuthenticate. + +.OUTPUTS + +String. The Authentication Token. + +.EXAMPLE + +PS> $Token = Receive-ConjurAuthenticate + + +.LINK + +https://docs.conjur.org/Latest/en/Content/Developer/Conjur_API_Authenticate.htm + + +#> +Function Receive-ConjurAuthenticate { + [CmdletBinding()] + param( + [string]$ApiKey = $CCConfig.APIKey, + [Switch]$Force + ) + process { + if (!$CCConfig.Token -or $PsBoundParameters.containskey("force") -or ((get-date) -gt $CCConfig.TokenExpireDate)) { + $StartTime = Get-date + if ( !$APIKey ) { + write-warning "No API Key was generated, you need to run [Receive-ConjurLogin | out-null] first" + } + $ConjurUsername = [uri]::EscapeDataString($CCConfig.Credential.username) + + $CCConfig.Token = Invoke-Conjur authn !a,$ConjurUsername,authenticate -Body $APIKey -Method POST -FixUri -Headers @{ } + + if (!$CCConfig.Token) { + write-Warning "The Conjur Module was not able to authenticate. Please run the [Initialize-ConjurConfiguration] command to configure the module. You can also run [get-help Initialize-ConjurConfiguration] for more information." + return + } else { + $CCConfig.TokenExpireDate = $StartTime.AddSeconds($CCConfig.TokenTTL) + } + } - $UnEscapeDotsAndSlashes = 0x2000000; - $SimpleUserSyntax = 0x20000; + return $CCConfig.Token + } +} +Export-ModuleMember -Function Receive-ConjurAuthenticate + - $type = $uri.GetType(); - $fieldInfo = $type.GetField("m_Syntax", ([System.Reflection.BindingFlags]::Instance -bor [System.Reflection.BindingFlags]::NonPublic)); +<# +.SYNOPSIS - $uriParser = $fieldInfo.GetValue($uri); - $typeUriParser = $uriParser.GetType().BaseType; - $fieldInfo = $typeUriParser.GetField("m_Flags", ([System.Reflection.BindingFlags]::Instance -bor [System.Reflection.BindingFlags]::NonPublic -bor [System.Reflection.BindingFlags]::FlattenHierarchy)); - $uriSyntaxFlags = $fieldInfo.GetValue($uriParser); +The Conjur IAM Authenticator allows an AWS resource to use its AWS IAM role to authenticate with Conjur - $uriSyntaxFlags = $uriSyntaxFlags -band (-bnot $UnEscapeDotsAndSlashes); - $uriSyntaxFlags = $uriSyntaxFlags -band (-bnot $SimpleUserSyntax); - $fieldInfo.SetValue($uriParser, $uriSyntaxFlags); + + +.DESCRIPTION + +The Conjur IAM Authenticator allows an AWS resource to use its AWS IAM role to authenticate with Conjur. This approach enables EC2 instances and Lambda functions to access credentials stored in Conjur without a pre-configured Conjur identity. + +To learn more, see IAM roles in the AWS Documentation. + +To enable an IAM Authenticator, for example, prod, set the following environment variable when you start a Conjur with the [Initialize-Conjur -IamAuthnBranch BranchName] Command + +.INPUTS + +None. You cannot pipe objects to Receive-ConjurIAMAuthenticate. + +.OUTPUTS + +To Be completed + +.EXAMPLE + +To Be Completed + +.LINK + +https://docs.conjur.org/Latest/en/Content/Operations/Services/AWS_IAM_Authenticator.htm + + +#> +Function Receive-ConjurIAMAuthenticate { + [CmdletBinding()] + param( ) + process { + $region = Invoke-ConjurIam -command "latest/meta-data/placement/availability-zone" + $role = Invoke-ConjurIam "/latest/meta-data/iam/security-credentials" + $cred_results = Invoke-Conjur "latest/meta-data/iam/security-credentials/$role" + } } +Export-ModuleMember -Function Receive-ConjurAuthenticate -############################### -# Exported Functions -############################### + +<# +.SYNOPSIS + +WhoAmI provides information about the client making an API request + +.DESCRIPTION + +It can be used to help troubleshoot configuration by verifying authentication and the client IP address for audit and network access restrictions. For more information, see Host Attributes. + + +.INPUTS + +None. You cannot pipe objects to Receive-ConjurLogin. + +.OUTPUTS + +String. The API key. + +.EXAMPLE + +PS> $APIKey = Receive-ConjurLogin + + +.LINK + +https://docs.conjur.org/Latest/en/Content/Developer/Conjur_API_Login.htm + + +#> +Function Get-ConjurWhoAmI { + [CmdletBinding()] + param( ) + process { + return Invoke-Conjur whoami + } +} +Export-ModuleMember -Function Get-ConjurWhoAmI <# .SYNOPSIS @@ -488,14 +639,15 @@ Export-ModuleMember -Function Get-ConjurHealth <# .SYNOPSIS -Retrieve a secret from conjur +Retrieve one or multiple secrets from conjur .DESCRIPTION -Retrieve a secret from conjur -Takes a Secret identifier +Retrieve one or multiple secret from conjur +If one Identifier is selected, the returned object will be the value of the secret +If Multiple Identifier, the returned object will a PsObject with all the secrets in a single query -.PARAMETER SecretIdentifier +.PARAMETER Identifier The identifier used to retrieve the secret .INPUTS @@ -508,28 +660,91 @@ System.String. The secret retrieved. .EXAMPLE -PS> Get-ConjurSecret -SecretIdentifier "path/to/secret" +PS> Get-ConjurSecret -Identifier "path/to/secret/username" AHfdkrjeb81hs6ah -.LINK +PS> Get-ConjurSecret -Identifier "path/to/secret/S1", "path/to/secret/S2" +Account:variable:path/to/secret/S1 Account:variable:path/to/secret/S2 +---------------------------------- ---------------------------------- +TestS1 TestS2 -https://www.conjur.org/api.html#secrets-retrieve-a-secret-get +.LINK +https://docs.conjur.org/Latest/en/Content/Developer/Conjur_API_Retrieve_Secret.htm +https://docs.conjur.org/Latest/en/Content/Developer/Conjur_API_Batch_Retrieve.htm #> Function Get-ConjurSecret { [CmdletBinding()] param( - [Parameter(Position=0,mandatory=$true)][string]$SecretIdentifier, + [Parameter(Position=0,mandatory=$true)][string[]]$Identifier, $SecretKind = "variable" ) - return Invoke-Conjur secrets "$SecretKind/$SecretIdentifier" + + if ($Identifier.count -gt 1) { + $ModifiedSI = "variable_ids=" + $ModifiedSI += ($Identifier | % { ($CCConfig.Account,$SecretKind,$_) -join ":" }) -join ',' + return Invoke-Conjur secrets -Search $ModifiedSI + } else { + return Invoke-Conjur secrets !a,$SecretKind,($Identifier | select -first 1) + } } Export-ModuleMember -Function Get-ConjurSecret <# .SYNOPSIS +Get-ConjurSecretCredential is an helper function that will directly retrieve a credential object from Conjur + +.DESCRIPTION + +If you add to a single path 2 secrets, one called username and the other called password, you will directly retrieve the PsCredential object from it +for example, if you have those 2 keys : +myhome\subpath\username +myhome\subpath\password +You will be able to directly retrieve the PsCredential Object using the command [Get-ConjurSecretCredential variable\myhome\subpath] + + +.PARAMETER IdentifierPath +The path to a pair of username/password couple + +.INPUTS +None. You cannot pipe objects to Get-ConjurSecret. + +.OUTPUTS +PsCredential. The PsCredential object. + +.EXAMPLE + +PS> Get-ConjurSecretCredential "path/to/secret" + +UserName Password +-------- -------- +TheUserName System.Security.SecureString + + +#> +Function Get-ConjurSecretCredential { + [CmdletBinding()] + param( + [Parameter(Position=0,mandatory=$true)][string[]]$IdentifierPath + ) + $ToRetrieve = $IdentifierPath | % { @(($_ + "/username"),($_ + "/password")) } + $ToRetrieve = $ToRetrieve -replace "//+","/" + $AllSecrets = Get-ConjurSecret $ToRetrieve + $AllSP = $AllSecrets.psobject.Members | ? { $_.membertype -like "noteproperty" } | select -ExpandProperty name + $AllSP = $allSP -replace '/(password|username)$' | select -unique + $Results = $AllSp | % { + [securestring]$SS = ConvertTo-SecureString $AllSecrets."$_/password" -AsPlainText -Force + New-Object System.Management.Automation.PSCredential ($AllSecrets."$_/username", $SS ) + } + return $results +} +Export-ModuleMember -Function Get-ConjurSecretCredential + +<# +.SYNOPSIS + Set a secret in conjur .DESCRIPTION @@ -537,7 +752,7 @@ Set a secret in conjur Set a secret in conjur Takes a secret identifier and secret value -.PARAMETER SecretIdentifier +.PARAMETER Identifier The identifier used to set the secret .PARAMETER SecretValue @@ -545,7 +760,7 @@ The value of the secret .INPUTS -None. You cannot pipe objects to Set-ConjurSecret. +None. You cannot pipe objects to Update-ConjurSecret. .OUTPUTS @@ -553,7 +768,7 @@ None. .EXAMPLE -PS> Set-ConjurSecret -SecretIdentifier "path/to/secret" -SecretValue "newPasswordHere" +PS> Update-ConjurSecret -Identifier "path/to/secret" -SecretValue "newPasswordHere" .LINK @@ -562,28 +777,28 @@ https://www.conjur.org/api.html#secrets-add-a-secret-post #> -Function Set-ConjurSecret { +Function Update-ConjurSecret { [CmdletBinding()] param( - [Parameter(Position=0,mandatory)][string]$SecretIdentifier, + [Parameter(Position=0,mandatory)][string]$Identifier, [Parameter(Position=1,mandatory)][string]$SecretValue, [Parameter(Position=2)][string]$SecretKind = "variable" ) - return Invoke-Conjur secrets "$SecretKind/$SecretIdentifier" -Body $SecretValue + return Invoke-Conjur secrets !A,$SecretKind,$Identifier -Body $SecretValue } -Export-ModuleMember -Function Set-ConjurSecret +New-Alias Set-ConjurSecret Update-ConjurSecret +Export-ModuleMember -Function Update-ConjurSecret -Alias Set-ConjurSecret <# .SYNOPSIS -Update a policy in conjur +Modifies an existing Conjur policy .DESCRIPTION -Modifies an existing Conjur policy. Data may be explicitly deleted using the !delete, !revoke, and !deny statements. -Unlike “replace” mode, no data is ever implicitly deleted. +Data may be explicitly deleted using the !delete, !revoke, and !deny statements. Unlike “replace” mode, no data is ever implicitly deleted. -.PARAMETER PolicyIdentifier +.PARAMETER Identifier The identifier used to update the policy .PARAMETER PolicyFilePath @@ -599,7 +814,7 @@ None. .EXAMPLE -PS> Update-ConjurPolicy -PolicyIdentifier "root" -PolicyFilePath ".\test-policy.yml" +PS> Update-ConjurPolicy -Identifier "root" -PolicyFilePath ".\test-policy.yml" created_roles version ------------- ------- @@ -608,24 +823,22 @@ created_roles .LINK -https://www.conjur.org/api.html#policies-update-a-policy-patch +https://docs.conjur.org/Latest/en/Content/Developer/Conjur_API_Update_Policy.htm #> Function Update-ConjurPolicy { [CmdletBinding()] param( - [Parameter(Position=0,mandatory=$true)][string]$PolicyIdentifier, + [Parameter(Position=0,mandatory=$true)][string]$Identifier, [Parameter(Position=1,mandatory=$true)][string]$PolicyFilePath ) - - $url = "policies/$($CCConfig.CONJUR_ACCOUNT)/policy/$PolicyIdentifier" $policyContent = Get-Content -Path $PolicyFilePath -Raw - return Invoke-Conjur policies "policy/$PolicyIdentifier" -Body $policyContent + return Invoke-Conjur policies !A,policy,$Identifier -Body $policyContent } -Export-ModuleMember -Function Update-ConjurPolicy +Export-ModuleMember -Function Update-ConjurPolicy <# .SYNOPSIS @@ -636,7 +849,7 @@ Loads or replaces a Conjur policy document. Any policy data which already exists on the server but is not explicitly specified in the new policy file will be deleted. -.PARAMETER PolicyIdentifier +.PARAMETER Identifier The identifier used to update the policy .PARAMETER PolicyFilePath @@ -644,7 +857,7 @@ The path to the policy that will be loaded .INPUTS -None. You cannot pipe objects to Update-ConjurPolicy. +None. You cannot pipe objects to Set-ConjurPolicy. .OUTPUTS @@ -652,7 +865,7 @@ None. .EXAMPLE -PS> Replace-ConjurPolicy -PolicyIdentifier "root" -PolicyFilePath ".\test-policy.yml" +PS> Set-ConjurPolicy -Identifier "root" -PolicyFilePath ".\test-policy.yml" created_roles version ------------- ------- @@ -668,11 +881,11 @@ https://www.conjur.org/api.html#policies-replace-a-policy Function Set-ConjurPolicy { [CmdletBinding()] param( - [Parameter(Position=0,mandatory=$true)][string]$PolicyIdentifier, + [Parameter(Position=0,mandatory=$true)][string]$Identifier, [Parameter(Position=1,mandatory=$true)][string]$PolicyFilePath ) $policyContent = Get-Content -Path $PolicyFilePath -Raw - return Invoke-Conjur policies "policy/$PolicyIdentifier" -Method PUT -Body $policyContent + return Invoke-Conjur policies !A,policy,$Identifier -Body $policyContent } New-Alias Replace-ConjurPolicy Set-ConjurPolicy Export-ModuleMember -Function Set-ConjurPolicy -Alias Replace-ConjurPolicy @@ -680,13 +893,13 @@ Export-ModuleMember -Function Set-ConjurPolicy -Alias Replace-ConjurPolicy <# .SYNOPSIS -Loads a Conjur policy document. +Adds data to the existing Conjur policy. .DESCRIPTION -Adds data to the existing Conjur policy. Deletions are not allowed. Any policy objects that exist on the server but are omitted from the policy file will not be deleted and any explicit deletions in the policy file will result in an error. +Deletions are not allowed. Any policy objects that exist on the server but are omitted from the policy file will not be deleted and any explicit deletions in the policy file will result in an error -.PARAMETER PolicyIdentifier +.PARAMETER Identifier The identifier used to update the policy .PARAMETER PolicyFilePath @@ -694,7 +907,7 @@ The path to the policy that will be loaded .INPUTS -None. You cannot pipe objects to Update-ConjurPolicy. +None. You cannot pipe objects to Add-ConjurPolicy. .OUTPUTS @@ -702,7 +915,7 @@ None. .EXAMPLE -PS> Append-ConjurPolicy -PolicyIdentifier "root" -PolicyFilePath ".\test-policy.yml" +PS> Add-ConjurPolicy -Identifier "root" -PolicyFilePath ".\test-policy.yml" created_roles version ------------- ------- @@ -711,24 +924,23 @@ created_roles .LINK -https://www.conjur.org/api.html#policies-append-to-a-policy +https://docs.conjur.org/Latest/en/Content/Developer/Conjur_API_Append_Policy.htm #> -Function Write-ConjurPolicy { +Function Add-ConjurPolicy { [CmdletBinding()] param( - [Parameter(Position=0,mandatory=$true)][string]$PolicyIdentifier, + [Parameter(Position=0,mandatory=$true)][string]$Identifier, [Parameter(Position=1,mandatory=$true)][string]$PolicyFilePath ) - $url = "$ConjurApplianceUrl/policies/$($CCConfig.CONJUR_ACCOUNT)/policy/$PolicyIdentifier" $policyContent = Get-Content -Path $PolicyFilePath -Raw - - return Invoke-Conjur policies "policy/$PolicyIdentifier" -Url $url -Header $header -Method POST -Body $policyContent + return Invoke-Conjur policies !A,policy,$Identifier -Body $policyContent } -New-Alias Append-ConjurPolicy Write-ConjurPolicy -Export-ModuleMember -Function Write-ConjurPolicy -Alias Append-ConjurPolicy +New-Alias Append-ConjurPolicy Add-ConjurPolicy +Export-ModuleMember -Function Add-ConjurPolicy -Alias Append-ConjurPolicy + <# .SYNOPSIS @@ -767,14 +979,43 @@ https://www.conjur.org/api.html#role-based-access-control-list-resources-get Function Get-ConjurResources { [CmdletBinding()] Param() - return Invoke-Conjur resources + return Invoke-Conjur resources !A } Export-ModuleMember -Function Get-ConjurResources +<# +.SYNOPSIS +Gets detailed information about a specific role, including the role members. + +.DESCRIPTION +If a role A is granted to a role B, then role A is said to have role B as a member. These relationships are described in the “members” portion of the returned JSON + +.INPUTS +None. You cannot pipe objects to Get-ConjurRole. + +.OUTPUTS +PsObject. All the resources the user has access to +.EXAMPLE +PS> Get-ConjurRole user alice +created_at : 2017-08-02T18:18:42.346+00:00 +id : myorg:user:alice +policy : myorg:policy:root +members : {@{admin_option=True; ownership=True; role=myorg:user:alice; member=myorg:policy:root; policy=myorg:policy:root}} +.LINK -Export-ModuleMember -Function Replace-ConjurPolicy +https://docs.conjur.org/Latest/en/Content/Developer/Conjur_API_Show_Role.htm +#> +Function Get-ConjurRole { + [CmdletBinding()] + param( + [ValidateSet("user","host","layer","group","policy")] [Parameter(Position=0,mandatory=$true)][string]$kind, + [Parameter(Position=1,mandatory=$true)][string]$identifier + ) + return Invoke-Conjur roles !A,$kind,$identifier +} +Export-ModuleMember -Function Get-ConjurRole diff --git a/README.md b/README.md index b1145dc..a09eba1 100644 --- a/README.md +++ b/README.md @@ -17,90 +17,147 @@ Powershell-based API SDK for [Conjur OSS](https://www.conjur.org/). PS C:\> Import-Module .\CyberarkConjur.psm1 ``` +### From anywere +Edit you computer environment variables, and add the Module path to the variable PSModulePath + OR +copy the module to one of the existing path of that environment variable +```powershell +PS C:\> $env:PSModulePath # <<<< This will show all the existing path + +PS C:\> Import-Module CyberarkConjur +``` + ## Usage -### Setting environment variables +### Setting the module #### Conjur authentication +Prior to launching any commands, you will need to configure your conjur environment ```powershell -PS C:\> $env:CONJUR_ACCOUNT="dev" -PS C:\> $env:CONJUR_AUTHN_LOGIN="admin" -PS C:\> $env:CONJUR_AUTHN_API_KEY="adminPassword" -PS C:\> $env:CONJUR_APPLIANCE_URL="https://conjur.yourorg.com:443" +PS C:\> Initialize-Conjur -Account Account -AuthnLogin "Identifier of a host" -AuthnApiKey "Your API generated key" -AuthaurityName "your-conjur-auth-read.mycompany.com" ``` #### IAM Authentication +Some code has been started to be written, but is not good enough to publish anything yet. +This would require someone with an IAM access to continue developping this code + +### Available Functions +#### Initialize-Conjur + ```powershell -PS C:\> $env:CONJUR_ACCOUNT="dev" -PS C:\> $env:CONJUR_AUTHN_LOGIN="host/cust-portal/622703825757/ubuntu-client-conjur-identity" -PS C:\> $env:CONJUR_IAM_AUTHN_BRANCH="authnBranchName" -PS C:\> $env:CONJUR_APPLIANCE_URL="https://conjur.yourorg.com:443" +PS C:\> Initialize-Conjur -Account Account -AuthnLogin "Identifier of a host" -AuthnApiKey "Your API generated key" -AuthaurityName "your-conjur-auth-read.mycompany.com" ``` -### Available Functions -#### Get-ConjurSecret +#### Invoke-Conjur +All commands are running this command at the end. you may call it directly if required +```powershell +PS C:\> Invoke-ConjurIam API Command Search +``` +#### Receive-ConjurLogin +Retries the API key (done automatically) ```powershell -PS C:\> Get-ConjurSecret -SecretIdentifier "secrets/db-password" -secretPasswordHere +PS C:\> $APIKey = Receive-ConjurLogin ``` -#### Set-ConjurSecret +#### Receive-ConjurAuthenticate +Generates a Token from the API Key (done automatically) +```powershell +PS C:\> $Token = Receive-ConjurAuthenticate $ApiKey +``` +#### Get-ConjurWhoAmI +Only if Authenticated ```powershell -PS C:\> Set-ConjurSecret -SecretIdentifier "secrets/db-password" -SecretValue "brandNewSecret" +PS C:\> Get-ConjurWhoAmI + +client_ip : 10.0.0.10 +user_agent : Mozilla/5.0 (Windows NT; Windows NT 10.0; en-US) WindowsPowerShell/5.1.19041.1237 +account : account +username : host/PowerShellAutomation +token_issued_at : 2021-09-24T12:56:40.000+00:00 ``` #### Get-ConjurHealth - ```powershell PS C:\> Get-ConjurHealth -services database ok --------- -------- -- -@{possum=ok; ui=ok; ok=True} @{ok=True; connect=; free_space=; re... True +services : @{ldap-sync=disabled; possum=ok; ui=ok; ok=True} +database : @{ok=True; connect=; free_space=; replication_status=} +audit : @{ok=True; forwarded=} +ok : True +role : follower ``` -#### Replace-ConjurPolicy +#### Get-ConjurSecret ```powershell -PS C:\> Replace-ConjurPolicy -PolicyIdentifier "root" -PolicyFilePath ".\test-policy.yml" +PS C:\> Get-ConjurSecret -Identifier "Identifier/path/password" -created_roles version -------------- ------- -@{dev:host:database/another-host=} 4 +SecretWillShow ``` -#### Append-ConjurPolicy - +#### Get-ConjurSecretCredential ```powershell -PS C:\> Append-ConjurPolicy -PolicyIdentifier "root" -PolicyFilePath ".\test-policy.yml" +PS C:\> Get-ConjurSecretCredential "Identifier/path" + +UserName Password +-------- -------- +TheUserName System.Security.SecureString +``` +#### Update-ConjurSecret -created_roles version -------------- ------- -@{dev:host:database/another-host=} 5 +```powershell +PS C:\> Update-ConjurSecret -Identifier "path/to/secret" -SecretValue "newPasswordHere"" ``` #### Update-ConjurPolicy ```powershell -PS C:\> Update-ConjurPolicy -PolicyIdentifier "root" -PolicyFilePath ".\test-policy.yml" +PS C:\> Update-ConjurPolicy -Identifier "root" -PolicyFilePath ".\test-policy.yml" + +created_roles version +------------- ------- +@{dev:host:database/another-host=} 4 +``` +#### Set-ConjurPolicy + +```powershell +PS C:\> Set-ConjurPolicy -Identifier "root" -PolicyFilePath ".\test-policy.yml" -created_roles version -------------- ------- -@{dev:host:database/another-host=} 6 +created_roles version +------------- ------- +@{dev:host:database/another-host=} 4 ``` +#### Add-ConjurPolicy +```powershell +PS C:\> Add-ConjurPolicy -Identifier "root" -PolicyFilePath ".\test-policy.yml" + +created_roles version +------------- ------- +@{dev:host:database/another-host=} 4 +``` #### Get-ConjurResources ```powershell -PS C:\> Get-ConjurResources +PS C:\> Get-ConjurResources -Identifier "Identifier/path" created_at : 2019-05-29T16:42:56.284+00:00 id : dev:policy:root owner : dev:user:admin permissions : {} annotations : {} -policy_versions : {@{version=1; created_at=2019-05-29T16:42:56.284+00:00; policy_text=--- +policy_versions : {@{version=1; created_at=2019-05-29T16:42:56.284+00:00; policy_text=--- +``` +#### Get-ConjurRole + +```powershell +PS C:\> Get-ConjurRole user alice + +created_at : 2017-08-02T18:18:42.346+00:00 +id : myorg:user:alice +policy : myorg:policy:root +members : {@{admin_option=True; ownership=True; role=myorg:user:alice; member=myorg:policy:root; policy=myorg:policy:root}} ``` #### Get-Help From 1a53a81857e5ab81b4e1e3f0da3df875324a0b25 Mon Sep 17 00:00:00 2001 From: "Thomas Farray (tfarray)" Date: Fri, 24 Sep 2021 15:19:34 +0200 Subject: [PATCH 04/12] fixed readme.md to modify the text --- README.md | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/README.md b/README.md index a09eba1..8605440 100644 --- a/README.md +++ b/README.md @@ -32,6 +32,13 @@ PS C:\> Import-Module CyberarkConjur ### Setting the module #### Conjur authentication Prior to launching any commands, you will need to configure your conjur environment + +```powershell +PS C:\> $PsCredential = Get-Credential -Message "CyberArk Conjur Credential input" -UserName "host\Host_Identifier" +PS C:\> Initialize-Conjur -Account Account -AuthnLogin "Identifier of a host" -Crednetial $PsCredential +``` + + ```powershell PS C:\> Initialize-Conjur -Account Account -AuthnLogin "Identifier of a host" -AuthnApiKey "Your API generated key" -AuthaurityName "your-conjur-auth-read.mycompany.com" ``` From db5552dc504db83347828519287693e723cce644 Mon Sep 17 00:00:00 2001 From: "Thomas Farray (tfarray)" Date: Mon, 27 Sep 2021 15:49:44 +0200 Subject: [PATCH 05/12] added some functions --- CyberarkConjur.psm1 | 31 +++++++++++++++++++++++++++---- 1 file changed, 27 insertions(+), 4 deletions(-) diff --git a/CyberarkConjur.psm1 b/CyberarkConjur.psm1 index 935796d..66d981e 100644 --- a/CyberarkConjur.psm1 +++ b/CyberarkConjur.psm1 @@ -950,8 +950,13 @@ List resource within an organization account List resource within an organization account -.INPUTS +.PARAMETER Kind +Filters on the Kinds of resources. Valid Kinds are : user,host,layer,group,policy,variable,webservice + +.PARAMETER identifier +The identifier (path) of the object +.INPUTS None. You cannot pipe objects to Get-ConjurResources. .OUTPUTS @@ -970,6 +975,15 @@ annotations : {} policy_versions : {@{version=1; created_at=2019-05-29T16:42:56.284+00:00; policy_text=--- 4 +.EXAMPLE + +PS> Get-ConjurResources -Kind policy | select id +id +-- +dev:policy:root/mypolicy +dev:policy:root/mypolicy/myother +dev:policy:root/mypolicylast + .LINK https://www.conjur.org/api.html#role-based-access-control-list-resources-get @@ -977,9 +991,18 @@ https://www.conjur.org/api.html#role-based-access-control-list-resources-get #> Function Get-ConjurResources { - [CmdletBinding()] - Param() - return Invoke-Conjur resources !A + [CmdletBinding(DefaultParameterSetName="None")] + Param( + [Parameter(ParameterSetName='filter',mandatory)] + [ValidateSet("user","host","layer","group","policy","variable","webservice")][string]$Kind, + $identifier + ) + process { + $Command = @("!A") + if ( $psboundparameters.containskey("kind")) { $Command += $Kind } + if ( $psboundparameters.containskey("identifier")) { $Command += $identifier } + return Invoke-Conjur resources $Command + } } Export-ModuleMember -Function Get-ConjurResources From 53e55c2c5dd98aa29d9f96994f5b1b632c26b291 Mon Sep 17 00:00:00 2001 From: "Thomas Farray (tfarray)" Date: Tue, 28 Sep 2021 09:53:53 +0200 Subject: [PATCH 06/12] fixed psd1 file --- CyberarkConjur.psd1 | Bin 1764 -> 1766 bytes README.md | 25 ++++++++++++++++--------- 2 files changed, 16 insertions(+), 9 deletions(-) diff --git a/CyberarkConjur.psd1 b/CyberarkConjur.psd1 index 7542339324418a216dcc5db5ca27c96cdde0cd05..627c84dbf2549e8919eff4eb4eea2912cac48c27 100644 GIT binary patch delta 12 TcmaFD`;2$OIY#x3XT{k7B?bis delta 10 RcmaFH`-FGGxs4aZ*Z>{E1mFMw diff --git a/README.md b/README.md index 8605440..94ec821 100644 --- a/README.md +++ b/README.md @@ -3,7 +3,7 @@ Powershell-based API SDK for [Conjur OSS](https://www.conjur.org/). --- -### **Status**: Alpha +### **Status**: Beta - zamothh Fork #### **Warning: Naming and APIs are still subject to breaking changes!** @@ -11,20 +11,27 @@ Powershell-based API SDK for [Conjur OSS](https://www.conjur.org/). ## Installing the code -### From source +### How should the module be installed +There is an evironment variable called PSModulePath, that lists all the path where you can have module installed. +This allows you to import modules without having to specify the path + +Instructions : +copy the module to one of the existing path of that environment variable ($env:PSModulePath will tell you all of them) ```powershell -PS C:\> Import-Module .\CyberarkConjur.psm1 +PS C:\> cd $env:USERPROFILE\Documents\WindowsPowerShell\Modules +PS C:\Users\MyProfile\Documents\WindowsPowerShell\Modules> git clone https://github.com/zamothh/conjur-api-powershell.git CyberarkConjur ``` -### From anywere -Edit you computer environment variables, and add the Module path to the variable PSModulePath - OR -copy the module to one of the existing path of that environment variable +Once you cloned the project to a PsModulePath folder, you can import the module from any directory ```powershell -PS C:\> $env:PSModulePath # <<<< This will show all the existing path +PS C:\> import-module CyberarkConjur +``` -PS C:\> Import-Module CyberarkConjur +### From source + +```powershell +PS C:\> Import-Module .\CyberarkConjur.psm1 ``` ## Usage From 3f01f44260395217ab9cb6c757b29f3f10eefef0 Mon Sep 17 00:00:00 2001 From: "Thomas Farray (tfarray)" Date: Fri, 1 Oct 2021 18:30:51 +0200 Subject: [PATCH 07/12] lots of changes, still need a few --- CyberarkConjur.psm1 | 1326 ++++++++++++++++++++++++++++++++++++------- 1 file changed, 1126 insertions(+), 200 deletions(-) diff --git a/CyberarkConjur.psm1 b/CyberarkConjur.psm1 index 66d981e..f9a873a 100644 --- a/CyberarkConjur.psm1 +++ b/CyberarkConjur.psm1 @@ -15,6 +15,8 @@ $CCConfig = @{ TokenTTL = 6 * 60 Credential = $null TokenExpireDate = $null + IdentifierRootPath = $null + CommonParameters = ([System.Management.Automation.PSCmdlet]::CommonParameters + [System.Management.Automation.PSCmdlet]::OptionalCommonParameters) } ############################### @@ -25,12 +27,14 @@ Function Invoke-Conjur { param( [Parameter(Position=0,Mandatory)][string]$API, [Parameter(Position=1)][string[]]$Command, - [Parameter(Position=2)][string[]]$Search, - [Parameter(Position=3)][string]$Body, + [Parameter(Position=2)][string]$Identifier, + [string[]]$query, + [string]$Body, [string]$Method = "GET", # [Hashtable]$Headers = @{ "Content-Type" = "application/json" }, [Hashtable]$Headers = @{ }, - [switch]$FixUri + [switch]$FixUri, + [PsCredential]$Credential ) process { ############################## @@ -39,25 +43,37 @@ Function Invoke-Conjur { $CalledBy = (Get-PSCallStack)[1].command if(!$PsBoundParameters.containskey("Method")) { switch -regex ($CalledBy) { - "^Remove-" { $method = "DELETE" } - "^Update-" { $method = "PATCH" } - "^(add|Update)-" { $method = "POST" } - "^(Set|New|Submit|Write)-" { $method = "PUT" } + "^(Remove|Revoke)-" { $method = "DELETE" } + "^(Update)-" { $method = "PATCH" } + "^(Set|add|Grant)-" { $method = "POST" } + "^(New|Submit|Write)-" { $method = "PUT" } } } + ############################## + # Changing to the Write instance if required + ############################## $Authority = $CCConfig.AuthaurityName if ($Method -notlike "GET" -and $CCConfig.AuthaurityName_WR -and $API -notmatch 'authn') { Write-verbose "Switching to WRITE" $Authority = $CCConfig.AuthaurityName_WR } + ############################## + # Building the URI + ############################## $Commands = (@($Authority,$API) + $Command) | ? { $_ } - Write-verbose "#### $($commands -join '||')" + if ($PsBoundParameters.containskey("Identifier")) { + if ($CCConfig.IdentifierRootPath) { + $Identifier = $CCConfig.IdentifierRootPath + "/" + $Identifier + } + $Commands += $Identifier + } + $Commands = ( $Commands -join "/") -replace "//+","/" -replace '/$' $Commands = $Commands -replace "/!a","/$($CCConfig.Account)" - if ($PsBoundParameters.containskey("search")) { - $commands = ($Commands -replace '/?$' ) + "?" + ($Search -join ',') + if ($PsBoundParameters.containskey("query")) { + $commands = ($Commands -replace '/?$' ) + "?" + ($query -join '&') } $URL = "https://$Commands" @@ -68,10 +84,15 @@ Function Invoke-Conjur { URI = [uri]$URL } + if ($PsBoundParameters.containskey("Credential")) { + $RestMethod.add("Credential",$Credential) + } + ############################## # Fixing URI the URI contains \ that should not be interpreted as URI path but as data ############################## - if ($PsBoundParameters.containskey("FixUri")) { + if ($PsBoundParameters.containskey("FixUri") -and $PSVersionTable.PSVersion.Major -le 5) { + $UnEscapeDotsAndSlashes = 0x2000000; $SimpleUserSyntax = 0x20000; @@ -136,34 +157,103 @@ Function Invoke-Conjur { # Sending Rest API Request ############################## Write-verbose ($RestMethod | out-string -Width ($host.UI.RawUI.BufferSize.Width -2 )) - # Write-verbose ($RestMethod["Headers"] | out-string -Width ($host.UI.RawUI.BufferSize.Width -2 )) # Write-Verbose "Invoke-Conjur : URL : $URL" + $ClearError = $false try { $Result = Invoke-RestMethod @RestMethod } catch { - $exception = $_.Exception - $responseBody = Get-ResponseBodyFromException($exception) - Write-Verbose -Message "Response Body: `n $($responseBody | out-string)" - # Write-Verbose -Message "Response Body: `n $($responseBody | ConvertFrom-Json | ConvertTo-Json)" - throw $_ - break + Write-warning "Message : $($_.Exception.Response.StatusCode)" + if ($_.Exception.Response.StatusCode -notin @("NotFound")) { + Write-warning "Error : $($_.ErrorDetails.Message)" + throw $_ + break + } else { + $ClearError = $true + } } - + if ($ClearError) {$global:Error.Remove($global:Error[0])} return $Result } } Export-ModuleMember -Function Invoke-Conjur +<# +.SYNOPSIS + +This command is required prior to running any other one. This will configure the module with the required settings. + +.DESCRIPTION + +Please check all the parameters in the help file. +Mandatory parameters are : +Account : Organization account name +Credential : Will store the API key that will grant you access to Conjur +AuthaurityName : DNS authority name of your Conjur instance + + +.PARAMETER Account +[Mandatory] Will set the Organization account for the repository you are reaching to + +.PARAMETER Credential +[Mandatory] A Credential object that will be stored in memory containing your API key, that will be used to authenticate your access to Conjur. See the examples below + +.PARAMETER AuthnLogin (deprecated | use credential instead) +Will set the indentifier of the host API key (requires AuthnApiKey) + +.PARAMETER AuthnApiKey (deprecated | use credential instead) +Will set the API key of the indentifier (requires AuthnLogin) + +.PARAMETER AuthaurityName +[Mandatory] Will set the name of your conjur instance. Example, if your site is https://eval.conjur.org then you need to set AuthaurityName = eval.conjur.org + +.PARAMETER AuthaurityName_WR +In some configurations, you have read only instances of Conjur. By adding this parameter, you will consider the AuthaurityName as read only instances, while any modification will call AuthaurityName_WR as DNS name + + +.PARAMETER IdentifierRootPath +If all your Indentifiers have the same headers, you might want to use this switch to automatically indent any identifier with this variable. +Example without having set this parameter, you will need to say identifier = deaultpath/defaultfolder/oracle/myAccount. +If you set the IdentifierRootPath to deaultpath/defaultfolder, in all your functions, you will only need to specify oracle/myAccount + +.PARAMETER IamAuthnBranch +[AWS IAM integration] This parameter is for Iam authentication plugin, and has not been tested yet + +.PARAMETER AWS_MetaData +[AWS IAM integration] This parameter is for Iam authentication plugin, and has not been tested yet + +.PARAMETER IgnoreSsl +This will ignore any SSL issues for all the Conjur queries. + +.INPUTS + +[PsCredential]Credential. You can set the credentials using a credential object is input + +.OUTPUTS + +Null + +.EXAMPLE + +PS> $HostApiIdentifier = "host/some/application" +PS> $Cred = (Get-credential -Message "Please enter your Conjur API key" -UserName $ApiIdentifier) +PS> Initialize-Conjur -Credential $Cred -Account MyOrg -AuthaurityName eval.conjur.org + +.EXAMPLE +PS> $Cred | Initialize-Conjur -Account MyOrg -AuthaurityName readeval.conjur.org -AuthaurityName_WR writeeval.conjur.org + + +#> Function Initialize-Conjur { [CmdletBinding(DefaultParameterSetName="Credential")] Param( [string]$Account, [parameter(ParameterSetName='Login',mandatory)][string]$AuthnLogin, [parameter(ParameterSetName='Login',mandatory)][string]$AuthnApiKey, - [parameter(ParameterSetName='Credential')][PSCredential]$Credential, + [parameter(ParameterSetName='Credential',ValueFromPipeline)][PSCredential]$Credential, [string]$AuthaurityName, [string]$AuthaurityName_WR, + [string]$IdentifierRootPath, [string]$IamAuthnBranch, [string]$AWS_MetaData, [Switch]$IgnoreSsl @@ -218,6 +308,48 @@ Function Initialize-Conjur { } Export-ModuleMember -Function Initialize-Conjur +<# +.SYNOPSIS + +This command will return you the actual configuration as set in memory. Modifying this variable will modify the Conjur configuration + +.DESCRIPTION + +Returns the hastable used to configure the Conjur module + + +.INPUTS + +None. You cannot pipe objects to this function. + + +.OUTPUTS + +HashTable. The configuration variables for this module + +.EXAMPLE + +PS> $HostApiIdentifier = "host/some/application" +PS> $Cred = (Get-credential -Message "Please enter your Conjur API key" -UserName $ApiIdentifier) +PS> Initialize-Conjur -Credential $Cred -Account MyOrg -AuthaurityName eval.conjur.org + +.EXAMPLE +PS> Show-ConjurConfiguration + +Name Value +---- ----- +TokenTTL 360 +AWS_MetaData 169.254.169.254 +TokenExpireDate 10/1/2021 10:11:39 AM +Account MyOrg +Credential System.Management.Automation.PSCredential +Token @{protected=***** Hidden ****** +Certificate +AuthaurityName read.eval.conjur.org +AuthaurityName_WR write.eval.conjur.org +IamAuthnBranch +APIKey ***** Hidden ****** +#> Function Show-ConjurConfiguration { return $CCConfig } @@ -253,6 +385,7 @@ Function Get-ResponseBodyFromException { # Internal IAM Functions ############################### +#### THIS FUNCTION HAS NOT BEEN TESTED Function Invoke-ConjurIam { [CmdletBinding()] param( @@ -314,6 +447,7 @@ Function Enable-HelperNamespace{ }" } +#### THIS FUNCTION HAS NOT BEEN TESTED function Get-IamAuthorizationHeader { [CmdletBinding()] param ( @@ -357,6 +491,7 @@ function Get-IamAuthorizationHeader { return "$($algorithm) Credential=$($cAccessKeyId)/$($cred_scope), SignedHeaders=$($signed_headers), Signature=$($signature)" } +#### THIS FUNCTION HAS NOT BEEN TESTED Function Receive-ConjurIamLogin { [CmdletBinding()] param() @@ -388,12 +523,11 @@ Function Receive-ConjurIamLogin { return $conjurToken } set-alias Get-IamConjurApiKey Receive-ConjurIamLogin - - - + ############################### -# Exported Functions +# Login / Authenticate ############################### + <# .SYNOPSIS @@ -413,7 +547,7 @@ Will not return the APIKey, but will store it in memory. .INPUTS -None. You cannot pipe objects to Receive-ConjurLogin. +None. You cannot pipe objects to this function. .OUTPUTS @@ -468,7 +602,7 @@ For host authentication, the login is the host ID with the prefix host/. For exa .INPUTS -None. You cannot pipe objects to Receive-ConjurAuthenticate. +None. You cannot pipe objects to this function. .OUTPUTS @@ -514,11 +648,10 @@ Function Receive-ConjurAuthenticate { } Export-ModuleMember -Function Receive-ConjurAuthenticate - <# .SYNOPSIS -The Conjur IAM Authenticator allows an AWS resource to use its AWS IAM role to authenticate with Conjur +The Conjur IAM Authenticator allows an AWS resource to use its AWS IAM role to authenticate with Conjur #### THIS FUNCTION HAS NOT BEEN TESTED @@ -532,7 +665,7 @@ To enable an IAM Authenticator, for example, prod, set the following environment .INPUTS -None. You cannot pipe objects to Receive-ConjurIAMAuthenticate. +None. You cannot pipe objects to this function. .OUTPUTS @@ -559,284 +692,602 @@ Function Receive-ConjurIAMAuthenticate { } Export-ModuleMember -Function Receive-ConjurAuthenticate - <# .SYNOPSIS -WhoAmI provides information about the client making an API request +Changes a user’s password #### THIS FUNCTION HAS NOT BEEN TESTED .DESCRIPTION -It can be used to help troubleshoot configuration by verifying authentication and the client IP address for audit and network access restrictions. For more information, see Host Attributes. +Changes a user’s password. You must provide the login name and current password or API key of the user whose password is to be updated in an HTTP Basic Authentication header. Also replaces the user’s API key with a new securely generated random value. You can fetch the new API key by using Login. + +Your HTTP/REST client probably provides HTTP basic authentication support. For example, curl and all of the Conjur client libraries provide this. + +Note : machine roles (Hosts) do not have passwords. They authenticate using their API keys, while passwords are only used by human users. .INPUTS -None. You cannot pipe objects to Receive-ConjurLogin. +None. You cannot pipe objects to this function. .OUTPUTS -String. The API key. +NULL .EXAMPLE -PS> $APIKey = Receive-ConjurLogin - +Not Tested Yet .LINK -https://docs.conjur.org/Latest/en/Content/Developer/Conjur_API_Login.htm +https://docs.conjur.org/Latest/en/Content/Developer/Conjur_API_change_Password.htm #> -Function Get-ConjurWhoAmI { +Function New-ConjurUserPassword { # PUT [CmdletBinding()] - param( ) + param( + [string]$Credential, + [string]$NewPassword + ) process { - return Invoke-Conjur whoami + return Invoke-Conjur authn !A,"password" -Body $Password -Credential $Credential -Headers @{} } } -Export-ModuleMember -Function Get-ConjurWhoAmI +Export-ModuleMember -Function New-ConjurUserPassword + <# .SYNOPSIS -Get health of a conjur instance +#### THIS FUNCTION HAS NOT BEEN TESTED +Rotate Personal API Key + Or +Replaces the API key of another role that you can update with a new, securely random API key. The new API key is returned as the response body. + + .DESCRIPTION -Get health of a conjur instance +Replaces your own API key with a new, securely random API key. The new API key is returned as the response body. + +For User API key , Any role can rotate its own API key. The name and password or current API key of the role must be provided via HTTP Basic Authorization. Your HTTP/REST client probably provides HTTP + +.PARAMETER Credential +The Credential object that contains the personal API Key as username and the API Key as password + +.PARAMETER Identifier +The identifier of the Role + +.PARAMETER Kind +The Kind API key you want to rotate. +Possible values are : user,host,layer,group,policy,variable,webservice +Default = host .INPUTS -None. You cannot pipe objects to Get-ConjurHealth. +None. You cannot pipe objects to this function. .OUTPUTS -System.Collections.Hashtable. The health of the conjur instance. +The new personal API Key .EXAMPLE -PS> Get-ConjurHealth -services database ok --------- -------- -- -@{possum=ok; ui=ok; ok=True} @{ok=True; connect=; free_space=; re... True - +Not Tested Yet .LINK -https://www.conjur.org/api.html#health-get-health +https://docs.conjur.org/Latest/en/Content/Developer/Conjur_API_Rotate_Personal_API_Key.htm +https://docs.conjur.org/Latest/en/Content/Developer/Conjur_API_Rotate_Other_API_Key #> -Function Get-ConjurHealth { - [CmdletBinding()] - param( ) - return Invoke-Conjur health +Function New-ConjurApiKey { # PUT + [CmdletBinding(DefaultParameterSetName="User")] + param( + [Parameter(Position=0,mandatory,ParameterSetName='User')][string]$Credential, + [Parameter(Position=0,mandatory,ParameterSetName='Kind')][string]$Identifier, + [ValidateSet("user","host","layer","group","policy","variable","webservice")] + [Parameter(Position=1,ParameterSetName='host')][string]$Kind='host' + ) + process { + $Switches = @{} + if ($PsCmdlet.ParameterSetName -like "User") { + $Switches.add("Credential",$Credential) + $Switches.add("Headers",@{}) + } else { + $Switches.add("query",("role=$Kind" + ":" + $identifier)) + } + return Invoke-Conjur authn !a,api_key -Body "" @Switches + } } -Export-ModuleMember -Function Get-ConjurHealth +Export-ModuleMember -Function New-ConjurApiKey + + <# .SYNOPSIS - -Retrieve one or multiple secrets from conjur +OIDC Authenticator .DESCRIPTION +Once the OIDC Authenticator is configured, you can send an authentication request. -Retrieve one or multiple secret from conjur -If one Identifier is selected, the returned object will be the value of the secret -If Multiple Identifier, the returned object will a PsObject with all the secrets in a single query +For more information about the OIDC Authenticator, see OpenID Connect (OIDC) Authenticator. -.PARAMETER Identifier -The identifier used to retrieve the secret +.PARAMETER serviceid +The ID of the OIDC Provider, for example okta .INPUTS -None. You cannot pipe objects to Get-ConjurSecret. +None. You cannot pipe objects to this function. .OUTPUTS -System.String. The secret retrieved. +String. The Authentication Token. .EXAMPLE -PS> Get-ConjurSecret -Identifier "path/to/secret/username" -AHfdkrjeb81hs6ah - -PS> Get-ConjurSecret -Identifier "path/to/secret/S1", "path/to/secret/S2" -Account:variable:path/to/secret/S1 Account:variable:path/to/secret/S2 ----------------------------------- ---------------------------------- -TestS1 TestS2 +PS> $Token = Receive-ConjurOIDCAuthenticator +eyJwcm90ZWN0ZWQiOiJleUpoYkdjaU9pSmpiMjVxZFhJdWIzSm5MM05zYjNOcGJHOHZkaklpTENKcmFXUWlPaUkyTXpka05HWTFZMlU1WVdJd05ESTVOR0ZpWkRNNFptTmhPV00zWW1Nek5qWTVaak16TWprNU5UUXdZamhsTm1ZeU5tRTBNVGM1T0RFeE1HSm1aRGcwSW4wPSIsInBheWxvYWQiOiJleUp6ZFdJaU9pSmhaRzFwYmlJc0ltbGhkQ0k2TVRVNU9EYzJPVFUwTUgwPSIsInNpZ25hdHVyZSI6Ik5ya25FQTc2MnoweC1GVmRRakZHZVRUbkJzeXFBdlBHSWEyZUxZV3IyYVVGZDU5dHk0aGMxSlRsVGptdmpGNWNtVDNMUnFGbDhYYzNwMDhabEhjbVc0cTdiVnFtM21odmZEdVNVaE13RzhKUk4yRFZQVHZKbkFiT1NPX0JGdWhKdmk2OGJEVGxZSFFmUF81WHY1VWtuWHlLUDR2dGNoSjloMHJuVXN0T0F1YWlkM0RyQW5RV1c2dDRaMzRQajJhT2JrTkZ1TlMxNDBsamNwZ1A1dHdfU19ISzB6d1dlSXF4cjh6eUpTbk5aNjJ1WlhZV25zU051WGZtSWdtVVo2cTJFeVZWWUJ1Zk5SZTNVUmFkU09OYjRIcnFyX21UaGctWHUzMjA2N1h3QmNWZ3lWQ0JrcWtybktuRW1vRzlMRWs2ZjdNQVpDX1BXZnA4NXQ1VFFhVm1iZFlqT2lDTW9GMFoxYkhyZGN2MC1LRnpNRGxHa0pCS1Jxb0xYYkFGakhjMCJ9 .LINK +https://docs.conjur.org/Latest/en/Content/Developer/Conjur_API_OIDC_Authenticator.htm + -https://docs.conjur.org/Latest/en/Content/Developer/Conjur_API_Retrieve_Secret.htm -https://docs.conjur.org/Latest/en/Content/Developer/Conjur_API_Batch_Retrieve.htm #> -Function Get-ConjurSecret { - [CmdletBinding()] - param( - [Parameter(Position=0,mandatory=$true)][string[]]$Identifier, - $SecretKind = "variable" - ) +Function Receive-ConjurOIDCAuthenticator { + [CmdletBinding()] + param( + [Parameter(Position=0,mandatory)][string]$serviceid, + [Parameter(Position=1,mandatory)][string]$APIKey, + [switch]$force + ) + process { + if (!$CCConfig.Token -or $PsBoundParameters.containskey("force") -or ((get-date) -gt $CCConfig.TokenExpireDate)) { + $StartTime = Get-date + if ( !$APIKey ) { + write-warning "No API Key was generated, you need to run [Receive-ConjurLogin | out-null] first" + } + $Headers = @{ + "Content-Type" = "application/x-www-form-urlencoded" + "Accept-Encoding" = "base64" + } + $Body = "id_token: ""$APIKey""" + $CCConfig.Token = Invoke-Conjur authn-oidc !a,$ConjurUsername,authenticate -Body $Body -Headers $Headers + + + if (!$CCConfig.Token) { + write-Warning "The Conjur Module was not able to authenticate. Please run the [Initialize-ConjurConfiguration] command to configure the module. You can also run [get-help Initialize-ConjurConfiguration] for more information." + return + } else { + $CCConfig.TokenExpireDate = $StartTime.AddSeconds($CCConfig.TokenTTL) + } + } - if ($Identifier.count -gt 1) { - $ModifiedSI = "variable_ids=" - $ModifiedSI += ($Identifier | % { ($CCConfig.Account,$SecretKind,$_) -join ":" }) -join ',' - return Invoke-Conjur secrets -Search $ModifiedSI - } else { - return Invoke-Conjur secrets !a,$SecretKind,($Identifier | select -first 1) + return $CCConfig.Token } } -Export-ModuleMember -Function Get-ConjurSecret +Export-ModuleMember -Function Receive-ConjurOIDCAuthenticator + + +############################### +# Various Types of API +############################### <# .SYNOPSIS -Get-ConjurSecretCredential is an helper function that will directly retrieve a credential object from Conjur +WhoAmI provides information about the client making an API request .DESCRIPTION -If you add to a single path 2 secrets, one called username and the other called password, you will directly retrieve the PsCredential object from it -for example, if you have those 2 keys : -myhome\subpath\username -myhome\subpath\password -You will be able to directly retrieve the PsCredential Object using the command [Get-ConjurSecretCredential variable\myhome\subpath] - +It can be used to help troubleshoot configuration by verifying authentication and the client IP address for audit and network access restrictions. For more information, see Host Attributes. -.PARAMETER IdentifierPath -The path to a pair of username/password couple .INPUTS -None. You cannot pipe objects to Get-ConjurSecret. + +None. You cannot pipe objects to this function. .OUTPUTS -PsCredential. The PsCredential object. + +String. The API key. .EXAMPLE -PS> Get-ConjurSecretCredential "path/to/secret" +PS> $APIKey = Receive-ConjurLogin -UserName Password --------- -------- -TheUserName System.Security.SecureString + +.LINK + +https://docs.conjur.org/Latest/en/Content/Developer/Conjur_API_Login.htm #> -Function Get-ConjurSecretCredential { - [CmdletBinding()] - param( - [Parameter(Position=0,mandatory=$true)][string[]]$IdentifierPath - ) - $ToRetrieve = $IdentifierPath | % { @(($_ + "/username"),($_ + "/password")) } - $ToRetrieve = $ToRetrieve -replace "//+","/" - $AllSecrets = Get-ConjurSecret $ToRetrieve - $AllSP = $AllSecrets.psobject.Members | ? { $_.membertype -like "noteproperty" } | select -ExpandProperty name - $AllSP = $allSP -replace '/(password|username)$' | select -unique - $Results = $AllSp | % { - [securestring]$SS = ConvertTo-SecureString $AllSecrets."$_/password" -AsPlainText -Force - New-Object System.Management.Automation.PSCredential ($AllSecrets."$_/username", $SS ) +Function Get-ConjurWhoAmI { + [CmdletBinding()] + param( ) + process { + return Invoke-Conjur whoami } - return $results } -Export-ModuleMember -Function Get-ConjurSecretCredential +Export-ModuleMember -Function Get-ConjurWhoAmI <# .SYNOPSIS - -Set a secret in conjur +#### THIS FUNCTION HAS NOT BEEN TESTED +Get the Authenticator Status .DESCRIPTION -Set a secret in conjur -Takes a secret identifier and secret value - -.PARAMETER Identifier -The identifier used to set the secret - -.PARAMETER SecretValue -The value of the secret +Once the status webservice has been properly configured and the relevant user groups have been given permissions to access the status webservice, the users in those groups can check the status of the authenticator. .INPUTS -None. You cannot pipe objects to Update-ConjurSecret. +None. You cannot pipe objects to this function. .OUTPUTS -None. +PsObject. The status of the Authenticator .EXAMPLE -PS> Update-ConjurSecret -Identifier "path/to/secret" -SecretValue "newPasswordHere" +PS> Get-ConjurAuthenticatorStatus authn-oidc okta +status +------ +ok .LINK -https://www.conjur.org/api.html#secrets-add-a-secret-post - +https://docs.conjur.org/Latest/en/Content/Developer/Conjur_API_authenticator_status.htm #> -Function Update-ConjurSecret { - [CmdletBinding()] - param( - [Parameter(Position=0,mandatory)][string]$Identifier, - [Parameter(Position=1,mandatory)][string]$SecretValue, - [Parameter(Position=2)][string]$SecretKind = "variable" - ) - return Invoke-Conjur secrets !A,$SecretKind,$Identifier -Body $SecretValue +Function Get-ConjurAuthenticatorStatus { + [CmdletBinding()] + param( + [string]$AuthenticatorType, + [string]$AerviceId + ) + process { + return Invoke-Conjur $AuthenticatorType $AerviceId,!A,status + } } -New-Alias Set-ConjurSecret Update-ConjurSecret -Export-ModuleMember -Function Update-ConjurSecret -Alias Set-ConjurSecret +Export-ModuleMember -Function Get-ConjurAuthenticatorStatus <# .SYNOPSIS -Modifies an existing Conjur policy +Get health of a conjur instance .DESCRIPTION -Data may be explicitly deleted using the !delete, !revoke, and !deny statements. Unlike “replace” mode, no data is ever implicitly deleted. - -.PARAMETER Identifier -The identifier used to update the policy - -.PARAMETER PolicyFilePath -The path to the policy that will be loaded +Get health of a conjur instance .INPUTS -None. You cannot pipe objects to Update-ConjurPolicy. +None. You cannot pipe objects to this function. .OUTPUTS -None. +System.Collections.Hashtable. The health of the conjur instance. .EXAMPLE -PS> Update-ConjurPolicy -Identifier "root" -PolicyFilePath ".\test-policy.yml" - -created_roles version -------------- ------- -@{dev:host:database/another-host=} 4 +PS> Get-ConjurHealth +services database ok +-------- -------- -- +@{possum=ok; ui=ok; ok=True} @{ok=True; connect=; free_space=; re... True .LINK -https://docs.conjur.org/Latest/en/Content/Developer/Conjur_API_Update_Policy.htm +https://www.conjur.org/api.html#health-get-health #> -Function Update-ConjurPolicy { +Function Get-ConjurHealth { [CmdletBinding()] - param( - [Parameter(Position=0,mandatory=$true)][string]$Identifier, - [Parameter(Position=1,mandatory=$true)][string]$PolicyFilePath + param( ) + return Invoke-Conjur health +} +Export-ModuleMember -Function Get-ConjurHealth + + +<# +.SYNOPSIS +Show Public Keys + +.DESCRIPTION +Shows all public keys for a resource as newline delimited string for compatibility with the authorized_keys SSH format. + +Returns an empty string if the resource does not exist, to prevent attackers from determining whether a resource exists. + +.PARAMETER Kind +kind of resource of which to show public keys. Possible values are : user,host,layer,group,policy,variable,webservice + +.PARAMETER identifier +The identifier of the object + +.INPUTS +None. You cannot pipe objects to this function. + +.OUTPUTS + +System.Collections.Hashtable. The health of the conjur instance. + +.EXAMPLE + +PS> Get-ConjurHealth +ssh-rsa AAAAB3Nzabc2 admin@alice.com +ssh-rsa AAAAB3Nza3nx alice@example.com + +.LINK +https://docs.conjur.org/Latest/en/Content/Developer/Conjur_API_Show_Public_Keys.htm + + +#> +Function Get-ConjurPublicKeys { + [CmdletBinding()] + param( + [ValidateSet("user","host","layer","group","policy","variable","webservice")] + [Parameter(Position=0,mandatory)][string]$Kind, + [Parameter(Position=1,mandatory)][string]$identifier + ) + return Invoke-Conjur public_keys !a,$Kind,$identifier +} +Export-ModuleMember -Function Get-ConjurPublicKeys + + + +############################### +# Secrets API +############################### +<# +.SYNOPSIS + +Retrieve one or multiple secrets from conjur + +.DESCRIPTION + +Retrieve one or multiple secret from conjur +If one Identifier is selected, the returned object will be the value of the secret +If Multiple Identifier, the returned object will a PsObject with all the secrets in a single query + +.PARAMETER Identifier +The identifier used to retrieve the secret + +.PARAMETER Kind +The Kind of secret you want to retrieve. +Possible values are : user,host,layer,group,policy,variable,webservice +Default = variable + +.PARAMETER variable_ids +List the secrets you want to retrieve in the Comma-delimited resource IDs format + + +.INPUTS + +None. You cannot pipe objects to this function. + +.OUTPUTS + +System.String. The secret retrieved. + +.EXAMPLE + +PS> Get-ConjurSecret -Identifier "path/to/secret/username" +AHfdkrjeb81hs6ah + +.EXAMPLE + +PS> Get-ConjurSecret -Identifier "path/to/secret/S1", "path/to/secret/S2" +Account:variable:path/to/secret/S1 Account:variable:path/to/secret/S2 +---------------------------------- ---------------------------------- +TestS1 TestS2 + +.EXAMPLE + +PS> Get-ConjurSecret -variable_ids "Account:variable:path/to/secret/S1", "Account:variable:path/to/secret/S2" +Account:variable:path/to/secret/S1 Account:variable:path/to/secret/S2 +---------------------------------- ---------------------------------- +TestS1 TestS2 + + + +.LINK + +https://docs.conjur.org/Latest/en/Content/Developer/Conjur_API_Retrieve_Secret.htm +https://docs.conjur.org/Latest/en/Content/Developer/Conjur_API_Batch_Retrieve.htm +#> +Function Get-ConjurSecret { + [CmdletBinding(DefaultParameterSetName="Identifier")] + param( + [Parameter(Position=0,ParameterSetName='Identifier',mandatory=$true)][string[]]$Identifier, + [ValidateSet("user","host","layer","group","policy","variable","webservice")] + [Parameter(Position=1,ParameterSetName='Identifier')]$Kind = "variable", + [string[]]$variable_ids + ) + process { + if ($PsCmdlet.ParameterSetName -like "Identifier" -and $Identifier.count -eq 1 ) { + $Result = Invoke-Conjur secrets !a,$Kind -Identifier ($Identifier | select -first 1) + } else { + $ModifiedSI = "variable_ids=" + if ($PsCmdlet.ParameterSetName -like "Identifier") { + $ModifiedSI += ($Identifier | % { ($CCConfig.Account,$Kind,$_) -join ":" }) -join ',' + } else { + $ModifiedSI += $variable_ids -join ',' + } + $Result = Invoke-Conjur secrets -query $ModifiedSI + } + return $Result + } +} +Export-ModuleMember -Function Get-ConjurSecret + +<# +.SYNOPSIS + +Get-ConjurSecretCredential is an helper function that will call Get-ConjurSecret and directly retrieve a PsCredential object based on the policy name. + +.DESCRIPTION + +If you add to a policy 2 secrets, one called username and the other called password, you will be able to use this function. +for example, if you have those 2 variables : +myhome\subpath\username +myhome\subpath\password +You will be able to directly retrieve the PsCredential Object using the command [Get-ConjurSecretCredential variable\myhome\subpath] + + +.PARAMETER IdentifierPath +The path to a pair of username/password couple + +.INPUTS +None. You cannot pipe objects to this function. + +.OUTPUTS +PsCredential. The PsCredential object. + +.EXAMPLE + +PS> Get-ConjurSecretCredential "policy/to/secret" + +UserName Password +-------- -------- +TheUserName System.Security.SecureString + + +#> +Function Get-ConjurSecretCredential { + [CmdletBinding()] + param( + [Parameter(Position=0,mandatory=$true)][string[]]$IdentifierPath ) - - $policyContent = Get-Content -Path $PolicyFilePath -Raw + $ToRetrieve = $IdentifierPath | % { @(($_ + "/username"),($_ + "/password")) } + $ToRetrieve = $ToRetrieve -replace "//+","/" + Write-Verbose "Get-ConjurSecretCredential : Calling [Get-ConjurSecret $ToRetrieve]" + $AllSecrets = Get-ConjurSecret $ToRetrieve + $AllSP = $AllSecrets.psobject.Members | ? { $_.membertype -like "noteproperty" } | select -ExpandProperty name + $AllSP = $allSP -replace '/(password|username)$' | select -unique + $Results = $AllSp | % { + [securestring]$SS = ConvertTo-SecureString $AllSecrets."$_/password" -AsPlainText -Force + New-Object System.Management.Automation.PSCredential ($AllSecrets."$_/username", $SS ) + } + return $results +} +Export-ModuleMember -Function Get-ConjurSecretCredential + +<# +.SYNOPSIS + +Set a secret in conjur + +.DESCRIPTION + +Set a secret in conjur +Takes a secret identifier and secret value + +.PARAMETER Identifier +The identifier used to set the secret + +.PARAMETER SecretValue +The value of the secret + +.PARAMETER Kind +The Kind of secret you want to retrieve. +Possible values are : user,host,layer,group,policy,variable,webservice +Default = variable + +.INPUTS + +None. You cannot pipe objects to this function. + +.OUTPUTS + +None. + +.EXAMPLE + +PS> Update-ConjurSecret -Identifier "path/to/secret" -SecretValue "newPasswordHere" + + +.LINK + +https://www.conjur.org/api.html#secrets-add-a-secret-post + + +#> +Function Set-ConjurSecret { # POST | Set a Secret + [CmdletBinding()] + param( + [Parameter(Position=0,mandatory)][string]$Identifier, + [Parameter(Position=1,mandatory)][string]$SecretValue, + [ValidateSet("user","host","layer","group","policy","variable","webservice")] + [Parameter(Position=2)][string]$Kind = "variable" + ) + return Invoke-Conjur secrets !A,$Kind -identifier $Identifier -Body $SecretValue +} +New-Alias Set-ConjurSecret Update-ConjurSecret +Export-ModuleMember -Function Update-ConjurSecret -Alias Set-ConjurSecret + +############################### +# Policies API +############################### +<# +.SYNOPSIS + +Modifies an existing Conjur policy + +.DESCRIPTION + +Data may be explicitly deleted using the !delete, !revoke, and !deny statements. Unlike “replace” mode, no data is ever implicitly deleted. + +.PARAMETER Identifier +The identifier used to update the policy + +.PARAMETER Policy +The YAML policy - return Invoke-Conjur policies !A,policy,$Identifier -Body $policyContent +.INPUTS + +[string]Policy : The Yaml configuration of a Policy + +.OUTPUTS + +None. + +.EXAMPLE + +PS> Get-content .\test-policy.yml | Update-ConjurPolicy -Identifier root + +created_roles version +------------- ------- +@{cucumber:host:database/another-host=} 3 + +.EXAMPLE + +PS> Update-ConjurPolicy -Identifier root ".\test-policy.yml" + +created_roles version +------------- ------- +@{cucumber:host:database/another-host=} 3 + +.LINK + +https://docs.conjur.org/Latest/en/Content/Developer/Conjur_API_Update_Policy.htm + + +#> +Function Update-ConjurPolicy { # PATCH | Update a Policy + [CmdletBinding(DefaultParameterSetName="File")] + param( + [Parameter(Position=0,mandatory=$true)][string]$Identifier, + [Parameter(Position=1,mandatory=$true,ParameterSetName='File')][string]$PolicyFilePath, + [Parameter(Position=1,mandatory=$true,ValueFromPipeline,ParameterSetName='Policy')][string]$Policy + ) + if ($PsCmdlet.ParameterSetName -like "File" ) { $Policy = get-content $PolicyFilePath } + return Invoke-Conjur policies !A,policy -Identifier $Identifier -Body $Policy } Export-ModuleMember -Function Update-ConjurPolicy @@ -852,12 +1303,17 @@ Any policy data which already exists on the server but is not explicitly specifi .PARAMETER Identifier The identifier used to update the policy + .PARAMETER PolicyFilePath The path to the policy that will be loaded +.PARAMETER Policy +The YAML policy that will be loaded + + .INPUTS -None. You cannot pipe objects to Set-ConjurPolicy. +None. You cannot pipe objects to this function. .OUTPUTS @@ -865,12 +1321,19 @@ None. .EXAMPLE -PS> Set-ConjurPolicy -Identifier "root" -PolicyFilePath ".\test-policy.yml" +PS> Get-content .\test-policy.yml | Set-ConjurPolicy -Identifier root -created_roles version -------------- ------- -@{dev:host:database/another-host=} 4 +created_roles version +------------- ------- +@{myorg:host:database/db-host=} 1 + +.EXAMPLE + +PS> Set-ConjurPolicy -Identifier "root" -PolicyFilePath ".\test-policy.yml" +created_roles version +------------- ------- +@{myorg:host:database/db-host=} 1 .LINK @@ -878,17 +1341,18 @@ https://www.conjur.org/api.html#policies-replace-a-policy #> -Function Set-ConjurPolicy { +Function Write-ConjurPolicy { # PUT | Replace a Policy [CmdletBinding()] param( [Parameter(Position=0,mandatory=$true)][string]$Identifier, - [Parameter(Position=1,mandatory=$true)][string]$PolicyFilePath + [Parameter(Position=1,mandatory=$true,ParameterSetName='File')][string]$PolicyFilePath, + [Parameter(Position=1,mandatory=$true,ValueFromPipeline,ParameterSetName='Policy')][string]$Policy ) - $policyContent = Get-Content -Path $PolicyFilePath -Raw - return Invoke-Conjur policies !A,policy,$Identifier -Body $policyContent + if ($PsCmdlet.ParameterSetName -like "File" ) { $Policy = get-content $PolicyFilePath } + return Invoke-Conjur policies !A,policy -Identifier $Identifier -Body $Policy } -New-Alias Replace-ConjurPolicy Set-ConjurPolicy -Export-ModuleMember -Function Set-ConjurPolicy -Alias Replace-ConjurPolicy +New-Alias Replace-ConjurPolicy Write-ConjurPolicy +Export-ModuleMember -Function Write-ConjurPolicy -Alias Replace-ConjurPolicy <# .SYNOPSIS @@ -902,12 +1366,16 @@ Deletions are not allowed. Any policy objects that exist on the server but are o .PARAMETER Identifier The identifier used to update the policy + .PARAMETER PolicyFilePath The path to the policy that will be loaded +.PARAMETER Policy +The YAML policy that will be loaded + .INPUTS -None. You cannot pipe objects to Add-ConjurPolicy. +None. You cannot pipe objects to this function. .OUTPUTS @@ -915,11 +1383,19 @@ None. .EXAMPLE +PS> Get-content test-policy.yml | Add-ConjurPolicy root + +created_roles version +------------- ------- +@{cucumber:host:database/new-host=} 2 + +.EXAMPLE + PS> Add-ConjurPolicy -Identifier "root" -PolicyFilePath ".\test-policy.yml" -created_roles version -------------- ------- -@{dev:host:database/another-host=} 4 +created_roles version +------------- ------- +@{cucumber:host:database/new-host=} 3 .LINK @@ -928,19 +1404,22 @@ https://docs.conjur.org/Latest/en/Content/Developer/Conjur_API_Append_Policy.htm #> -Function Add-ConjurPolicy { +Function Add-ConjurPolicy { # POST | Load a Policy (add) [CmdletBinding()] param( [Parameter(Position=0,mandatory=$true)][string]$Identifier, - [Parameter(Position=1,mandatory=$true)][string]$PolicyFilePath + [Parameter(Position=1,mandatory=$true,ParameterSetName='File')][string]$PolicyFilePath, + [Parameter(Position=1,mandatory=$true,ValueFromPipeline,ParameterSetName='Policy')][string]$Policy ) - - $policyContent = Get-Content -Path $PolicyFilePath -Raw - return Invoke-Conjur policies !A,policy,$Identifier -Body $policyContent + if ($PsCmdlet.ParameterSetName -like "File" ) { $Policy = get-content $PolicyFilePath } + return Invoke-Conjur policies !A,policy,$Identifier -Body $Policy } New-Alias Append-ConjurPolicy Add-ConjurPolicy Export-ModuleMember -Function Add-ConjurPolicy -Alias Append-ConjurPolicy +############################### +# Resources API +############################### <# .SYNOPSIS @@ -948,7 +1427,15 @@ List resource within an organization account .DESCRIPTION -List resource within an organization account +If a kind query parameter is given, narrows results to only resources of that kind. + +If a limit is given, returns no more than that number of results. Providing an offset skips a number of resources before returning the rest. In addition, providing an offset will give limit a default value of 10 if none other is provided. These two parameters can be combined to page through results. + +If the parameter count is true, returns only the number of items in the list. + +If the role or acting_as query parameter is given, then the resource list can be retrieved for a different role (as long as the authenticated role has access). + + .PARAMETER Kind Filters on the Kinds of resources. Valid Kinds are : user,host,layer,group,policy,variable,webservice @@ -957,7 +1444,7 @@ Filters on the Kinds of resources. Valid Kinds are : user,host,layer,group,polic The identifier (path) of the object .INPUTS -None. You cannot pipe objects to Get-ConjurResources. +None. You cannot pipe objects to this function. .OUTPUTS @@ -977,12 +1464,23 @@ policy_versions : {@{version=1; created_at=2019-05-29T16:42:56.284+00:00; policy .EXAMPLE -PS> Get-ConjurResources -Kind policy | select id -id --- -dev:policy:root/mypolicy -dev:policy:root/mypolicy/myother -dev:policy:root/mypolicylast +PS> Get-ConjurResources +created_at : 2017-07-25T06:30:38.768+00:00 +id : myorg:variable:app-prod/db-password +owner : myorg:policy:app-prod +policy : myorg:policy:root +permissions : {} +annotations : {} +secrets : {@{version=1}} + +created_at : 2017-07-25T06:30:38.768+00:00 +id : myorg:policy:app-prod +owner : myorg:user:admin +policy : myorg:policy:root +permissions : {} +annotations : {} +policy_versions : {} + .LINK @@ -994,19 +1492,201 @@ Function Get-ConjurResources { [CmdletBinding(DefaultParameterSetName="None")] Param( [Parameter(ParameterSetName='filter',mandatory)] - [ValidateSet("user","host","layer","group","policy","variable","webservice")][string]$Kind, - $identifier + [ValidateSet("user","host","layer","group","policy","variable","webservice")][string]$kind, + [string]$search, + [int]$limit, + [int]$offset, + [int]$count, + [string]$acting_as ) process { - $Command = @("!A") - if ( $psboundparameters.containskey("kind")) { $Command += $Kind } - if ( $psboundparameters.containskey("identifier")) { $Command += $identifier } - return Invoke-Conjur resources $Command + $Command = @() + $psboundparameters.keys | ? { $_ -notin $CCConfig.CommonParameters } | % { + $Command += "$_=$($psboundparameters.item($_))" + } + return Invoke-Conjur resources !A -query $Command } } Export-ModuleMember -Function Get-ConjurResources +<# +.SYNOPSIS + +Show a Resource + +.DESCRIPTION + +Show a Resource + +.PARAMETER Kind +Filters on the Kinds of resources. Valid Kinds are : user,host,layer,group,policy,variable,webservice + +.PARAMETER identifier +The identifier (path) of the object + +.INPUTS +None. You cannot pipe objects to this function. + +.OUTPUTS + +PsObject of the resource + +.EXAMPLE + +PS> Get-ConjurResources + +created_at : 2019-05-29T16:42:56.284+00:00 +id : dev:policy:root +owner : dev:user:admin +permissions : {} +annotations : {} +policy_versions : {@{version=1; created_at=2019-05-29T16:42:56.284+00:00; policy_text=--- 4 + + +.EXAMPLE + +PS> Get-ConjurResource + +created_at : 7/25/2017 8:30:38 AM +id : myorg:variable:db/password +owner : myorg:user:admin +policy : myorg:policy:root +permissions : {} +annotations : {} +policy_versions : {} + +.LINK + +https://docs.conjur.org/Latest/en/Content/Developer/Conjur_API_Show_Resources.htm + + +#> +Function Get-ConjurResource { + [CmdletBinding(DefaultParameterSetName="None")] + Param( + [Parameter(position=0,mandatory)][string]$identifier, + [ValidateSet("user","host","layer","group","policy","variable","webservice")] + [Parameter(position=1)][string]$kind="variable" + ) + process { + return Invoke-Conjur resources !A,$kind,$identifier + } +} +Export-ModuleMember -Function Get-ConjurResource + +<# +.SYNOPSIS +Show Permitted Roles + +.DESCRIPTION +Lists the roles which have the named permission on a resource + +.PARAMETER Kind +kind of resource requested. Valid Kinds are : user,host,layer,group,policy,variable,webservice + +.PARAMETER identifier +The identifier of the resource + +.PARAMETER privilege +roles permitted to exercise this privilege are shown +Example: execute + + +.INPUTS +None. You cannot pipe objects to this function. + +.OUTPUTS + +PsObject + + +.EXAMPLE + +PS> Get-ConjurPermittedRoles variable db execute + +myorg:policy:database +myorg:user:db-admin +myorg:host:database/db-host + +.LINK + +https://docs.conjur.org/Latest/en/Content/Developer/Conjur_API_Show_Permitted_Roles.htm + + +#> +Function Get-ConjurPermittedRoles { + [CmdletBinding(DefaultParameterSetName="None")] + Param( + [ValidateSet("user","host","layer","group","policy","variable","webservice")] + [Parameter(position=0,mandatory)][string]$kind, + [Parameter(position=1,mandatory)][string]$identifier, + [Parameter(position=2,mandatory)][string]$privilege + ) + process { + return Invoke-Conjur resources !A,$kind,$identifier -query "permitted_roles=true",$privilege + } +} +Export-ModuleMember -Function Get-ConjurPermittedRoles +<# +.SYNOPSIS +Check Permission + +.DESCRIPTION +Checks whether a role has a privilege on a resource. For example, is this Host authorized to execute (fetch the value of) this Secret? + +.PARAMETER Kind +kind of resource requested. Valid Kinds are : user,host,layer,group,policy,variable,webservice + +.PARAMETER identifier +The identifier of the resource (Example : db ) + +.PARAMETER privilege +the fully qualified identifier of the role to test (Example: myorg:host:application) + +.PARAMETER privilege +roles permitted to exercise this privilege are shown (Example: execute) + + +.INPUTS +None. You cannot pipe objects to this function. + +.OUTPUTS + +PsObject + + +.EXAMPLE + +PS> Test-ConjurPermission variable db "myorg:host:application" execute + + +.LINK + +https://docs.conjur.org/Latest/en/Content/Developer/Conjur_API_Check_Permission.htm + + +#> +Function Test-ConjurPermission { + [CmdletBinding(DefaultParameterSetName="None")] + Param( + [ValidateSet("user","host","layer","group","policy","variable","webservice")] + [Parameter(position=0,mandatory)][string]$kind, + [Parameter(position=1,mandatory)][string]$identifier, + [Parameter(position=2,mandatory)][string]$role, + [Parameter(position=3,mandatory)][string]$privilege + ) + process { + $Query = @("check=true","role=$role","privilege=$privilege") + return Invoke-Conjur resources !A,$kind,$identifier -query $Query + } +} +Export-ModuleMember -Function Test-ConjurPermission + + +############################### +# Roles API +############################### <# .SYNOPSIS Gets detailed information about a specific role, including the role members. @@ -1015,7 +1695,7 @@ Gets detailed information about a specific role, including the role members. If a role A is granted to a role B, then role A is said to have role B as a member. These relationships are described in the “members” portion of the returned JSON .INPUTS -None. You cannot pipe objects to Get-ConjurRole. +None. You cannot pipe objects to this function. .OUTPUTS PsObject. All the resources the user has access to @@ -1042,3 +1722,249 @@ Function Get-ConjurRole { } Export-ModuleMember -Function Get-ConjurRole + +<# +.SYNOPSIS +List a Role's Members + +.DESCRIPTION +List members within a role. + +If a kind query parameter is used, the results are narrowed to only resources of that kind. + +If a limit is provided, the results return up to the number specified. Providing an offset skips a number of resources before returning the rest. In addition, providing an offset gives limit a default value of 10 if no other limit is provided. These two parameters can be combined to page through results. + +If the parameter count is true, the number of items in the list are returned. + +Text search + +If the search parameter is provided, the results are narrowed to those pertaining to the search query. Search works across resource IDs and the values of annotations. It weighs results so that those with matching id or a matching value of an annotation called name appear first, then those with another matching annotation value, and finally those with a matching kind. + + + +.INPUTS +None. You cannot pipe objects to this function. + +.OUTPUTS +PsObject + +.EXAMPLE +PS> Get-ConjurRoleMember devs + +admin_option : True +ownership : True +role : myorg:group:devs +member : myorg:user:admin +policy : myorg:policy:root + +admin_option : False +ownership : False +role : myorg:group:devs +member : myorg:user:alice +policy : myorg:policy:root + +admin_option : False +ownership : False +role : myorg:group:devs +member : myorg:user:bob +policy : myorg:policy:root + +.LINK + +https://docs.conjur.org/Latest/en/Content/Developer/Conjur_API_Show_Role.htm +#> +Function Get-ConjurRoleMember { + [CmdletBinding()] + param( + [Parameter(Position=1)][string]$search, + [Parameter(Position=2)][ValidateSet("user","host","layer","group","policy")][string]$kind, + [int]$limit, + [int]$offset + ) + return Invoke-Conjur roles !A,$kind,$identifier, -query members +} +Export-ModuleMember -Function Get-ConjurRoleMember + + +<# +.SYNOPSIS +List a Role's Memberships + +.DESCRIPTION +Allows you to view the memberships of a role, including a list of groups of which a specific host or user is a member. + +If a kind query parameter is used, the results are narrowed to only resources of that kind. + +If a limit is provided, the results return up to the number specified. Providing an offset skips a number of resources before returning the rest. In addition, providing an offset gives limit a default value of 10 if no other limit is provided. These two parameters can be combined to page through results. + +If the parameter count is true, the number of items in the list are returned. + +.INPUTS +None. You cannot pipe objects to this function. + +.OUTPUTS +PsObject + +.EXAMPLE +PS> Get-ConjurRoleMemberships devs + +admin_option : False +ownership : False +role : myorg:group:devs +member : myorg:user:alice +policy : myorg:policy:root + +.LINK + +https://docs.conjur.org/Latest/en/Content/Developer/Conjur_API_Show_Role.htm +#> +Function Get-ConjurRoleMemberships { + [CmdletBinding()] + param( + [Parameter(Position=1,mandatory)][string]$identifier, + [Parameter(Position=2,mandatory)][ValidateSet("user","host","layer","group","policy")][string]$kind, + [int]$limit, + [int]$offset + ) + return Invoke-Conjur roles !A,$kind,$identifier -query memberships +} +Export-ModuleMember -Function Get-ConjurRoleMemberships + +############################### +# Host Factories API +############################### + +<# +.SYNOPSIS +Creates one or more tokens which can be used to bootstrap host identity + +.DESCRIPTION +Creates one or more tokens which can be used to bootstrap host identity. Responds with a JSON document containing the tokens and their restrictions. + +If the tokens are created with a CIDR restriction, Conjur will only accept them from the allowlisted IP ranges. + +.INPUTS +None. You cannot pipe objects to this function. + +.OUTPUTS +PsObject + +.EXAMPLE +PS> Grant-ConjurNewToken devs + +expiration cidr token +---------- ---- ----- +8/5/2017 12:27:20 AM {127.0.0.1/32, 127.0.0.2/32} 281s2ag1g8s7gd2ezf6td3d619b52t9gaak3w8rj0p38124n384sq7x +8/5/2017 12:27:20 AM {127.0.0.1/32, 127.0.0.2/32} 2c0vfj61pmah3efbgpcz2x9vzcy1ycskfkyqy0kgk1fv014880f4 + + +.LINK + +https://docs.conjur.org/Latest/en/Content/Developer/Conjur_API_Create_Tokens.htm +#> +Function Grant-ConjurNewToken { + [CmdletBinding()] + param( + [Parameter(Position=1,mandatory)][datetime]$expiration, + [Parameter(Position=2,mandatory)][string]$host_factory, + [Parameter(Position=3)][int]$count, + [Parameter(Position=3)][string[]]$cidr + ) + process { + $Query = @("expiration=$expiration","host_factory=$host_factory") + switch ($psboundparameters.keys) { + count { $Query += "count=$count"} + cidr { $cidr | % { $Query += "cidr[]=$_"} } + } + $Query = $Query | % { [System.Web.HttpUtility]::UrlEncode($_) } + return Invoke-Conjur host_factory_tokens -query $Query + } +} +Export-ModuleMember -Function Grant-ConjurNewToken + +<# +.SYNOPSIS +Revoke Tokens + +.DESCRIPTION +Revokes a token, immediately disabling it. + +If the tokens are created with a CIDR restriction, Conjur will only accept them from the allowlisted IP ranges. + +.INPUTS +None. You cannot pipe objects to this function. + +.OUTPUTS +None + +.EXAMPLE +PS> Revoke-ConjurNewToken 281s2ag1g8s7gd2ezf6td3d619b52t9gaak3w8rj0p38124n384sq7x + + +.LINK + +https://docs.conjur.org/Latest/en/Content/Developer/Conjur_API_Create_Tokens.htm +#> +Function Revoke-ConjurToken { + [CmdletBinding()] + param( + [Parameter(Position=0,mandatory)][string]$token + ) + process { + return Invoke-Conjur host_factory_tokens $token + } +} +Export-ModuleMember -Function Revoke-ConjurToken + + +<# +.SYNOPSIS +Create a Host + +.DESCRIPTION +Creates a Host using the Host Factory and returns a JSON description of it. + +Requires a Host Factory Token, which can be created using the Create Tokens API. In practice, this token is usually provided automatically as part of Conjur integration with your host provisioning infrastructure. + +.PARAMETER id +Identifier of the Host to be created. It will be created within the account of the Host Factory. (Example: brand-new-host) + +.PARAMETER annotations +Json Annotations to apply to the new Host (Example: {"puppet": "true", "description": "new db host"}) + +.INPUTS +None. You cannot pipe objects to this function. + +.OUTPUTS +None + +.EXAMPLE +PS> Add-ConjurHost -id brand-new-host + +created_at : 8/8/2017 12:30:00 AM +id : myorg:host:brand-new-host +owner : myorg:host_factory:hf-db +permissions : {} +annotations : {} +api_key : rq5bk73nwjnm52zdj87993ezmvx3m75k3whwxszekvmnwdqek0r + +.LINK + +https://docs.conjur.org/Latest/en/Content/Developer/Conjur_API_Create_Host.htm +#> +Function Add-ConjurHost { + [CmdletBinding()] + param( + [Parameter(Position=0,mandatory)][string]$id, + [Parameter(Position=1)][string]$annotations + ) + process { + $Query = @("id=$id") + switch ($psboundparameters.keys) { + annotations { $Query += "annotations=$annotations"} + } + $Query = $Query | % { [System.Web.HttpUtility]::UrlEncode($_) } + return Invoke-Conjur host_factory_tokens hosts -body $Body + } +} +Export-ModuleMember -Function Add-ConjurHost \ No newline at end of file From 7475c7c755f07113ba6ae4d3980da6d7040e02b3 Mon Sep 17 00:00:00 2001 From: "Thomas Farray (tfarray)" Date: Mon, 4 Oct 2021 13:14:27 +0200 Subject: [PATCH 08/12] fixed many things, mostly help commands --- CyberarkConjur.psm1 | 212 +++++++++++++++++++++++++++++++------------- 1 file changed, 148 insertions(+), 64 deletions(-) diff --git a/CyberarkConjur.psm1 b/CyberarkConjur.psm1 index f9a873a..95781d1 100644 --- a/CyberarkConjur.psm1 +++ b/CyberarkConjur.psm1 @@ -15,13 +15,55 @@ $CCConfig = @{ TokenTTL = 6 * 60 Credential = $null TokenExpireDate = $null - IdentifierRootPath = $null CommonParameters = ([System.Management.Automation.PSCmdlet]::CommonParameters + [System.Management.Automation.PSCmdlet]::OptionalCommonParameters) } ############################### # Invoke & Config Conjur ############################### + +<# +.SYNOPSIS +This is the main fonction that does all the API calls. +Please don't use it unless you want to test it + +.DESCRIPTION +Does what it needs to do to parse API request + +.PARAMETER API +[Mandatory] the main API branch you are calling + +.PARAMETER Command +additional path that is added to the URI + +.PARAMETER Identifier +adds to the URI the Identifier + +.PARAMETER Body +The Body sent within the query + +.PARAMETER Method +The used method + +.PARAMETER Headers +Specific headers can be added (no authentication headers will be added if used) + +.PARAMETER FixUri +Fixing URI issues + +.PARAMETER Credential +Credential object that is passed directly to the Rest method call + + +.INPUTS + +None + +.OUTPUTS + +Too many outputs are possible to describe them here. + +#> Function Invoke-Conjur { [CmdletBinding()] param( @@ -62,14 +104,7 @@ Function Invoke-Conjur { ############################## # Building the URI ############################## - $Commands = (@($Authority,$API) + $Command) | ? { $_ } - if ($PsBoundParameters.containskey("Identifier")) { - if ($CCConfig.IdentifierRootPath) { - $Identifier = $CCConfig.IdentifierRootPath + "/" + $Identifier - } - $Commands += $Identifier - } - + $Commands = (@($Authority,$API) + $Command) | ? { $_ } $Commands = ( $Commands -join "/") -replace "//+","/" -replace '/$' $Commands = $Commands -replace "/!a","/$($CCConfig.Account)" if ($PsBoundParameters.containskey("query")) { @@ -210,12 +245,6 @@ Will set the API key of the indentifier (requires AuthnLogin) .PARAMETER AuthaurityName_WR In some configurations, you have read only instances of Conjur. By adding this parameter, you will consider the AuthaurityName as read only instances, while any modification will call AuthaurityName_WR as DNS name - -.PARAMETER IdentifierRootPath -If all your Indentifiers have the same headers, you might want to use this switch to automatically indent any identifier with this variable. -Example without having set this parameter, you will need to say identifier = deaultpath/defaultfolder/oracle/myAccount. -If you set the IdentifierRootPath to deaultpath/defaultfolder, in all your functions, you will only need to specify oracle/myAccount - .PARAMETER IamAuthnBranch [AWS IAM integration] This parameter is for Iam authentication plugin, and has not been tested yet @@ -253,7 +282,6 @@ Function Initialize-Conjur { [parameter(ParameterSetName='Credential',ValueFromPipeline)][PSCredential]$Credential, [string]$AuthaurityName, [string]$AuthaurityName_WR, - [string]$IdentifierRootPath, [string]$IamAuthnBranch, [string]$AWS_MetaData, [Switch]$IgnoreSsl @@ -379,8 +407,6 @@ Function Get-ResponseBodyFromException { return $responseBody } - - ############################### # Internal IAM Functions ############################### @@ -694,8 +720,8 @@ Export-ModuleMember -Function Receive-ConjurAuthenticate <# .SYNOPSIS - -Changes a user’s password #### THIS FUNCTION HAS NOT BEEN TESTED +#### This function has not been tested yet #### +Changes a user’s password .DESCRIPTION @@ -705,6 +731,11 @@ Your HTTP/REST client probably provides HTTP basic authentication support. For e Note : machine roles (Hosts) do not have passwords. They authenticate using their API keys, while passwords are only used by human users. +.PARAMETER Credential +The user accout/password + +.PARAMETER Password +The new password .INPUTS @@ -728,7 +759,7 @@ Function New-ConjurUserPassword { # PUT [CmdletBinding()] param( [string]$Credential, - [string]$NewPassword + [string]$Password ) process { return Invoke-Conjur authn !A,"password" -Body $Password -Credential $Credential -Headers @{} @@ -739,8 +770,7 @@ Export-ModuleMember -Function New-ConjurUserPassword <# .SYNOPSIS - -#### THIS FUNCTION HAS NOT BEEN TESTED +#### This function has not been tested yet #### Rotate Personal API Key Or Replaces the API key of another role that you can update with a new, securely random API key. The new API key is returned as the response body. @@ -789,7 +819,7 @@ Function New-ConjurApiKey { # PUT [Parameter(Position=0,mandatory,ParameterSetName='User')][string]$Credential, [Parameter(Position=0,mandatory,ParameterSetName='Kind')][string]$Identifier, [ValidateSet("user","host","layer","group","policy","variable","webservice")] - [Parameter(Position=1,ParameterSetName='host')][string]$Kind='host' + [Parameter(Position=1,ParameterSetName='Kind')][string]$Kind='host' ) process { $Switches = @{} @@ -808,6 +838,7 @@ Export-ModuleMember -Function New-ConjurApiKey <# .SYNOPSIS +#### This function has not been tested yet #### OIDC Authenticator .DESCRIPTION @@ -916,13 +947,19 @@ Export-ModuleMember -Function Get-ConjurWhoAmI <# .SYNOPSIS -#### THIS FUNCTION HAS NOT BEEN TESTED +#### This function has not been tested yet #### Get the Authenticator Status .DESCRIPTION Once the status webservice has been properly configured and the relevant user groups have been given permissions to access the status webservice, the users in those groups can check the status of the authenticator. +.PARAMETER AuthenticatorType +The type of authenticator, for example authn-oidc + +.PARAMETER ServiceId +The ID of the authenticator provider, for example okta + .INPUTS None. You cannot pipe objects to this function. @@ -948,33 +985,28 @@ Function Get-ConjurAuthenticatorStatus { [CmdletBinding()] param( [string]$AuthenticatorType, - [string]$AerviceId + [string]$ServiceId ) process { - return Invoke-Conjur $AuthenticatorType $AerviceId,!A,status + return Invoke-Conjur $AuthenticatorType $ServiceId,!A,status } } Export-ModuleMember -Function Get-ConjurAuthenticatorStatus <# .SYNOPSIS - Get health of a conjur instance .DESCRIPTION - Get health of a conjur instance .INPUTS - None. You cannot pipe objects to this function. .OUTPUTS - System.Collections.Hashtable. The health of the conjur instance. .EXAMPLE - PS> Get-ConjurHealth services database ok -------- -------- -- @@ -997,6 +1029,7 @@ Export-ModuleMember -Function Get-ConjurHealth <# .SYNOPSIS +#### This function has not been tested yet #### Show Public Keys .DESCRIPTION @@ -1046,11 +1079,9 @@ Export-ModuleMember -Function Get-ConjurPublicKeys ############################### <# .SYNOPSIS - Retrieve one or multiple secrets from conjur .DESCRIPTION - Retrieve one or multiple secret from conjur If one Identifier is selected, the returned object will be the value of the secret If Multiple Identifier, the returned object will a PsObject with all the secrets in a single query @@ -1180,11 +1211,9 @@ Export-ModuleMember -Function Get-ConjurSecretCredential <# .SYNOPSIS - Set a secret in conjur .DESCRIPTION - Set a secret in conjur Takes a secret identifier and secret value @@ -1236,29 +1265,28 @@ Export-ModuleMember -Function Update-ConjurSecret -Alias Set-ConjurSecret ############################### <# .SYNOPSIS - +#### This function has not been tested yet #### Modifies an existing Conjur policy .DESCRIPTION - Data may be explicitly deleted using the !delete, !revoke, and !deny statements. Unlike “replace” mode, no data is ever implicitly deleted. .PARAMETER Identifier The identifier used to update the policy +.PARAMETER PolicyFilePath +The YAML policy file path (can not be used with Policy) + .PARAMETER Policy -The YAML policy +The YAML policy (can not be used with PolicyFilePath) .INPUTS - [string]Policy : The Yaml configuration of a Policy .OUTPUTS - None. .EXAMPLE - PS> Get-content .\test-policy.yml | Update-ConjurPolicy -Identifier root created_roles version @@ -1293,11 +1321,10 @@ Export-ModuleMember -Function Update-ConjurPolicy <# .SYNOPSIS - +#### This function has not been tested yet #### Loads or replaces a Conjur policy document. .DESCRIPTION - Any policy data which already exists on the server but is not explicitly specified in the new policy file will be deleted. .PARAMETER Identifier @@ -1305,10 +1332,10 @@ The identifier used to update the policy .PARAMETER PolicyFilePath -The path to the policy that will be loaded +The YAML policy file path (can not be used with Policy) .PARAMETER Policy -The YAML policy that will be loaded +The YAML policy (can not be used with PolicyFilePath) .INPUTS @@ -1368,10 +1395,10 @@ The identifier used to update the policy .PARAMETER PolicyFilePath -The path to the policy that will be loaded +The YAML policy file path (can not be used with Policy) .PARAMETER Policy -The YAML policy that will be loaded +The YAML policy (can not be used with PolicyFilePath) .INPUTS @@ -1422,11 +1449,9 @@ Export-ModuleMember -Function Add-ConjurPolicy -Alias Append-ConjurPolicy ############################### <# .SYNOPSIS - List resource within an organization account .DESCRIPTION - If a kind query parameter is given, narrows results to only resources of that kind. If a limit is given, returns no more than that number of results. Providing an offset skips a number of resources before returning the rest. In addition, providing an offset will give limit a default value of 10 if none other is provided. These two parameters can be combined to page through results. @@ -1440,8 +1465,22 @@ If the role or acting_as query parameter is given, then the resource list can be .PARAMETER Kind Filters on the Kinds of resources. Valid Kinds are : user,host,layer,group,policy,variable,webservice -.PARAMETER identifier -The identifier (path) of the object +.PARAMETER search +search term used to narrow results + +.PARAMETER limit +maximum number of results to return + +.PARAMETER offset +number of results to skip + +.PARAMETER count +if true, return only the number of items in the list + +.PARAMETER acting_as +The fully qualified identifier for the role whose resource list you want to view. It should be entered as {account}:{kind}:{identifier} where the identifier is URL-encoded. For more information about URL encoding, see URI. + +Example: cucumber:user:alice .INPUTS None. You cannot pipe objects to this function. @@ -1484,7 +1523,7 @@ policy_versions : {} .LINK -https://www.conjur.org/api.html#role-based-access-control-list-resources-get +https://docs.conjur.org/Latest/en/Content/Developer/Conjur_API_List_Resources.htm #> @@ -1511,11 +1550,9 @@ Export-ModuleMember -Function Get-ConjurResources <# .SYNOPSIS - Show a Resource .DESCRIPTION - Show a Resource .PARAMETER Kind @@ -1528,11 +1565,9 @@ The identifier (path) of the object None. You cannot pipe objects to this function. .OUTPUTS - PsObject of the resource .EXAMPLE - PS> Get-ConjurResources created_at : 2019-05-29T16:42:56.284+00:00 @@ -1544,7 +1579,6 @@ policy_versions : {@{version=1; created_at=2019-05-29T16:42:56.284+00:00; policy .EXAMPLE - PS> Get-ConjurResource created_at : 7/25/2017 8:30:38 AM @@ -1694,6 +1728,13 @@ Gets detailed information about a specific role, including the role members. .DESCRIPTION If a role A is granted to a role B, then role A is said to have role B as a member. These relationships are described in the “members” portion of the returned JSON +.PARAMETER kind +[Mandatory] The Kind of role. +Possible values are : user,host,layer,group,policy + +.PARAMETER identifier +[Mandatory] The identifier of the Role + .INPUTS None. You cannot pipe objects to this function. @@ -1741,6 +1782,17 @@ Text search If the search parameter is provided, the results are narrowed to those pertaining to the search query. Search works across resource IDs and the values of annotations. It weighs results so that those with matching id or a matching value of an annotation called name appear first, then those with another matching annotation value, and finally those with a matching kind. +.PARAMETER search +Search string + +.PARAMETER kind +kind of role requested + +.PARAMETER limit +maximum number of results to return + +.PARAMETER offset +number of results to skip .INPUTS None. You cannot pipe objects to this function. @@ -1771,7 +1823,7 @@ policy : myorg:policy:root .LINK -https://docs.conjur.org/Latest/en/Content/Developer/Conjur_API_Show_Role.htm +https://docs.conjur.org/Latest/en/Content/Developer/Conjur_API_List_Role_Members.htm #> Function Get-ConjurRoleMember { [CmdletBinding()] @@ -1799,6 +1851,19 @@ If a limit is provided, the results return up to the number specified. Providing If the parameter count is true, the number of items in the list are returned. +.PARAMETER identifier +[Mandatory] identifier of the role + +.PARAMETER kind +[Mandatory] kind of role requested +Possible values are : user,host,layer,group,policy + +.PARAMETER limit +maximum number of results to return + +.PARAMETER offset +number of results to skip + .INPUTS None. You cannot pipe objects to this function. @@ -1836,13 +1901,26 @@ Export-ModuleMember -Function Get-ConjurRoleMemberships <# .SYNOPSIS -Creates one or more tokens which can be used to bootstrap host identity +#### This function has not been tested yet #### +Creates one or more tokens which can be used to bootstrap host identity .DESCRIPTION Creates one or more tokens which can be used to bootstrap host identity. Responds with a JSON document containing the tokens and their restrictions. If the tokens are created with a CIDR restriction, Conjur will only accept them from the allowlisted IP ranges. +.PARAMETER expiration +[Mandatory] Expiration date of the token + +.PARAMETER host_factory +[Mandatory] Fully qualified Host Factory id + +.PARAMETER count +Number of tokens to create + +.PARAMETER cidr +CIDR restriction(s) on token usage + .INPUTS None. You cannot pipe objects to this function. @@ -1884,13 +1962,17 @@ Export-ModuleMember -Function Grant-ConjurNewToken <# .SYNOPSIS -Revoke Tokens +#### This function has not been tested yet #### +Revoke Tokens .DESCRIPTION Revokes a token, immediately disabling it. If the tokens are created with a CIDR restriction, Conjur will only accept them from the allowlisted IP ranges. +.PARAMETER token +[Mandatory] Token you want to revoke. + .INPUTS None. You cannot pipe objects to this function. @@ -1903,7 +1985,7 @@ PS> Revoke-ConjurNewToken 281s2ag1g8s7gd2ezf6td3d619b52t9gaak3w8rj0p38124n384sq7 .LINK -https://docs.conjur.org/Latest/en/Content/Developer/Conjur_API_Create_Tokens.htm +https://docs.conjur.org/Latest/en/Content/Developer/Conjur_API_Revoke_Tokens.htm #> Function Revoke-ConjurToken { [CmdletBinding()] @@ -1919,6 +2001,7 @@ Export-ModuleMember -Function Revoke-ConjurToken <# .SYNOPSIS +#### This function has not been tested yet #### Create a Host .DESCRIPTION @@ -1963,8 +2046,9 @@ Function Add-ConjurHost { switch ($psboundparameters.keys) { annotations { $Query += "annotations=$annotations"} } - $Query = $Query | % { [System.Web.HttpUtility]::UrlEncode($_) } - return Invoke-Conjur host_factory_tokens hosts -body $Body + $Query = $Query | % { [System.Web.HttpUtility]::UrlEncode($_) } + write-verbose $query + return Invoke-Conjur host_factory_tokens hosts -query $query } } Export-ModuleMember -Function Add-ConjurHost \ No newline at end of file From ddee27b833e76c45dd29bc9c7e21d060ba285009 Mon Sep 17 00:00:00 2001 From: "Thomas Farray (tfarray)" Date: Thu, 14 Oct 2021 11:29:10 +0200 Subject: [PATCH 09/12] fixed a major issue with identifier not beeing added to URL --- CyberarkConjur.psm1 | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/CyberarkConjur.psm1 b/CyberarkConjur.psm1 index 95781d1..fd49ee8 100644 --- a/CyberarkConjur.psm1 +++ b/CyberarkConjur.psm1 @@ -104,7 +104,8 @@ Function Invoke-Conjur { ############################## # Building the URI ############################## - $Commands = (@($Authority,$API) + $Command) | ? { $_ } + $Commands = @((@($Authority,$API) + $Command) | ? { $_ }) + if ($PsBoundParameters.containskey("Identifier")) { $commands += $Identifier } $Commands = ( $Commands -join "/") -replace "//+","/" -replace '/$' $Commands = $Commands -replace "/!a","/$($CCConfig.Account)" if ($PsBoundParameters.containskey("query")) { @@ -1193,17 +1194,25 @@ TheUserName System.Security.SecureString Function Get-ConjurSecretCredential { [CmdletBinding()] param( - [Parameter(Position=0,mandatory=$true)][string[]]$IdentifierPath + [Parameter(Position=0,mandatory=$true)][string[]]$IdentifierPath, + [switch]$IncludeDomain ) $ToRetrieve = $IdentifierPath | % { @(($_ + "/username"),($_ + "/password")) } + if ($psboundparameters.containskey("IncludeDomain")) { + $ToRetrieve += $IdentifierPath | % { ($_ + "/domain") } + } $ToRetrieve = $ToRetrieve -replace "//+","/" Write-Verbose "Get-ConjurSecretCredential : Calling [Get-ConjurSecret $ToRetrieve]" $AllSecrets = Get-ConjurSecret $ToRetrieve $AllSP = $AllSecrets.psobject.Members | ? { $_.membertype -like "noteproperty" } | select -ExpandProperty name - $AllSP = $allSP -replace '/(password|username)$' | select -unique + $AllSP = $allSP -replace '/(password|username|domain)$' | select -unique $Results = $AllSp | % { [securestring]$SS = ConvertTo-SecureString $AllSecrets."$_/password" -AsPlainText -Force - New-Object System.Management.Automation.PSCredential ($AllSecrets."$_/username", $SS ) + $UserName = $AllSecrets."$_/username" + if ($AllSecrets."$_/domain") { + $UserName = $AllSecrets."$_/domain" + "\" + $UserName + } + New-Object System.Management.Automation.PSCredential ($UserName, $SS ) } return $results } From f1dff8c0cce0da2a37c35f19f57f81cdb78d38a2 Mon Sep 17 00:00:00 2001 From: "Thomas Farray (tfarray)" Date: Mon, 25 Oct 2021 11:05:48 +0200 Subject: [PATCH 10/12] Mostly fixing typos & grammar --- CyberarkConjur.psm1 | 52 +++++++++++++++++------------------- README.md | 65 ++++++++++++++++++++++++++++++++++++++------- 2 files changed, 81 insertions(+), 36 deletions(-) diff --git a/CyberarkConjur.psm1 b/CyberarkConjur.psm1 index fd49ee8..3ab33a3 100644 --- a/CyberarkConjur.psm1 +++ b/CyberarkConjur.psm1 @@ -6,8 +6,8 @@ $CCConfig = @{ AWS_MetaData = "169.254.169.254" Account = $null - AuthaurityName = $null - AuthaurityName_WR = $null + AuthorityName = $null + AuthorityName_WR = $null IamAuthnBranch = $null Certificate = $null # This has not been explained in the former Module Token = $null @@ -21,10 +21,10 @@ $CCConfig = @{ ############################### # Invoke & Config Conjur ############################### - +[System.Net.ServicePointManager]::ServerCertificateValidationCallback = $null <# .SYNOPSIS -This is the main fonction that does all the API calls. +This is the main function that does all the API calls. Please don't use it unless you want to test it .DESCRIPTION @@ -95,10 +95,10 @@ Function Invoke-Conjur { ############################## # Changing to the Write instance if required ############################## - $Authority = $CCConfig.AuthaurityName - if ($Method -notlike "GET" -and $CCConfig.AuthaurityName_WR -and $API -notmatch 'authn') { + $Authority = $CCConfig.AuthorityName + if ($Method -notlike "GET" -and $CCConfig.AuthorityName_WR -and $API -notmatch 'authn') { Write-verbose "Switching to WRITE" - $Authority = $CCConfig.AuthaurityName_WR + $Authority = $CCConfig.AuthorityName_WR } ############################## @@ -209,7 +209,7 @@ Function Invoke-Conjur { } } if ($ClearError) {$global:Error.Remove($global:Error[0])} - return $Result + if ($Result) { return $Result } else { return } } } Export-ModuleMember -Function Invoke-Conjur @@ -225,7 +225,7 @@ Please check all the parameters in the help file. Mandatory parameters are : Account : Organization account name Credential : Will store the API key that will grant you access to Conjur -AuthaurityName : DNS authority name of your Conjur instance +AuthorityName : DNS authority name of your Conjur instance .PARAMETER Account @@ -240,11 +240,11 @@ Will set the indentifier of the host API key (requires AuthnApiKey) .PARAMETER AuthnApiKey (deprecated | use credential instead) Will set the API key of the indentifier (requires AuthnLogin) -.PARAMETER AuthaurityName -[Mandatory] Will set the name of your conjur instance. Example, if your site is https://eval.conjur.org then you need to set AuthaurityName = eval.conjur.org +.PARAMETER AuthorityName +[Mandatory] Will set the name of your conjur instance. Example, if your site is https://eval.conjur.org then you need to set AuthorityName = eval.conjur.org -.PARAMETER AuthaurityName_WR -In some configurations, you have read only instances of Conjur. By adding this parameter, you will consider the AuthaurityName as read only instances, while any modification will call AuthaurityName_WR as DNS name +.PARAMETER AuthorityName_WR +In some configurations, you have read only instances of Conjur. By adding this parameter, you will consider the AuthorityName as read only instances, while any modification will call AuthorityName_WR as DNS name .PARAMETER IamAuthnBranch [AWS IAM integration] This parameter is for Iam authentication plugin, and has not been tested yet @@ -267,10 +267,10 @@ Null PS> $HostApiIdentifier = "host/some/application" PS> $Cred = (Get-credential -Message "Please enter your Conjur API key" -UserName $ApiIdentifier) -PS> Initialize-Conjur -Credential $Cred -Account MyOrg -AuthaurityName eval.conjur.org +PS> Initialize-Conjur -Credential $Cred -Account MyOrg -AuthorityName eval.conjur.org .EXAMPLE -PS> $Cred | Initialize-Conjur -Account MyOrg -AuthaurityName readeval.conjur.org -AuthaurityName_WR writeeval.conjur.org +PS> $Cred | Initialize-Conjur -Account MyOrg -AuthorityName readeval.conjur.org -AuthorityName_WR writeeval.conjur.org #> @@ -281,8 +281,8 @@ Function Initialize-Conjur { [parameter(ParameterSetName='Login',mandatory)][string]$AuthnLogin, [parameter(ParameterSetName='Login',mandatory)][string]$AuthnApiKey, [parameter(ParameterSetName='Credential',ValueFromPipeline)][PSCredential]$Credential, - [string]$AuthaurityName, - [string]$AuthaurityName_WR, + [string]$AuthorityName, + [string]$AuthorityName_WR, [string]$IamAuthnBranch, [string]$AWS_MetaData, [Switch]$IgnoreSsl @@ -315,7 +315,7 @@ Function Initialize-Conjur { $CCConfig[$_] = $PsBoundParameters.item($_) $CCConfig["Credential"] = $null } - AuthaurityName{ + AuthorityName{ $CCConfig[$_] = $PsBoundParameters.item($_) -replace "http.://" } @@ -360,7 +360,7 @@ HashTable. The configuration variables for this module PS> $HostApiIdentifier = "host/some/application" PS> $Cred = (Get-credential -Message "Please enter your Conjur API key" -UserName $ApiIdentifier) -PS> Initialize-Conjur -Credential $Cred -Account MyOrg -AuthaurityName eval.conjur.org +PS> Initialize-Conjur -Credential $Cred -Account MyOrg -AuthorityName eval.conjur.org .EXAMPLE PS> Show-ConjurConfiguration @@ -374,8 +374,8 @@ Account MyOrg Credential System.Management.Automation.PSCredential Token @{protected=***** Hidden ****** Certificate -AuthaurityName read.eval.conjur.org -AuthaurityName_WR write.eval.conjur.org +AuthorityName read.eval.conjur.org +AuthorityName_WR write.eval.conjur.org IamAuthnBranch APIKey ***** Hidden ****** #> @@ -598,7 +598,7 @@ Function Receive-ConjurLogin { ) process { if ( !$CCConfig.APIKey -or $PsBoundParameters.containskey("force") ) { - $MissingConfig = "Account","AuthaurityName","Credential" | ? { !$CCConfig[$_] } + $MissingConfig = "Account","AuthorityName","Credential" | ? { !$CCConfig[$_] } if ($MissingConfig) { write-Warning "The Conjur Module is is missing information : [$($MissingConfig -join ',')] . Please run the [Initialize-ConjurConfiguration] command with the above switches. You can also run [get-help Initialize-ConjurConfiguration] for more information." return @@ -835,8 +835,6 @@ Function New-ConjurApiKey { # PUT } Export-ModuleMember -Function New-ConjurApiKey - - <# .SYNOPSIS #### This function has not been tested yet #### @@ -1151,7 +1149,7 @@ Function Get-ConjurSecret { } else { $ModifiedSI += $variable_ids -join ',' } - $Result = Invoke-Conjur secrets -query $ModifiedSI + $Result = Invoke-Conjur secrets -query $ModifiedSI } return $Result } @@ -1266,8 +1264,8 @@ Function Set-ConjurSecret { # POST | Set a Secret ) return Invoke-Conjur secrets !A,$Kind -identifier $Identifier -Body $SecretValue } -New-Alias Set-ConjurSecret Update-ConjurSecret -Export-ModuleMember -Function Update-ConjurSecret -Alias Set-ConjurSecret +New-Alias Update-ConjurSecret Set-ConjurSecret +Export-ModuleMember -Function Set-ConjurSecret -Alias Update-ConjurSecret ############################### # Policies API diff --git a/README.md b/README.md index 94ec821..fbb9521 100644 --- a/README.md +++ b/README.md @@ -18,16 +18,45 @@ This allows you to import modules without having to specify the path Instructions : copy the module to one of the existing path of that environment variable ($env:PSModulePath will tell you all of them) -```powershell -PS C:\> cd $env:USERPROFILE\Documents\WindowsPowerShell\Modules PS C:\Users\MyProfile\Documents\WindowsPowerShell\Modules> git clone https://github.com/zamothh/conjur-api-powershell.git CyberarkConjur -``` Once you cloned the project to a PsModulePath folder, you can import the module from any directory ```powershell PS C:\> import-module CyberarkConjur ``` + + +### How should the module be installed +There is an environment variable called `$ENV:PsModulePath folder`, that lists all the paths where you can have module installed. +This allows you to import modules without having to specify the path +```powershell +PS C:\> $ENV:PSModulePath -split ";" + C:\Users\MyAccount\Documents\PowerShell\Modules + C:\Program Files\PowerShell\Modules + ... and more ... +``` + +Instructions : +Download and install git https://git-scm.com/download/win +On git hub, go to the fork/project you want to use, click on the green `Code` button and then click on `copy` to copy the clone link to your clipboard. +Then open git bash +Go to the directory you want to clone you project on +Clone your porject +```bash +MyAccount@MyPc MINGW64 ~ +$ cd "C:\Program Files\PowerShell\Modules" + +MyAccount@MyPc MINGW64 /c/Program Files/PowerShell/Modules +$ git clone [paste the clone link here] CyberarkConjur +``` + +Once you cloned the project to a `$ENV:PsModulePath folder`, you can import the module from any directory +```powershell +PS C:\> import-module CyberarkConjur +``` + + ### From source ```powershell @@ -38,27 +67,45 @@ PS C:\> Import-Module .\CyberarkConjur.psm1 ### Setting the module #### Conjur authentication -Prior to launching any commands, you will need to configure your conjur environment +Prior to launching any commands, you will need to configure your Conjur environment. To do so, and to keep the environment secure, the Initialize-Conjur will store in memory your API path & token into a PsCredential object. +You can authenticate using the less secured method : ```powershell -PS C:\> $PsCredential = Get-Credential -Message "CyberArk Conjur Credential input" -UserName "host\Host_Identifier" -PS C:\> Initialize-Conjur -Account Account -AuthnLogin "Identifier of a host" -Crednetial $PsCredential +PS C:\> Initialize-Conjur -Account myorg -AuthorityName "eval.conjur.org" +-AuthnLogin "Identifier of a host" -AuthnApiKey "Your API Key" ``` +The best is to always use `PsCredential` object, and never to store an uncrypted secret into memory. +```powershell +PS C:\> Initialize-Conjur -Account myorg -AuthorityName "eval.conjur.org" +-Credential $credential +``` + +By directly using a credential object, you will also be able to securely store that credential on your hard drive, using the Windows Data Protection API : ```powershell -PS C:\> Initialize-Conjur -Account Account -AuthnLogin "Identifier of a host" -AuthnApiKey "Your API generated key" -AuthaurityName "your-conjur-auth-read.mycompany.com" +# How to store the credential on the hard drive (you will have to do it only once) : +$Credential = (Get-credential -Message "Please enter your Conjur API key" -UserName $AuthnLogin) +$Credential | Export-Clixml $MyPath + +# How recall the credential and authenticate : +$Credential = Import-Clixml $MyPath +Initialize-Conjur -Account myorg -AuthorityName "eval.conjur.org" +-Credential $credential ``` +The Windows Data Protection API is well documented over internet, feel free to have a closer look if you have security concerns. + + #### IAM Authentication Some code has been started to be written, but is not good enough to publish anything yet. -This would require someone with an IAM access to continue developping this code +This would require someone with an IAM access to continue developing this code. ### Available Functions #### Initialize-Conjur ```powershell -PS C:\> Initialize-Conjur -Account Account -AuthnLogin "Identifier of a host" -AuthnApiKey "Your API generated key" -AuthaurityName "your-conjur-auth-read.mycompany.com" +PS C:\> Initialize-Conjur -Account Account -AuthnLogin "Identifier of a host" -AuthnApiKey "Your API generated key" -AuthorityName "your-conjur-auth-read.mycompany.com" ``` #### Invoke-Conjur From ad129796aadf9c2441f78ca179679200405a45a9 Mon Sep 17 00:00:00 2001 From: tfarray Date: Thu, 17 Feb 2022 16:22:09 +0100 Subject: [PATCH 11/12] Removes existing token when initializing Cyberark --- CyberarkConjur.psm1 | 270 ++++++++++++++++++++++---------------------- 1 file changed, 138 insertions(+), 132 deletions(-) diff --git a/CyberarkConjur.psm1 b/CyberarkConjur.psm1 index 3ab33a3..f62f6ac 100644 --- a/CyberarkConjur.psm1 +++ b/CyberarkConjur.psm1 @@ -12,10 +12,10 @@ $CCConfig = @{ Certificate = $null # This has not been explained in the former Module Token = $null APIKey = $null - TokenTTL = 6 * 60 + TokenTTL = 6 * 60 Credential = $null TokenExpireDate = $null - CommonParameters = ([System.Management.Automation.PSCmdlet]::CommonParameters + [System.Management.Automation.PSCmdlet]::OptionalCommonParameters) + CommonParameters = ([System.Management.Automation.PSCmdlet]::CommonParameters + [System.Management.Automation.PSCmdlet]::OptionalCommonParameters) } ############################### @@ -25,16 +25,16 @@ $CCConfig = @{ <# .SYNOPSIS This is the main function that does all the API calls. -Please don't use it unless you want to test it +Please don't use it unless you want to test it .DESCRIPTION -Does what it needs to do to parse API request +Does what it needs to do to parse API request .PARAMETER API [Mandatory] the main API branch you are calling .PARAMETER Command -additional path that is added to the URI +additional path that is added to the URI .PARAMETER Identifier adds to the URI the Identifier @@ -57,7 +57,7 @@ Credential object that is passed directly to the Rest method call .INPUTS -None +None .OUTPUTS @@ -67,10 +67,10 @@ Too many outputs are possible to describe them here. Function Invoke-Conjur { [CmdletBinding()] param( - [Parameter(Position=0,Mandatory)][string]$API, - [Parameter(Position=1)][string[]]$Command, - [Parameter(Position=2)][string]$Identifier, - [string[]]$query, + [Parameter(Position=0,Mandatory)][string]$API, + [Parameter(Position=1)][string[]]$Command, + [Parameter(Position=2)][string]$Identifier, + [string[]]$query, [string]$Body, [string]$Method = "GET", # [Hashtable]$Headers = @{ "Content-Type" = "application/json" }, @@ -78,9 +78,9 @@ Function Invoke-Conjur { [switch]$FixUri, [PsCredential]$Credential ) - process { + process { ############################## - # Initialization + # Initialization ############################## $CalledBy = (Get-PSCallStack)[1].command if(!$PsBoundParameters.containskey("Method")) { @@ -91,18 +91,18 @@ Function Invoke-Conjur { "^(New|Submit|Write)-" { $method = "PUT" } } } - + ############################## # Changing to the Write instance if required ############################## $Authority = $CCConfig.AuthorityName if ($Method -notlike "GET" -and $CCConfig.AuthorityName_WR -and $API -notmatch 'authn') { - Write-verbose "Switching to WRITE" + Write-verbose "Switching to WRITE" $Authority = $CCConfig.AuthorityName_WR } - + ############################## - # Building the URI + # Building the URI ############################## $Commands = @((@($Authority,$API) + $Command) | ? { $_ }) if ($PsBoundParameters.containskey("Identifier")) { $commands += $Identifier } @@ -111,23 +111,23 @@ Function Invoke-Conjur { if ($PsBoundParameters.containskey("query")) { $commands = ($Commands -replace '/?$' ) + "?" + ($query -join '&') } - $URL = "https://$Commands" - - + $URL = "https://$Commands" + + $RestMethod = @{ Method = $Method Headers = $Headers URI = [uri]$URL } - + if ($PsBoundParameters.containskey("Credential")) { $RestMethod.add("Credential",$Credential) } - + ############################## - # Fixing URI the URI contains \ that should not be interpreted as URI path but as data + # Fixing URI the URI contains \ that should not be interpreted as URI path but as data ############################## - if ($PsBoundParameters.containskey("FixUri") -and $PSVersionTable.PSVersion.Major -le 5) { + if ($PsBoundParameters.containskey("FixUri") -and $PSVersionTable.PSVersion.Major -le 5) { $UnEscapeDotsAndSlashes = 0x2000000; $SimpleUserSyntax = 0x20000; @@ -144,31 +144,31 @@ Function Invoke-Conjur { $uriSyntaxFlags = $uriSyntaxFlags -band (-bnot $SimpleUserSyntax); $fieldInfo.SetValue($uriParser, $uriSyntaxFlags); } - + ############################## # Authentication verification ############################## - + if ( $API -notmatch 'authn') { if ($CCConfig.IamAuthnBranch) { $ApiKey = Get-IamConjurApiKey } else { $ApiKey = Receive-ConjurLogin } - + if (!$ApiKey) { throw "CyberArkConjour Module Failed to retrieve an API Key" } if ($CCConfig.IamAuthnBranch) { # $TokenAPI = "authn-iam" - # $TokenCommand += "$($CCConfig.IamAuthnBranch)/" + # $TokenCommand += "$($CCConfig.IamAuthnBranch)/" # $TokenCommand += "$ConjurUsername/authenticate" - } else { + } else { $Auth = Receive-ConjurAuthenticate -ApiKey $ApiKey } if (!$Auth) { throw "CyberArkConjour Module Failed to Authenticate (the API Key was generated)" } } - + ############################## # Headers (Token) ############################## @@ -176,27 +176,27 @@ Function Invoke-Conjur { $base64 = [Convert]::ToBase64String([Text.Encoding]::ASCII.GetBytes((($CCConfig.Token | ConvertTo-Json)))) $RestMethod.Headers.add("Authorization","Token token=""$base64""") } - + ############################## - # Additional parameters + # Additional parameters ############################## Switch ($PsBoundParameters.keys) { "Body" { $RestMethod.add("body",$body) } } - - if ($CCConfig.Certificate) { + + if ($CCConfig.Certificate) { $RestMethod.add("Certificate",$CCConfig.Certificate) $RestMethod.add("CertificateThumbprint",$CCConfig.Certificate.Thumbprint) } - + ############################## - # Sending Rest API Request + # Sending Rest API Request ############################## Write-verbose ($RestMethod | out-string -Width ($host.UI.RawUI.BufferSize.Width -2 )) - + # Write-Verbose "Invoke-Conjur : URL : $URL" $ClearError = $false - try { + try { $Result = Invoke-RestMethod @RestMethod } catch { Write-warning "Message : $($_.Exception.Response.StatusCode)" @@ -204,8 +204,8 @@ Function Invoke-Conjur { Write-warning "Error : $($_.ErrorDetails.Message)" throw $_ break - } else { - $ClearError = $true + } else { + $ClearError = $true } } if ($ClearError) {$global:Error.Remove($global:Error[0])} @@ -213,7 +213,7 @@ Function Invoke-Conjur { } } Export-ModuleMember -Function Invoke-Conjur - + <# .SYNOPSIS @@ -222,9 +222,9 @@ This command is required prior to running any other one. This will configure the .DESCRIPTION Please check all the parameters in the help file. -Mandatory parameters are : +Mandatory parameters are : Account : Organization account name -Credential : Will store the API key that will grant you access to Conjur +Credential : Will store the API key that will grant you access to Conjur AuthorityName : DNS authority name of your Conjur instance @@ -241,12 +241,12 @@ Will set the indentifier of the host API key (requires AuthnApiKey) Will set the API key of the indentifier (requires AuthnLogin) .PARAMETER AuthorityName -[Mandatory] Will set the name of your conjur instance. Example, if your site is https://eval.conjur.org then you need to set AuthorityName = eval.conjur.org +[Mandatory] Will set the name of your conjur instance. Example, if your site is https://eval.conjur.org then you need to set AuthorityName = eval.conjur.org .PARAMETER AuthorityName_WR -In some configurations, you have read only instances of Conjur. By adding this parameter, you will consider the AuthorityName as read only instances, while any modification will call AuthorityName_WR as DNS name +In some configurations, you have read only instances of Conjur. By adding this parameter, you will consider the AuthorityName as read only instances, while any modification will call AuthorityName_WR as DNS name -.PARAMETER IamAuthnBranch +.PARAMETER IamAuthnBranch [AWS IAM integration] This parameter is for Iam authentication plugin, and has not been tested yet .PARAMETER AWS_MetaData @@ -288,17 +288,23 @@ Function Initialize-Conjur { [Switch]$IgnoreSsl ) Process { - $ParamatersToIgnore = ([System.Management.Automation.PSCmdlet]::CommonParameters + [System.Management.Automation.PSCmdlet]::OptionalCommonParameters) + $ParamatersToIgnore = ([System.Management.Automation.PSCmdlet]::CommonParameters + [System.Management.Automation.PSCmdlet]::OptionalCommonParameters) $ParamatersToIgnore += @('AuthnLogin','AuthnApiKey',"IgnoreSsl") - + + # Whenever we call Initialize-Conjur, I want to make sure existing token infromation is cleared + $CCConfig["Token"] = $null + $CCConfig["TokenTTL"] = $null + $CCConfig["TokenExpireDate"] = $null + + $PsBoundParameters.keys | ? { $_ -notin $ParamatersToIgnore } | % { Switch ($_) { - "IgnoreSsl" { + "IgnoreSsl" { try { add-type " using System.Net; using System.Security.Cryptography.X509Certificates; - + public class IDontCarePolicy : ICertificatePolicy { public IDontCarePolicy() {} public bool CheckValidationResult( @@ -307,25 +313,25 @@ Function Initialize-Conjur { return true; } }" - [System.Net.ServicePointManager]::CertificatePolicy = new-object IDontCarePolicy + [System.Net.ServicePointManager]::CertificatePolicy = new-object IDontCarePolicy [Net.ServicePointManager]::SecurityProtocol = [Net.ServicePointManager]::SecurityProtocol -bor [Net.SecurityProtocolType]::Tls12 } catch { } } - IamAuthnBranch { + IamAuthnBranch { $CCConfig[$_] = $PsBoundParameters.item($_) $CCConfig["Credential"] = $null } - AuthorityName{ + AuthorityName{ $CCConfig[$_] = $PsBoundParameters.item($_) -replace "http.://" } - - - default { - $CCConfig[$_] = $PsBoundParameters.item($_) + + + default { + $CCConfig[$_] = $PsBoundParameters.item($_) } } } - + if ($PsCmdlet.ParameterSetName -like "Login") { write-warning "Please note that manipulating Credential object is always more secure. Please consider using the -Credential $CredObject instead" [securestring]$SS = ConvertTo-SecureString $AuthnApiKey -AsPlainText -Force @@ -373,14 +379,14 @@ TokenExpireDate 10/1/2021 10:11:39 AM Account MyOrg Credential System.Management.Automation.PSCredential Token @{protected=***** Hidden ****** -Certificate +Certificate AuthorityName read.eval.conjur.org AuthorityName_WR write.eval.conjur.org IamAuthnBranch APIKey ***** Hidden ****** #> Function Show-ConjurConfiguration { - return $CCConfig + return $CCConfig } Export-ModuleMember -Function Show-ConjurConfiguration @@ -416,20 +422,20 @@ Function Get-ResponseBodyFromException { Function Invoke-ConjurIam { [CmdletBinding()] param( - [Parameter(Position=0, Mandatory=$true)][string]$Command, + [Parameter(Position=0, Mandatory=$true)][string]$Command, [string]$Method = "get", [string]$Body - + ) - process { - $URL = - + process { + $URL = + $RestMethod = @{ Method = $Method URI = "http://$($CCConfig.AWS_MetaData)/" + $Command } - - try { + + try { $Result = Invoke-RestMethod @RestMethod } catch { $exception = $_.Exception @@ -438,7 +444,7 @@ Function Invoke-ConjurIam { throw $_ break } - + return $Result } } @@ -464,7 +470,7 @@ Function Enable-HelperNamespace{ byte[] kSigning = HmacSHA256(kService, ""aws4_request""); return kSigning; } - + public static byte[] HmacSHA256(byte[] key, string data) { var hashAlgorithm = new System.Security.Cryptography.HMACSHA256(key); @@ -478,8 +484,8 @@ Function Enable-HelperNamespace{ function Get-IamAuthorizationHeader { [CmdletBinding()] param ( - $cHost, - $cDate, + $cHost, + $cDate, $cToken, $cRegion, $cService, @@ -522,9 +528,9 @@ function Get-IamAuthorizationHeader { Function Receive-ConjurIamLogin { [CmdletBinding()] param() - + $region = Invoke-ConjurIam -command "latest/meta-data/placement/availability-zone" - $role = Invoke-ConjurIam "/latest/meta-data/iam/security-credentials" + $role = Invoke-ConjurIam "/latest/meta-data/iam/security-credentials" $cred_results = Invoke-Conjur "latest/meta-data/iam/security-credentials/$role" @@ -547,10 +553,10 @@ Function Receive-ConjurIamLogin { "authorization"="$output" }|ConvertTo-Json - return $conjurToken + return $conjurToken } set-alias Get-IamConjurApiKey Receive-ConjurIamLogin - + ############################### # Login / Authenticate ############################### @@ -593,19 +599,19 @@ https://docs.conjur.org/Latest/en/Content/Developer/Conjur_API_Login.htm #> Function Receive-ConjurLogin { [CmdletBinding()] - param( - [switch]$Force + param( + [switch]$Force ) process { if ( !$CCConfig.APIKey -or $PsBoundParameters.containskey("force") ) { $MissingConfig = "Account","AuthorityName","Credential" | ? { !$CCConfig[$_] } - if ($MissingConfig) { + if ($MissingConfig) { write-Warning "The Conjur Module is is missing information : [$($MissingConfig -join ',')] . Please run the [Initialize-ConjurConfiguration] command with the above switches. You can also run [get-help Initialize-ConjurConfiguration] for more information." return } $base64 = [Convert]::ToBase64String([Text.Encoding]::ASCII.GetBytes(("{0}:{1}" -f $CCConfig.Credential.UserName, $CCConfig.Credential.GetNetworkCredential().password))) $CCConfig.APIKey = Invoke-Conjur authn !a,login -headers @{ Authorization = "Basic $base64" } - } + } return $CCConfig.APIKey } } @@ -648,28 +654,28 @@ https://docs.conjur.org/Latest/en/Content/Developer/Conjur_API_Authenticate.htm #> Function Receive-ConjurAuthenticate { [CmdletBinding()] - param( + param( [string]$ApiKey = $CCConfig.APIKey, [Switch]$Force ) process { - if (!$CCConfig.Token -or $PsBoundParameters.containskey("force") -or ((get-date) -gt $CCConfig.TokenExpireDate)) { + if (!$CCConfig.Token -or $PsBoundParameters.containskey("force") -or ((get-date) -gt $CCConfig.TokenExpireDate)) { $StartTime = Get-date - if ( !$APIKey ) { + if ( !$APIKey ) { write-warning "No API Key was generated, you need to run [Receive-ConjurLogin | out-null] first" } $ConjurUsername = [uri]::EscapeDataString($CCConfig.Credential.username) - + $CCConfig.Token = Invoke-Conjur authn !a,$ConjurUsername,authenticate -Body $APIKey -Method POST -FixUri -Headers @{ } - + if (!$CCConfig.Token) { write-Warning "The Conjur Module was not able to authenticate. Please run the [Initialize-ConjurConfiguration] command to configure the module. You can also run [get-help Initialize-ConjurConfiguration] for more information." - return - } else { + return + } else { $CCConfig.TokenExpireDate = $StartTime.AddSeconds($CCConfig.TokenTTL) } } - + return $CCConfig.Token } } @@ -696,7 +702,7 @@ None. You cannot pipe objects to this function. .OUTPUTS -To Be completed +To Be completed .EXAMPLE @@ -713,7 +719,7 @@ Function Receive-ConjurIAMAuthenticate { param( ) process { $region = Invoke-ConjurIam -command "latest/meta-data/placement/availability-zone" - $role = Invoke-ConjurIam "/latest/meta-data/iam/security-credentials" + $role = Invoke-ConjurIam "/latest/meta-data/iam/security-credentials" $cred_results = Invoke-Conjur "latest/meta-data/iam/security-credentials/$role" } } @@ -736,7 +742,7 @@ Note : machine roles (Hosts) do not have passwords. They authenticate using thei The user accout/password .PARAMETER Password -The new password +The new password .INPUTS @@ -744,7 +750,7 @@ None. You cannot pipe objects to this function. .OUTPUTS -NULL +NULL .EXAMPLE @@ -758,9 +764,9 @@ https://docs.conjur.org/Latest/en/Content/Developer/Conjur_API_change_Password.h #> Function New-ConjurUserPassword { # PUT [CmdletBinding()] - param( + param( [string]$Credential, - [string]$Password + [string]$Password ) process { return Invoke-Conjur authn !A,"password" -Body $Password -Credential $Credential -Headers @{} @@ -772,7 +778,7 @@ Export-ModuleMember -Function New-ConjurUserPassword <# .SYNOPSIS #### This function has not been tested yet #### -Rotate Personal API Key +Rotate Personal API Key Or Replaces the API key of another role that you can update with a new, securely random API key. The new API key is returned as the response body. @@ -785,10 +791,10 @@ Replaces your own API key with a new, securely random API key. The new API key i For User API key , Any role can rotate its own API key. The name and password or current API key of the role must be provided via HTTP Basic Authorization. Your HTTP/REST client probably provides HTTP .PARAMETER Credential -The Credential object that contains the personal API Key as username and the API Key as password +The Credential object that contains the personal API Key as username and the API Key as password .PARAMETER Identifier -The identifier of the Role +The identifier of the Role .PARAMETER Kind The Kind API key you want to rotate. @@ -801,7 +807,7 @@ None. You cannot pipe objects to this function. .OUTPUTS -The new personal API Key +The new personal API Key .EXAMPLE @@ -816,7 +822,7 @@ https://docs.conjur.org/Latest/en/Content/Developer/Conjur_API_Rotate_Other_API_ #> Function New-ConjurApiKey { # PUT [CmdletBinding(DefaultParameterSetName="User")] - param( + param( [Parameter(Position=0,mandatory,ParameterSetName='User')][string]$Credential, [Parameter(Position=0,mandatory,ParameterSetName='Kind')][string]$Identifier, [ValidateSet("user","host","layer","group","policy","variable","webservice")] @@ -869,33 +875,33 @@ https://docs.conjur.org/Latest/en/Content/Developer/Conjur_API_OIDC_Authenticato #> Function Receive-ConjurOIDCAuthenticator { [CmdletBinding()] - param( + param( [Parameter(Position=0,mandatory)][string]$serviceid, [Parameter(Position=1,mandatory)][string]$APIKey, [switch]$force ) process { - if (!$CCConfig.Token -or $PsBoundParameters.containskey("force") -or ((get-date) -gt $CCConfig.TokenExpireDate)) { + if (!$CCConfig.Token -or $PsBoundParameters.containskey("force") -or ((get-date) -gt $CCConfig.TokenExpireDate)) { $StartTime = Get-date - if ( !$APIKey ) { + if ( !$APIKey ) { write-warning "No API Key was generated, you need to run [Receive-ConjurLogin | out-null] first" } - $Headers = @{ + $Headers = @{ "Content-Type" = "application/x-www-form-urlencoded" "Accept-Encoding" = "base64" } $Body = "id_token: ""$APIKey""" $CCConfig.Token = Invoke-Conjur authn-oidc !a,$ConjurUsername,authenticate -Body $Body -Headers $Headers - - + + if (!$CCConfig.Token) { write-Warning "The Conjur Module was not able to authenticate. Please run the [Initialize-ConjurConfiguration] command to configure the module. You can also run [get-help Initialize-ConjurConfiguration] for more information." - return - } else { + return + } else { $CCConfig.TokenExpireDate = $StartTime.AddSeconds($CCConfig.TokenTTL) } } - + return $CCConfig.Token } } @@ -982,7 +988,7 @@ https://docs.conjur.org/Latest/en/Content/Developer/Conjur_API_authenticator_sta #> Function Get-ConjurAuthenticatorStatus { [CmdletBinding()] - param( + param( [string]$AuthenticatorType, [string]$ServiceId ) @@ -1139,17 +1145,17 @@ Function Get-ConjurSecret { [Parameter(Position=1,ParameterSetName='Identifier')]$Kind = "variable", [string[]]$variable_ids ) - process { + process { if ($PsCmdlet.ParameterSetName -like "Identifier" -and $Identifier.count -eq 1 ) { $Result = Invoke-Conjur secrets !a,$Kind -Identifier ($Identifier | select -first 1) } else { $ModifiedSI = "variable_ids=" if ($PsCmdlet.ParameterSetName -like "Identifier") { - $ModifiedSI += ($Identifier | % { ($CCConfig.Account,$Kind,$_) -join ":" }) -join ',' + $ModifiedSI += ($Identifier | % { ($CCConfig.Account,$Kind,$_) -join ":" }) -join ',' } else { - $ModifiedSI += $variable_ids -join ',' + $ModifiedSI += $variable_ids -join ',' } - $Result = Invoke-Conjur secrets -query $ModifiedSI + $Result = Invoke-Conjur secrets -query $ModifiedSI } return $Result } @@ -1164,11 +1170,11 @@ Get-ConjurSecretCredential is an helper function that will call Get-ConjurSecret .DESCRIPTION If you add to a policy 2 secrets, one called username and the other called password, you will be able to use this function. -for example, if you have those 2 variables : +for example, if you have those 2 variables : myhome\subpath\username -myhome\subpath\password +myhome\subpath\password You will be able to directly retrieve the PsCredential Object using the command [Get-ConjurSecretCredential variable\myhome\subpath] - + .PARAMETER IdentifierPath The path to a pair of username/password couple @@ -1196,15 +1202,15 @@ Function Get-ConjurSecretCredential { [switch]$IncludeDomain ) $ToRetrieve = $IdentifierPath | % { @(($_ + "/username"),($_ + "/password")) } - if ($psboundparameters.containskey("IncludeDomain")) { + if ($psboundparameters.containskey("IncludeDomain")) { $ToRetrieve += $IdentifierPath | % { ($_ + "/domain") } - } + } $ToRetrieve = $ToRetrieve -replace "//+","/" Write-Verbose "Get-ConjurSecretCredential : Calling [Get-ConjurSecret $ToRetrieve]" $AllSecrets = Get-ConjurSecret $ToRetrieve $AllSP = $AllSecrets.psobject.Members | ? { $_.membertype -like "noteproperty" } | select -ExpandProperty name $AllSP = $allSP -replace '/(password|username|domain)$' | select -unique - $Results = $AllSp | % { + $Results = $AllSp | % { [securestring]$SS = ConvertTo-SecureString $AllSecrets."$_/password" -AsPlainText -Force $UserName = $AllSecrets."$_/username" if ($AllSecrets."$_/domain") { @@ -1264,7 +1270,7 @@ Function Set-ConjurSecret { # POST | Set a Secret ) return Invoke-Conjur secrets !A,$Kind -identifier $Identifier -Body $SecretValue } -New-Alias Update-ConjurSecret Set-ConjurSecret +New-Alias Update-ConjurSecret Set-ConjurSecret Export-ModuleMember -Function Set-ConjurSecret -Alias Update-ConjurSecret ############################### @@ -1294,7 +1300,7 @@ The YAML policy (can not be used with PolicyFilePath) None. .EXAMPLE -PS> Get-content .\test-policy.yml | Update-ConjurPolicy -Identifier root +PS> Get-content .\test-policy.yml | Update-ConjurPolicy -Identifier root created_roles version ------------- ------- @@ -1324,7 +1330,7 @@ Function Update-ConjurPolicy { # PATCH | Update a Policy if ($PsCmdlet.ParameterSetName -like "File" ) { $Policy = get-content $PolicyFilePath } return Invoke-Conjur policies !A,policy -Identifier $Identifier -Body $Policy } -Export-ModuleMember -Function Update-ConjurPolicy +Export-ModuleMember -Function Update-ConjurPolicy <# .SYNOPSIS @@ -1547,7 +1553,7 @@ Function Get-ConjurResources { ) process { $Command = @() - $psboundparameters.keys | ? { $_ -notin $CCConfig.CommonParameters } | % { + $psboundparameters.keys | ? { $_ -notin $CCConfig.CommonParameters } | % { $Command += "$_=$($psboundparameters.item($_))" } return Invoke-Conjur resources !A -query $Command @@ -1566,7 +1572,7 @@ Show a Resource Filters on the Kinds of resources. Valid Kinds are : user,host,layer,group,policy,variable,webservice .PARAMETER identifier -The identifier (path) of the object +The identifier (path) of the object .INPUTS None. You cannot pipe objects to this function. @@ -1789,7 +1795,7 @@ Text search If the search parameter is provided, the results are narrowed to those pertaining to the search query. Search works across resource IDs and the values of annotations. It weighs results so that those with matching id or a matching value of an annotation called name appear first, then those with another matching annotation value, and finally those with a matching kind. -.PARAMETER search +.PARAMETER search Search string .PARAMETER kind @@ -1858,10 +1864,10 @@ If a limit is provided, the results return up to the number specified. Providing If the parameter count is true, the number of items in the list are returned. -.PARAMETER identifier +.PARAMETER identifier [Mandatory] identifier of the role -.PARAMETER kind +.PARAMETER kind [Mandatory] kind of role requested Possible values are : user,host,layer,group,policy @@ -1903,20 +1909,20 @@ Function Get-ConjurRoleMemberships { Export-ModuleMember -Function Get-ConjurRoleMemberships ############################### -# Host Factories API +# Host Factories API ############################### <# .SYNOPSIS #### This function has not been tested yet #### -Creates one or more tokens which can be used to bootstrap host identity +Creates one or more tokens which can be used to bootstrap host identity .DESCRIPTION Creates one or more tokens which can be used to bootstrap host identity. Responds with a JSON document containing the tokens and their restrictions. If the tokens are created with a CIDR restriction, Conjur will only accept them from the allowlisted IP ranges. -.PARAMETER expiration +.PARAMETER expiration [Mandatory] Expiration date of the token .PARAMETER host_factory @@ -1957,11 +1963,11 @@ Function Grant-ConjurNewToken { ) process { $Query = @("expiration=$expiration","host_factory=$host_factory") - switch ($psboundparameters.keys) { + switch ($psboundparameters.keys) { count { $Query += "count=$count"} cidr { $cidr | % { $Query += "cidr[]=$_"} } } - $Query = $Query | % { [System.Web.HttpUtility]::UrlEncode($_) } + $Query = $Query | % { [System.Web.HttpUtility]::UrlEncode($_) } return Invoke-Conjur host_factory_tokens -query $Query } } @@ -1970,7 +1976,7 @@ Export-ModuleMember -Function Grant-ConjurNewToken <# .SYNOPSIS #### This function has not been tested yet #### -Revoke Tokens +Revoke Tokens .DESCRIPTION Revokes a token, immediately disabling it. @@ -2050,7 +2056,7 @@ Function Add-ConjurHost { ) process { $Query = @("id=$id") - switch ($psboundparameters.keys) { + switch ($psboundparameters.keys) { annotations { $Query += "annotations=$annotations"} } $Query = $Query | % { [System.Web.HttpUtility]::UrlEncode($_) } From 9a305f0e94481e69022911c7ed9b12bdcf6b1248 Mon Sep 17 00:00:00 2001 From: tfarray Date: Fri, 11 Mar 2022 13:46:56 +0100 Subject: [PATCH 12/12] text modifications on help, and almost nothing else --- CyberarkConjur.psm1 | 502 +++++--------------------------------------- 1 file changed, 57 insertions(+), 445 deletions(-) diff --git a/CyberarkConjur.psm1 b/CyberarkConjur.psm1 index f62f6ac..b574240 100644 --- a/CyberarkConjur.psm1 +++ b/CyberarkConjur.psm1 @@ -4,18 +4,18 @@ ############################### $CCConfig = @{ - AWS_MetaData = "169.254.169.254" - Account = $null - AuthorityName = $null - AuthorityName_WR = $null - IamAuthnBranch = $null - Certificate = $null # This has not been explained in the former Module - Token = $null - APIKey = $null - TokenTTL = 6 * 60 - Credential = $null - TokenExpireDate = $null - CommonParameters = ([System.Management.Automation.PSCmdlet]::CommonParameters + [System.Management.Automation.PSCmdlet]::OptionalCommonParameters) + AWS_MetaData = "169.254.169.254" + Account = $null + AuthorityName = $null + AuthorityName_WR = $null + IamAuthnBranch = $null + Certificate = $null # This has not been explained in the former Module + Token = $null + APIKey = $null + TokenTTL = 6 * 60 # This is the default value, as I have been told + Credential = $null + TokenExpireDate = $null + CommonParameters = ([System.Management.Automation.PSCmdlet]::CommonParameters + [System.Management.Automation.PSCmdlet]::OptionalCommonParameters) } ############################### @@ -25,44 +25,35 @@ $CCConfig = @{ <# .SYNOPSIS This is the main function that does all the API calls. -Please don't use it unless you want to test it - +You shouldn't need to be using it, unless you want to build your own queries manally .DESCRIPTION Does what it needs to do to parse API request - .PARAMETER API -[Mandatory] the main API branch you are calling - +[Mandatory] Invokes the command API which you are calling, as described in the official Conjur documentation https://docs.conjur.org/Latest/en/Content/Developer/lp_REST_API.htm .PARAMETER Command additional path that is added to the URI - .PARAMETER Identifier adds to the URI the Identifier - .PARAMETER Body The Body sent within the query - .PARAMETER Method The used method - .PARAMETER Headers Specific headers can be added (no authentication headers will be added if used) - .PARAMETER FixUri -Fixing URI issues - +Fixing URI issues with powershell version 5 and below, when the called URI is not able to make the difference between a "\" related to the URI and a "\" related to a path of an object, but considered as a URI subfolder .PARAMETER Credential Credential object that is passed directly to the Rest method call - - .INPUTS - None - .OUTPUTS - Too many outputs are possible to describe them here. - +.EXAMPLE +# To call the API function "WhoAmi" +PS> Invoke-Conjur -API whoami +.EXAMPLE +# To call the API function "List Resources" of kind "group" +PS> Invoke-Conjur -API resources -command MyOrg -query "kind=group" #> Function Invoke-Conjur { [CmdletBinding()] @@ -85,10 +76,10 @@ Function Invoke-Conjur { $CalledBy = (Get-PSCallStack)[1].command if(!$PsBoundParameters.containskey("Method")) { switch -regex ($CalledBy) { - "^(Remove|Revoke)-" { $method = "DELETE" } - "^(Update)-" { $method = "PATCH" } - "^(Set|add|Grant)-" { $method = "POST" } - "^(New|Submit|Write)-" { $method = "PUT" } + "^(Remove|Revoke)-" { $method = "DELETE" } + "^(Update)-" { $method = "PATCH" } + "^(Set|add|Grant)-" { $method = "POST" } + "^(New|Submit|Write)-" { $method = "PUT" } } } @@ -115,9 +106,9 @@ Function Invoke-Conjur { $RestMethod = @{ - Method = $Method + Method = $Method Headers = $Headers - URI = [uri]$URL + URI = [uri]$URL } if ($PsBoundParameters.containskey("Credential")) { @@ -216,63 +207,41 @@ Export-ModuleMember -Function Invoke-Conjur <# .SYNOPSIS - This command is required prior to running any other one. This will configure the module with the required settings. - .DESCRIPTION - Please check all the parameters in the help file. Mandatory parameters are : Account : Organization account name Credential : Will store the API key that will grant you access to Conjur AuthorityName : DNS authority name of your Conjur instance - - .PARAMETER Account [Mandatory] Will set the Organization account for the repository you are reaching to - .PARAMETER Credential [Mandatory] A Credential object that will be stored in memory containing your API key, that will be used to authenticate your access to Conjur. See the examples below - .PARAMETER AuthnLogin (deprecated | use credential instead) Will set the indentifier of the host API key (requires AuthnApiKey) - .PARAMETER AuthnApiKey (deprecated | use credential instead) Will set the API key of the indentifier (requires AuthnLogin) - .PARAMETER AuthorityName [Mandatory] Will set the name of your conjur instance. Example, if your site is https://eval.conjur.org then you need to set AuthorityName = eval.conjur.org - .PARAMETER AuthorityName_WR In some configurations, you have read only instances of Conjur. By adding this parameter, you will consider the AuthorityName as read only instances, while any modification will call AuthorityName_WR as DNS name - .PARAMETER IamAuthnBranch [AWS IAM integration] This parameter is for Iam authentication plugin, and has not been tested yet - .PARAMETER AWS_MetaData [AWS IAM integration] This parameter is for Iam authentication plugin, and has not been tested yet - .PARAMETER IgnoreSsl This will ignore any SSL issues for all the Conjur queries. - .INPUTS - [PsCredential]Credential. You can set the credentials using a credential object is input - .OUTPUTS - Null - .EXAMPLE - PS> $HostApiIdentifier = "host/some/application" PS> $Cred = (Get-credential -Message "Please enter your Conjur API key" -UserName $ApiIdentifier) PS> Initialize-Conjur -Credential $Cred -Account MyOrg -AuthorityName eval.conjur.org - .EXAMPLE PS> $Cred | Initialize-Conjur -Account MyOrg -AuthorityName readeval.conjur.org -AuthorityName_WR writeeval.conjur.org - - #> Function Initialize-Conjur { [CmdletBinding(DefaultParameterSetName="Credential")] @@ -345,29 +314,17 @@ Export-ModuleMember -Function Initialize-Conjur <# .SYNOPSIS - This command will return you the actual configuration as set in memory. Modifying this variable will modify the Conjur configuration - .DESCRIPTION - Returns the hastable used to configure the Conjur module - - .INPUTS - None. You cannot pipe objects to this function. - - .OUTPUTS - HashTable. The configuration variables for this module - .EXAMPLE - PS> $HostApiIdentifier = "host/some/application" PS> $Cred = (Get-credential -Message "Please enter your Conjur API key" -UserName $ApiIdentifier) PS> Initialize-Conjur -Credential $Cred -Account MyOrg -AuthorityName eval.conjur.org - .EXAMPLE PS> Show-ConjurConfiguration @@ -394,7 +351,6 @@ Export-ModuleMember -Function Show-ConjurConfiguration ############################### # Internal Functions ############################### - Function Get-ResponseBodyFromException { [CmdletBinding()] param( @@ -545,13 +501,13 @@ Function Receive-ConjurIamLogin { $empty_body_hash = "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" - $conjurToken = [pscustomobject]@{ - "host"="$sts_host" - "x-amz-content-sha256"="$empty_body_hash" - "x-amz-date"="$x_amz_date" - "x-amz-security-token"="$x_amz_security_token" - "authorization"="$output" - }|ConvertTo-Json + $conjurToken = [pscustomobject]@{ + "host" = "$sts_host" + "x-amz-content-sha256" = "$empty_body_hash" + "x-amz-date" = "$x_amz_date" + "x-amz-security-token" = "$x_amz_security_token" + "authorization" = "$output" + } | ConvertTo-Json return $conjurToken } @@ -563,39 +519,23 @@ set-alias Get-IamConjurApiKey Receive-ConjurIamLogin <# .SYNOPSIS - Gets the API key of a user given the username and password via HTTP Basic Authentication & Stores the information in memory. - .DESCRIPTION - Passwords are stored in the Conjur database using bcrypt with a work factor of 12. Therefore, login is a fairly expensive operation. However, once the API key is obtained, it may be used to inexpensively obtain access tokens by calling the Authenticate method. An access token is required to use most other parts of the Conjur API. Your HTTP/REST client probably provides HTTP basic authentication support. For example, curl and all of the Conjur client libraries provide this. - .PARAMETER Force Will force to renew the APIKey, even if it has already been stored in memory. - .PARAMETER Silent Will not return the APIKey, but will store it in memory. - .INPUTS - None. You cannot pipe objects to this function. - .OUTPUTS - String. The API key. - .EXAMPLE - PS> $APIKey = Receive-ConjurLogin - - .LINK - https://docs.conjur.org/Latest/en/Content/Developer/Conjur_API_Login.htm - - #> Function Receive-ConjurLogin { [CmdletBinding()] @@ -619,38 +559,21 @@ Export-ModuleMember -Function Receive-ConjurLogin <# .SYNOPSIS - Gets a short-lived access token, which is required in the header of most subsequent API requests. A client can obtain an access token by presenting a valid login name and API key. - - - .DESCRIPTION - The access token is used to communicate to the REST API that the bearer of the token has been authorized to access the API and perform specific actions specified by the scope that was granted during authorization. The login must be URL encoded. For example, alice@devops must be encoded as alice%40devops. For host authentication, the login is the host ID with the prefix host/. For example, the host webserver would login as host/webserver, and would be encoded as host%2Fwebserver. - - .INPUTS - None. You cannot pipe objects to this function. - .OUTPUTS - String. The Authentication Token. - .EXAMPLE - PS> $Token = Receive-ConjurAuthenticate - - .LINK - https://docs.conjur.org/Latest/en/Content/Developer/Conjur_API_Authenticate.htm - - #> Function Receive-ConjurAuthenticate { [CmdletBinding()] @@ -683,36 +606,21 @@ Export-ModuleMember -Function Receive-ConjurAuthenticate <# .SYNOPSIS - The Conjur IAM Authenticator allows an AWS resource to use its AWS IAM role to authenticate with Conjur #### THIS FUNCTION HAS NOT BEEN TESTED - - - .DESCRIPTION - The Conjur IAM Authenticator allows an AWS resource to use its AWS IAM role to authenticate with Conjur. This approach enables EC2 instances and Lambda functions to access credentials stored in Conjur without a pre-configured Conjur identity. To learn more, see IAM roles in the AWS Documentation. To enable an IAM Authenticator, for example, prod, set the following environment variable when you start a Conjur with the [Initialize-Conjur -IamAuthnBranch BranchName] Command - .INPUTS - None. You cannot pipe objects to this function. - .OUTPUTS - To Be completed - .EXAMPLE - To Be Completed - .LINK - https://docs.conjur.org/Latest/en/Content/Operations/Services/AWS_IAM_Authenticator.htm - - #> Function Receive-ConjurIAMAuthenticate { [CmdletBinding()] @@ -729,38 +637,24 @@ Export-ModuleMember -Function Receive-ConjurAuthenticate .SYNOPSIS #### This function has not been tested yet #### Changes a user’s password - .DESCRIPTION - Changes a user’s password. You must provide the login name and current password or API key of the user whose password is to be updated in an HTTP Basic Authentication header. Also replaces the user’s API key with a new securely generated random value. You can fetch the new API key by using Login. Your HTTP/REST client probably provides HTTP basic authentication support. For example, curl and all of the Conjur client libraries provide this. Note : machine roles (Hosts) do not have passwords. They authenticate using their API keys, while passwords are only used by human users. - .PARAMETER Credential The user accout/password - .PARAMETER Password The new password - .INPUTS - None. You cannot pipe objects to this function. - .OUTPUTS - NULL - .EXAMPLE - Not Tested Yet - .LINK - https://docs.conjur.org/Latest/en/Content/Developer/Conjur_API_change_Password.htm - - #> Function New-ConjurUserPassword { # PUT [CmdletBinding()] @@ -781,44 +675,27 @@ Export-ModuleMember -Function New-ConjurUserPassword Rotate Personal API Key Or Replaces the API key of another role that you can update with a new, securely random API key. The new API key is returned as the response body. - - - .DESCRIPTION - Replaces your own API key with a new, securely random API key. The new API key is returned as the response body. For User API key , Any role can rotate its own API key. The name and password or current API key of the role must be provided via HTTP Basic Authorization. Your HTTP/REST client probably provides HTTP - .PARAMETER Credential The Credential object that contains the personal API Key as username and the API Key as password - .PARAMETER Identifier The identifier of the Role - .PARAMETER Kind The Kind API key you want to rotate. Possible values are : user,host,layer,group,policy,variable,webservice Default = host - .INPUTS - None. You cannot pipe objects to this function. - .OUTPUTS - The new personal API Key - .EXAMPLE - Not Tested Yet - .LINK - https://docs.conjur.org/Latest/en/Content/Developer/Conjur_API_Rotate_Personal_API_Key.htm https://docs.conjur.org/Latest/en/Content/Developer/Conjur_API_Rotate_Other_API_Key - - #> Function New-ConjurApiKey { # PUT [CmdletBinding(DefaultParameterSetName="User")] @@ -840,38 +717,25 @@ Function New-ConjurApiKey { # PUT } } Export-ModuleMember -Function New-ConjurApiKey - <# .SYNOPSIS #### This function has not been tested yet #### OIDC Authenticator - .DESCRIPTION Once the OIDC Authenticator is configured, you can send an authentication request. - For more information about the OIDC Authenticator, see OpenID Connect (OIDC) Authenticator. - .PARAMETER serviceid The ID of the OIDC Provider, for example okta - .INPUTS - None. You cannot pipe objects to this function. - .OUTPUTS - String. The Authentication Token. - .EXAMPLE - -PS> $Token = Receive-ConjurOIDCAuthenticator +PS> Receive-ConjurOIDCAuthenticator eyJwcm90ZWN0ZWQiOiJleUpoYkdjaU9pSmpiMjVxZFhJdWIzSm5MM05zYjNOcGJHOHZkaklpTENKcmFXUWlPaUkyTXpka05HWTFZMlU1WVdJd05ESTVOR0ZpWkRNNFptTmhPV00zWW1Nek5qWTVaak16TWprNU5UUXdZamhsTm1ZeU5tRTBNVGM1T0RFeE1HSm1aRGcwSW4wPSIsInBheWxvYWQiOiJleUp6ZFdJaU9pSmhaRzFwYmlJc0ltbGhkQ0k2TVRVNU9EYzJPVFUwTUgwPSIsInNpZ25hdHVyZSI6Ik5ya25FQTc2MnoweC1GVmRRakZHZVRUbkJzeXFBdlBHSWEyZUxZV3IyYVVGZDU5dHk0aGMxSlRsVGptdmpGNWNtVDNMUnFGbDhYYzNwMDhabEhjbVc0cTdiVnFtM21odmZEdVNVaE13RzhKUk4yRFZQVHZKbkFiT1NPX0JGdWhKdmk2OGJEVGxZSFFmUF81WHY1VWtuWHlLUDR2dGNoSjloMHJuVXN0T0F1YWlkM0RyQW5RV1c2dDRaMzRQajJhT2JrTkZ1TlMxNDBsamNwZ1A1dHdfU19ISzB6d1dlSXF4cjh6eUpTbk5aNjJ1WlhZV25zU051WGZtSWdtVVo2cTJFeVZWWUJ1Zk5SZTNVUmFkU09OYjRIcnFyX21UaGctWHUzMjA2N1h3QmNWZ3lWQ0JrcWtybktuRW1vRzlMRWs2ZjdNQVpDX1BXZnA4NXQ1VFFhVm1iZFlqT2lDTW9GMFoxYkhyZGN2MC1LRnpNRGxHa0pCS1Jxb0xYYkFGakhjMCJ9 - .LINK https://docs.conjur.org/Latest/en/Content/Developer/Conjur_API_OIDC_Authenticator.htm - - #> Function Receive-ConjurOIDCAuthenticator { [CmdletBinding()] @@ -914,32 +778,17 @@ Export-ModuleMember -Function Receive-ConjurOIDCAuthenticator <# .SYNOPSIS - WhoAmI provides information about the client making an API request - .DESCRIPTION - It can be used to help troubleshoot configuration by verifying authentication and the client IP address for audit and network access restrictions. For more information, see Host Attributes. - - .INPUTS - None. You cannot pipe objects to this function. - .OUTPUTS - String. The API key. - .EXAMPLE - PS> $APIKey = Receive-ConjurLogin - - .LINK - https://docs.conjur.org/Latest/en/Content/Developer/Conjur_API_Login.htm - - #> Function Get-ConjurWhoAmI { [CmdletBinding()] @@ -954,37 +803,24 @@ Export-ModuleMember -Function Get-ConjurWhoAmI .SYNOPSIS #### This function has not been tested yet #### Get the Authenticator Status - .DESCRIPTION - Once the status webservice has been properly configured and the relevant user groups have been given permissions to access the status webservice, the users in those groups can check the status of the authenticator. - .PARAMETER AuthenticatorType The type of authenticator, for example authn-oidc - .PARAMETER ServiceId The ID of the authenticator provider, for example okta - .INPUTS - None. You cannot pipe objects to this function. - .OUTPUTS - PsObject. The status of the Authenticator - .EXAMPLE - PS> Get-ConjurAuthenticatorStatus authn-oidc okta status ------ ok - .LINK - https://docs.conjur.org/Latest/en/Content/Developer/Conjur_API_authenticator_status.htm - #> Function Get-ConjurAuthenticatorStatus { [CmdletBinding()] @@ -1001,28 +837,22 @@ Export-ModuleMember -Function Get-ConjurAuthenticatorStatus <# .SYNOPSIS Get health of a conjur instance - .DESCRIPTION Get health of a conjur instance - .INPUTS None. You cannot pipe objects to this function. - .OUTPUTS System.Collections.Hashtable. The health of the conjur instance. - .EXAMPLE PS> Get-ConjurHealth -services database ok --------- -------- -- -@{possum=ok; ui=ok; ok=True} @{ok=True; connect=; free_space=; re... True - +services : @{ldap-sync=disabled; possum=ok; ui=ok; ok=True} +database : @{ok=True; connect=; free_space=; replication_status=} +audit : @{ok=True; forwarded=} +ok : True +role : follower .LINK - https://www.conjur.org/api.html#health-get-health - - #> Function Get-ConjurHealth { [CmdletBinding()] @@ -1036,35 +866,25 @@ Export-ModuleMember -Function Get-ConjurHealth .SYNOPSIS #### This function has not been tested yet #### Show Public Keys - .DESCRIPTION Shows all public keys for a resource as newline delimited string for compatibility with the authorized_keys SSH format. Returns an empty string if the resource does not exist, to prevent attackers from determining whether a resource exists. - .PARAMETER Kind kind of resource of which to show public keys. Possible values are : user,host,layer,group,policy,variable,webservice - .PARAMETER identifier The identifier of the object - .INPUTS None. You cannot pipe objects to this function. - .OUTPUTS - System.Collections.Hashtable. The health of the conjur instance. - .EXAMPLE +PS> Get-ConjurPublicKeys -Kind user -identifier alice -PS> Get-ConjurHealth ssh-rsa AAAAB3Nzabc2 admin@alice.com ssh-rsa AAAAB3Nza3nx alice@example.com - .LINK https://docs.conjur.org/Latest/en/Content/Developer/Conjur_API_Show_Public_Keys.htm - - #> Function Get-ConjurPublicKeys { [CmdletBinding()] @@ -1085,55 +905,38 @@ Export-ModuleMember -Function Get-ConjurPublicKeys <# .SYNOPSIS Retrieve one or multiple secrets from conjur - .DESCRIPTION Retrieve one or multiple secret from conjur If one Identifier is selected, the returned object will be the value of the secret If Multiple Identifier, the returned object will a PsObject with all the secrets in a single query - .PARAMETER Identifier The identifier used to retrieve the secret - .PARAMETER Kind The Kind of secret you want to retrieve. Possible values are : user,host,layer,group,policy,variable,webservice Default = variable - .PARAMETER variable_ids List the secrets you want to retrieve in the Comma-delimited resource IDs format - - .INPUTS - None. You cannot pipe objects to this function. - .OUTPUTS - System.String. The secret retrieved. - .EXAMPLE - PS> Get-ConjurSecret -Identifier "path/to/secret/username" -AHfdkrjeb81hs6ah - + AHfdkrjeb81hs6ah .EXAMPLE - PS> Get-ConjurSecret -Identifier "path/to/secret/S1", "path/to/secret/S2" + Account:variable:path/to/secret/S1 Account:variable:path/to/secret/S2 ---------------------------------- ---------------------------------- TestS1 TestS2 - .EXAMPLE - PS> Get-ConjurSecret -variable_ids "Account:variable:path/to/secret/S1", "Account:variable:path/to/secret/S2" + Account:variable:path/to/secret/S1 Account:variable:path/to/secret/S2 ---------------------------------- ---------------------------------- TestS1 TestS2 - - - .LINK - https://docs.conjur.org/Latest/en/Content/Developer/Conjur_API_Retrieve_Secret.htm https://docs.conjur.org/Latest/en/Content/Developer/Conjur_API_Batch_Retrieve.htm #> @@ -1164,36 +967,25 @@ Export-ModuleMember -Function Get-ConjurSecret <# .SYNOPSIS - Get-ConjurSecretCredential is an helper function that will call Get-ConjurSecret and directly retrieve a PsCredential object based on the policy name. - .DESCRIPTION - If you add to a policy 2 secrets, one called username and the other called password, you will be able to use this function. for example, if you have those 2 variables : myhome\subpath\username myhome\subpath\password You will be able to directly retrieve the PsCredential Object using the command [Get-ConjurSecretCredential variable\myhome\subpath] - - .PARAMETER IdentifierPath The path to a pair of username/password couple - .INPUTS None. You cannot pipe objects to this function. - .OUTPUTS PsCredential. The PsCredential object. - .EXAMPLE - PS> Get-ConjurSecretCredential "policy/to/secret" UserName Password -------- -------- TheUserName System.Security.SecureString - - #> Function Get-ConjurSecretCredential { [CmdletBinding()] @@ -1225,40 +1017,25 @@ Export-ModuleMember -Function Get-ConjurSecretCredential <# .SYNOPSIS Set a secret in conjur - .DESCRIPTION Set a secret in conjur Takes a secret identifier and secret value - .PARAMETER Identifier The identifier used to set the secret - .PARAMETER SecretValue The value of the secret - .PARAMETER Kind The Kind of secret you want to retrieve. Possible values are : user,host,layer,group,policy,variable,webservice Default = variable - .INPUTS - None. You cannot pipe objects to this function. - .OUTPUTS - None. - .EXAMPLE - PS> Update-ConjurSecret -Identifier "path/to/secret" -SecretValue "newPasswordHere" - - .LINK - https://www.conjur.org/api.html#secrets-add-a-secret-post - - #> Function Set-ConjurSecret { # POST | Set a Secret [CmdletBinding()] @@ -1280,45 +1057,33 @@ Export-ModuleMember -Function Set-ConjurSecret -Alias Update-ConjurSecret .SYNOPSIS #### This function has not been tested yet #### Modifies an existing Conjur policy - .DESCRIPTION Data may be explicitly deleted using the !delete, !revoke, and !deny statements. Unlike “replace” mode, no data is ever implicitly deleted. - .PARAMETER Identifier The identifier used to update the policy - .PARAMETER PolicyFilePath The YAML policy file path (can not be used with Policy) .PARAMETER Policy The YAML policy (can not be used with PolicyFilePath) - .INPUTS [string]Policy : The Yaml configuration of a Policy - .OUTPUTS None. - .EXAMPLE PS> Get-content .\test-policy.yml | Update-ConjurPolicy -Identifier root created_roles version ------------- ------- @{cucumber:host:database/another-host=} 3 - .EXAMPLE - PS> Update-ConjurPolicy -Identifier root ".\test-policy.yml" created_roles version ------------- ------- @{cucumber:host:database/another-host=} 3 - .LINK - https://docs.conjur.org/Latest/en/Content/Developer/Conjur_API_Update_Policy.htm - - #> Function Update-ConjurPolicy { # PATCH | Update a Policy [CmdletBinding(DefaultParameterSetName="File")] @@ -1327,8 +1092,10 @@ Function Update-ConjurPolicy { # PATCH | Update a Policy [Parameter(Position=1,mandatory=$true,ParameterSetName='File')][string]$PolicyFilePath, [Parameter(Position=1,mandatory=$true,ValueFromPipeline,ParameterSetName='Policy')][string]$Policy ) - if ($PsCmdlet.ParameterSetName -like "File" ) { $Policy = get-content $PolicyFilePath } - return Invoke-Conjur policies !A,policy -Identifier $Identifier -Body $Policy + process { + if ($PsCmdlet.ParameterSetName -like "File" ) { $Policy = get-content $PolicyFilePath } + return Invoke-Conjur policies !A,policy -Identifier $Identifier -Body $Policy + } } Export-ModuleMember -Function Update-ConjurPolicy @@ -1336,50 +1103,32 @@ Export-ModuleMember -Function Update-ConjurPolicy .SYNOPSIS #### This function has not been tested yet #### Loads or replaces a Conjur policy document. - .DESCRIPTION Any policy data which already exists on the server but is not explicitly specified in the new policy file will be deleted. - .PARAMETER Identifier The identifier used to update the policy - - .PARAMETER PolicyFilePath The YAML policy file path (can not be used with Policy) - .PARAMETER Policy The YAML policy (can not be used with PolicyFilePath) - - .INPUTS - None. You cannot pipe objects to this function. - .OUTPUTS - None. - .EXAMPLE - PS> Get-content .\test-policy.yml | Set-ConjurPolicy -Identifier root created_roles version ------------- ------- @{myorg:host:database/db-host=} 1 - .EXAMPLE - PS> Set-ConjurPolicy -Identifier "root" -PolicyFilePath ".\test-policy.yml" created_roles version ------------- ------- @{myorg:host:database/db-host=} 1 - .LINK - https://www.conjur.org/api.html#policies-replace-a-policy - - #> Function Write-ConjurPolicy { # PUT | Replace a Policy [CmdletBinding()] @@ -1388,61 +1137,43 @@ Function Write-ConjurPolicy { # PUT | Replace a Policy [Parameter(Position=1,mandatory=$true,ParameterSetName='File')][string]$PolicyFilePath, [Parameter(Position=1,mandatory=$true,ValueFromPipeline,ParameterSetName='Policy')][string]$Policy ) - if ($PsCmdlet.ParameterSetName -like "File" ) { $Policy = get-content $PolicyFilePath } - return Invoke-Conjur policies !A,policy -Identifier $Identifier -Body $Policy + process { + if ($PsCmdlet.ParameterSetName -like "File" ) { $Policy = get-content $PolicyFilePath } + return Invoke-Conjur policies !A,policy -Identifier $Identifier -Body $Policy + } } New-Alias Replace-ConjurPolicy Write-ConjurPolicy Export-ModuleMember -Function Write-ConjurPolicy -Alias Replace-ConjurPolicy <# .SYNOPSIS - Adds data to the existing Conjur policy. - .DESCRIPTION - Deletions are not allowed. Any policy objects that exist on the server but are omitted from the policy file will not be deleted and any explicit deletions in the policy file will result in an error - .PARAMETER Identifier The identifier used to update the policy - - .PARAMETER PolicyFilePath The YAML policy file path (can not be used with Policy) - .PARAMETER Policy The YAML policy (can not be used with PolicyFilePath) - .INPUTS - None. You cannot pipe objects to this function. - .OUTPUTS - None. - .EXAMPLE - PS> Get-content test-policy.yml | Add-ConjurPolicy root created_roles version ------------- ------- @{cucumber:host:database/new-host=} 2 - .EXAMPLE - PS> Add-ConjurPolicy -Identifier "root" -PolicyFilePath ".\test-policy.yml" created_roles version ------------- ------- @{cucumber:host:database/new-host=} 3 - - .LINK - https://docs.conjur.org/Latest/en/Content/Developer/Conjur_API_Append_Policy.htm - - #> Function Add-ConjurPolicy { # POST | Load a Policy (add) [CmdletBinding()] @@ -1451,8 +1182,10 @@ Function Add-ConjurPolicy { # POST | Load a Policy (add) [Parameter(Position=1,mandatory=$true,ParameterSetName='File')][string]$PolicyFilePath, [Parameter(Position=1,mandatory=$true,ValueFromPipeline,ParameterSetName='Policy')][string]$Policy ) - if ($PsCmdlet.ParameterSetName -like "File" ) { $Policy = get-content $PolicyFilePath } - return Invoke-Conjur policies !A,policy,$Identifier -Body $Policy + process { + if ($PsCmdlet.ParameterSetName -like "File" ) { $Policy = get-content $PolicyFilePath } + return Invoke-Conjur policies !A,policy,$Identifier -Body $Policy + } } New-Alias Append-ConjurPolicy Add-ConjurPolicy Export-ModuleMember -Function Add-ConjurPolicy -Alias Append-ConjurPolicy @@ -1463,7 +1196,6 @@ Export-ModuleMember -Function Add-ConjurPolicy -Alias Append-ConjurPolicy <# .SYNOPSIS List resource within an organization account - .DESCRIPTION If a kind query parameter is given, narrows results to only resources of that kind. @@ -1472,38 +1204,25 @@ If a limit is given, returns no more than that number of results. Providing an o If the parameter count is true, returns only the number of items in the list. If the role or acting_as query parameter is given, then the resource list can be retrieved for a different role (as long as the authenticated role has access). - - - .PARAMETER Kind Filters on the Kinds of resources. Valid Kinds are : user,host,layer,group,policy,variable,webservice - .PARAMETER search search term used to narrow results - .PARAMETER limit maximum number of results to return - .PARAMETER offset number of results to skip - .PARAMETER count if true, return only the number of items in the list - .PARAMETER acting_as The fully qualified identifier for the role whose resource list you want to view. It should be entered as {account}:{kind}:{identifier} where the identifier is URL-encoded. For more information about URL encoding, see URI. Example: cucumber:user:alice - .INPUTS None. You cannot pipe objects to this function. - .OUTPUTS - System.Collections.Hashtable. All the resources the user has access to - .EXAMPLE - PS> Get-ConjurResources created_at : 2019-05-29T16:42:56.284+00:00 @@ -1512,11 +1231,9 @@ owner : dev:user:admin permissions : {} annotations : {} policy_versions : {@{version=1; created_at=2019-05-29T16:42:56.284+00:00; policy_text=--- 4 - - .EXAMPLE - PS> Get-ConjurResources + created_at : 2017-07-25T06:30:38.768+00:00 id : myorg:variable:app-prod/db-password owner : myorg:policy:app-prod @@ -1532,13 +1249,8 @@ policy : myorg:policy:root permissions : {} annotations : {} policy_versions : {} - - .LINK - https://docs.conjur.org/Latest/en/Content/Developer/Conjur_API_List_Resources.htm - - #> Function Get-ConjurResources { [CmdletBinding(DefaultParameterSetName="None")] @@ -1564,22 +1276,16 @@ Export-ModuleMember -Function Get-ConjurResources <# .SYNOPSIS Show a Resource - .DESCRIPTION Show a Resource - .PARAMETER Kind Filters on the Kinds of resources. Valid Kinds are : user,host,layer,group,policy,variable,webservice - .PARAMETER identifier The identifier (path) of the object - .INPUTS None. You cannot pipe objects to this function. - .OUTPUTS PsObject of the resource - .EXAMPLE PS> Get-ConjurResources @@ -1589,8 +1295,6 @@ owner : dev:user:admin permissions : {} annotations : {} policy_versions : {@{version=1; created_at=2019-05-29T16:42:56.284+00:00; policy_text=--- 4 - - .EXAMPLE PS> Get-ConjurResource @@ -1601,12 +1305,8 @@ policy : myorg:policy:root permissions : {} annotations : {} policy_versions : {} - .LINK - https://docs.conjur.org/Latest/en/Content/Developer/Conjur_API_Show_Resources.htm - - #> Function Get-ConjurResource { [CmdletBinding(DefaultParameterSetName="None")] @@ -1624,42 +1324,27 @@ Export-ModuleMember -Function Get-ConjurResource <# .SYNOPSIS Show Permitted Roles - .DESCRIPTION Lists the roles which have the named permission on a resource - .PARAMETER Kind kind of resource requested. Valid Kinds are : user,host,layer,group,policy,variable,webservice - .PARAMETER identifier The identifier of the resource - .PARAMETER privilege roles permitted to exercise this privilege are shown Example: execute - - .INPUTS None. You cannot pipe objects to this function. - .OUTPUTS - PsObject - - .EXAMPLE - PS> Get-ConjurPermittedRoles variable db execute myorg:policy:database myorg:user:db-admin myorg:host:database/db-host - .LINK - https://docs.conjur.org/Latest/en/Content/Developer/Conjur_API_Show_Permitted_Roles.htm - - #> Function Get-ConjurPermittedRoles { [CmdletBinding(DefaultParameterSetName="None")] @@ -1678,41 +1363,24 @@ Export-ModuleMember -Function Get-ConjurPermittedRoles <# .SYNOPSIS Check Permission - .DESCRIPTION Checks whether a role has a privilege on a resource. For example, is this Host authorized to execute (fetch the value of) this Secret? - .PARAMETER Kind kind of resource requested. Valid Kinds are : user,host,layer,group,policy,variable,webservice - .PARAMETER identifier The identifier of the resource (Example : db ) - .PARAMETER privilege the fully qualified identifier of the role to test (Example: myorg:host:application) - .PARAMETER privilege roles permitted to exercise this privilege are shown (Example: execute) - - .INPUTS None. You cannot pipe objects to this function. - .OUTPUTS - PsObject - - .EXAMPLE - PS> Test-ConjurPermission variable db "myorg:host:application" execute - - .LINK - https://docs.conjur.org/Latest/en/Content/Developer/Conjur_API_Check_Permission.htm - - #> Function Test-ConjurPermission { [CmdletBinding(DefaultParameterSetName="None")] @@ -1737,23 +1405,17 @@ Export-ModuleMember -Function Test-ConjurPermission <# .SYNOPSIS Gets detailed information about a specific role, including the role members. - .DESCRIPTION If a role A is granted to a role B, then role A is said to have role B as a member. These relationships are described in the “members” portion of the returned JSON - .PARAMETER kind [Mandatory] The Kind of role. Possible values are : user,host,layer,group,policy - .PARAMETER identifier [Mandatory] The identifier of the Role - .INPUTS None. You cannot pipe objects to this function. - .OUTPUTS PsObject. All the resources the user has access to - .EXAMPLE PS> Get-ConjurRole user alice @@ -1761,9 +1423,7 @@ created_at : 2017-08-02T18:18:42.346+00:00 id : myorg:user:alice policy : myorg:policy:root members : {@{admin_option=True; ownership=True; role=myorg:user:alice; member=myorg:policy:root; policy=myorg:policy:root}} - .LINK - https://docs.conjur.org/Latest/en/Content/Developer/Conjur_API_Show_Role.htm #> Function Get-ConjurRole { @@ -1780,7 +1440,6 @@ Export-ModuleMember -Function Get-ConjurRole <# .SYNOPSIS List a Role's Members - .DESCRIPTION List members within a role. @@ -1793,26 +1452,18 @@ If the parameter count is true, the number of items in the list are returned. Text search If the search parameter is provided, the results are narrowed to those pertaining to the search query. Search works across resource IDs and the values of annotations. It weighs results so that those with matching id or a matching value of an annotation called name appear first, then those with another matching annotation value, and finally those with a matching kind. - - .PARAMETER search Search string - .PARAMETER kind kind of role requested - .PARAMETER limit maximum number of results to return - .PARAMETER offset number of results to skip - .INPUTS None. You cannot pipe objects to this function. - .OUTPUTS PsObject - .EXAMPLE PS> Get-ConjurRoleMember devs @@ -1833,9 +1484,7 @@ ownership : False role : myorg:group:devs member : myorg:user:bob policy : myorg:policy:root - .LINK - https://docs.conjur.org/Latest/en/Content/Developer/Conjur_API_List_Role_Members.htm #> Function Get-ConjurRoleMember { @@ -1854,7 +1503,6 @@ Export-ModuleMember -Function Get-ConjurRoleMember <# .SYNOPSIS List a Role's Memberships - .DESCRIPTION Allows you to view the memberships of a role, including a list of groups of which a specific host or user is a member. @@ -1863,26 +1511,19 @@ If a kind query parameter is used, the results are narrowed to only resources of If a limit is provided, the results return up to the number specified. Providing an offset skips a number of resources before returning the rest. In addition, providing an offset gives limit a default value of 10 if no other limit is provided. These two parameters can be combined to page through results. If the parameter count is true, the number of items in the list are returned. - .PARAMETER identifier [Mandatory] identifier of the role - .PARAMETER kind [Mandatory] kind of role requested Possible values are : user,host,layer,group,policy - .PARAMETER limit maximum number of results to return - .PARAMETER offset number of results to skip - .INPUTS None. You cannot pipe objects to this function. - .OUTPUTS PsObject - .EXAMPLE PS> Get-ConjurRoleMemberships devs @@ -1891,9 +1532,7 @@ ownership : False role : myorg:group:devs member : myorg:user:alice policy : myorg:policy:root - .LINK - https://docs.conjur.org/Latest/en/Content/Developer/Conjur_API_Show_Role.htm #> Function Get-ConjurRoleMemberships { @@ -1916,30 +1555,22 @@ Export-ModuleMember -Function Get-ConjurRoleMemberships .SYNOPSIS #### This function has not been tested yet #### Creates one or more tokens which can be used to bootstrap host identity - .DESCRIPTION Creates one or more tokens which can be used to bootstrap host identity. Responds with a JSON document containing the tokens and their restrictions. If the tokens are created with a CIDR restriction, Conjur will only accept them from the allowlisted IP ranges. - .PARAMETER expiration [Mandatory] Expiration date of the token - .PARAMETER host_factory [Mandatory] Fully qualified Host Factory id - .PARAMETER count Number of tokens to create - .PARAMETER cidr CIDR restriction(s) on token usage - .INPUTS None. You cannot pipe objects to this function. - .OUTPUTS PsObject - .EXAMPLE PS> Grant-ConjurNewToken devs @@ -1947,10 +1578,7 @@ expiration cidr token ---------- ---- ----- 8/5/2017 12:27:20 AM {127.0.0.1/32, 127.0.0.2/32} 281s2ag1g8s7gd2ezf6td3d619b52t9gaak3w8rj0p38124n384sq7x 8/5/2017 12:27:20 AM {127.0.0.1/32, 127.0.0.2/32} 2c0vfj61pmah3efbgpcz2x9vzcy1ycskfkyqy0kgk1fv014880f4 - - .LINK - https://docs.conjur.org/Latest/en/Content/Developer/Conjur_API_Create_Tokens.htm #> Function Grant-ConjurNewToken { @@ -1977,27 +1605,19 @@ Export-ModuleMember -Function Grant-ConjurNewToken .SYNOPSIS #### This function has not been tested yet #### Revoke Tokens - .DESCRIPTION Revokes a token, immediately disabling it. If the tokens are created with a CIDR restriction, Conjur will only accept them from the allowlisted IP ranges. - .PARAMETER token [Mandatory] Token you want to revoke. - .INPUTS None. You cannot pipe objects to this function. - .OUTPUTS None - .EXAMPLE PS> Revoke-ConjurNewToken 281s2ag1g8s7gd2ezf6td3d619b52t9gaak3w8rj0p38124n384sq7x - - .LINK - https://docs.conjur.org/Latest/en/Content/Developer/Conjur_API_Revoke_Tokens.htm #> Function Revoke-ConjurToken { @@ -2016,24 +1636,18 @@ Export-ModuleMember -Function Revoke-ConjurToken .SYNOPSIS #### This function has not been tested yet #### Create a Host - .DESCRIPTION Creates a Host using the Host Factory and returns a JSON description of it. Requires a Host Factory Token, which can be created using the Create Tokens API. In practice, this token is usually provided automatically as part of Conjur integration with your host provisioning infrastructure. - .PARAMETER id Identifier of the Host to be created. It will be created within the account of the Host Factory. (Example: brand-new-host) - .PARAMETER annotations Json Annotations to apply to the new Host (Example: {"puppet": "true", "description": "new db host"}) - .INPUTS None. You cannot pipe objects to this function. - .OUTPUTS None - .EXAMPLE PS> Add-ConjurHost -id brand-new-host @@ -2043,9 +1657,7 @@ owner : myorg:host_factory:hf-db permissions : {} annotations : {} api_key : rq5bk73nwjnm52zdj87993ezmvx3m75k3whwxszekvmnwdqek0r - .LINK - https://docs.conjur.org/Latest/en/Content/Developer/Conjur_API_Create_Host.htm #> Function Add-ConjurHost {