I have a pipeline where I run the AzurePowerShell@5 task. The pipeline runs a separate powershell script like this:
- task: AzurePowerShell@5
displayName: "PowerShell Script"
inputs:
azureSubscription: "Platform - Management"
ScriptType: "filePath"
ScriptPath: ./post_migration/post-migration.ps1
ScriptArguments: "-SubscriptionId ${env:SUBSCRIPTIONID} -ResourceGroup ${env:RESOURCEGROUP} -VmName ${env:VMNAME} -Username ${env:USERNAME} -Password ${env:PWD}"
azurePowerShellVersion: "LatestVersion"
env:
PWD: $(Password)
The variable Password is marked as "Keep this value secret". The reason to do like this is that we need to be able to set different values on the variables every time.
The param block for the variable $Password in the powershell script looks like this:
[Parameter(Mandatory = $true)]
[ValidateNotNullOrEmpty()]
[SecureString]$Password
When I run the pipeline i get this error message:
Cannot process argument transformation on parameter 'Password'. Cannot convert the "***" value of type "System.String" to type "System.Security.SecureString".
All other variables seem to work fine, but not the secret. Any suggestion about what I'm doing wrong?
The secret is passed as cleartext in the environment, not as a SecureString
. There is no way to pass the secret from the agent to the script in encrypted/protected form.
You can probably cheat a little:
-Password $(ConvertTo-SecureString $env:PWD -AsPlainText -Force)
That will take the insecure value from the environment, then convert it before passing it into your script.
⚠️ Just understand, this isn't in any way more secure, since the value won't be encrypted and it will be passed plaintext in memory. But it will allow you to call a script that expects a secure string.
The agent's "keep secure" checkbox on variables does a few things, but not what you're expecting:
Variables marked as secure aren't automatically available to scripts - Unlike other variables which are set as an environment variable by default, secure variables need to be explicitly passed in through the env:
section or inlined in an input using the $(...)
or ${{ ... }}
or $[ ... ]` syntax:
- pwsh: |
echo $(SECRET)
- pwsh: |
echo ${{ variables.SECRET }}
- pwsh: |
echo $[ variables.SECRET ]
- pwsh: |
echo $env:SECRET
env:
SECRET: $(SECRET)
- task: PowerShell@2:
inputs:
scriptArguments: $(SECRET) ${{ variables.SECRET }} $[ variables.SECRET ] $env:SECRET
env:
SECRET: $(SECRET)
Variables marked as secure are scrubbed from the logs - The primary purpose of marking a string as secure is to tell the agent to not accidentally expose the value through the logs. So every time a secret is written to Standard Out/Error the value is replaced by ***
, the same is done in the deug logs that are written to the agent's disk.
Secrets can't be passed to another job through output variables. - The agent will try to detect when a secret is passed to an output variable and block this. This prevents the secret from being logged in the initialization phase of the next job, since output variables don't carry the secret-true
flag unfortunately.
What secrets do not do:
SecureString
at all times. When you explicitly pass a secret to a step, it's passed in as plain text. This is due to the fact that there is no equivalent of SecureString
that will work everywhere.If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With