Open Kittoes0124 opened 1 year ago
The prohibition on using @secure()
on a type
statement was lifted in #10669, which will be part of Bicep 0.19. Allowing @secure()
on types opened up some holes in the static analysis done by the linter, so we wanted to disarm any potential footguns until the relevant linter rules were updated.
As far as defining a type and then making a usage thereof @secure()
: that is unlikely to be supported due to a limitation in the ARM intermediate language. If the propertiesInfo
type from your screenshot isn't reused, you can define it in the param
statement instead:
@secure()
param properties {
foo: string?
} = {}
In the next release, you will also be able to define a type as secure and then use it in param
statement:
@secure()
type propertiesType = {
foo: string?
}
param properties propertiesType = {}
Something like the following example is not working with AZ Powershell New-AzResourceGroupDeployment
.
type propertiesType = {
@secure()
foo: string
}
When the args are passed to bicep the following message is thrown:
InvalidTemplate - Deployment template validation failed: 'The provided value for the template parameter 'adminPassword' is not valid. Expected a value of type 'String, Uri', but received a value of type 'Object'. Please see https://aka.ms/arm-create-parameter-file for usage details.'.
As a workaround, I had to default to the default param
.
@rmjoia How is the adminPassword
parameter declared, and what value is passed to it?
It's a regular secure string passed from the az powershell command mentioned, something along the lines of
Powershell File
$templateFile = Join-Path $PSScriptRoot -ChildPath "infrastructure.bicep"
$adminUsername = "adminUsername" | ConvertTo-SecureString -AsPlainText
$adminPassword = ".$.S0M3R4nD0MPwd#%" | ConvertTo-SecureString -AsPlainText
$virtualMachine = @{
Name = 'VMName'
AdminUsername = $adminUsername
AdminPassword = $adminPassword
VmSize = 'Standard_E8_v5'
}
New-AzResourceGroupDeployment -Mode Incremental `
-TemplateFile $templateFile `
-Vm $virtualMachine `
Bicep file
type vmSize = 'Standard_E8_v5' | 'Standard_E8s_v5' | 'Standard_E16_v5' | 'Standard_E16s_v5' | 'Standard_E32_v5' | 'Standard_E32s_v5'
type virtualMachine = {
name: string
@secure()
adminUsername: string
@secure()
adminPassword: string
vmSize: vmSize
}
param vm virtualMachine
module resourceVMs 'module.bicep' = [for vm in vms: {
name: vm.name
params: {
location: location
adminUsername: vm.adminUsername
adminPassword: vm.adminPassword
vmSize: vm.vmSize
}
}]
Something like this... I had to cut some bits and pieces for brevity and to remove the specifics of the project...
It's something related with the datatype. if it's a string works fine.. it can't be a secureString
else it throws the error.
I was also glancing the PR mentioned above, and it seems that only addresses (I may be wrong) the output of secrets to the terminal.
The test cases only cover scenarios where the @secure
decorator is used on param obj
and not for user-defined typed properties, such as the case above.
Anyways, I tried also to decorate the whole type as @secure
but didn't work either, same error...
I also tried to create a Powershell class object (strong typed) instead of the dynamic PSO... to force it.. same result.
@rmjoia I believe the error you're seeing is caused by how the Az powershell module is serializing aggregate values:
Would you mind if I move this discussion to a separate issue? This is not related to the feature request by @Kittoes0124
Sure, please do.
Thank you
Did you find a resolution to this? We are having the same issue.
Did you find a resolution to this? We are having the same issue.
No, the issue seems to be indeed powershell serialisation.
My team decided not to use user defined types and we're passing the secure strings separately as parameters...
@teeekzy / @rmjoia -- just FWIW, per this comment, the .NET (and correspondingly PowerShell) team does not recommend using SecureString.
Thank you Alex. It's not a want, it's a need... but if the team has a better way to pass secrets as params to bicep without the risk of exposing them I'm interested to learn.
Cheers
On Tue 26 Mar 2024, 14:24 Alex Frankel, @.***> wrote:
@Teeekzy https://github.com/Teeekzy / @rmjoia https://github.com/rmjoia -- just FWIW, per this comment https://github.com/Azure/bicep/issues/12481#issuecomment-1845818213, the .NET (and correspondingly PowerShell) team does not recommend using SecureString.
— Reply to this email directly, view it on GitHub https://github.com/Azure/bicep/issues/11082#issuecomment-2020572858, or unsubscribe https://github.com/notifications/unsubscribe-auth/ABXTC3GQRW2GD4DLONGOQWDY2GAJXAVCNFSM6AAAAAAZUWFCIWVHI2DSMVQWIX3LMV43OSLTON2WKQ3PNVWWK3TUHMZDAMRQGU3TEOBVHA . You are receiving this because you were mentioned.Message ID: @.***>
This is independent of bicep. The right way to pass a secret to a bicep deployment is using @secure()
parameters. That parameter can be provided on the command line or via a parameter file either using a key-vault reference or passing via an environment.
As I understand the issue you are facing is that using SecureString in powershell is causing some sort of serialization issue, but the .NET time recommends not using the type. Reading this page closer, my read is that it is essentially giving you a false sense of security: https://github.com/dotnet/platform-compat/blob/master/docs/DE0001.md
hey @alex-frankel, first of all, I would like to thank you for your time and support.
I agree with all that, I also know that SecureStrings don't exist as OS Concept.. but they exist as a powershell one :) Actually, even though it might not be reccomended now, I used it on .net Framework on many occasions in the past.
The issue arises when using Powershell (Az CLI) to provision resources in Azure and trying to use bicep, hence why I raised the issue here. As mentioned before following the thread, the issue was closed because this was a Powershell Serialization issue and indeed, regardless if I'm using user defined types or just PowerShell Objects... the error is the same.
However, regardless of the .Net Core team saying it shouldn't be used and it's not reccomended when porting to .Net Core... I'm (we're) not porting anything to .Net Core...
We're using the "vanilla" Az CLI, with Powershell Core and Bicep... and this is a valid (and supported to some extent) concept.
PowerShell has tools to convert strings to SecureString and Vice-Versa, so, I would say it's a valid concept on that domain.
Also, we can pass SecureString's as Params perfectly from PowerShell to Bicep, and Bicep handles them like a pro! The issue is when the secureString is on User Defined Types or PSOs..
That said, even though the argument that it shouldn't be used in .net core (.Net 5+) is valid, has nothing to do with what we're doing here, and until there's a better way to do it, people will have to use it, because it's the only way (as far as I know) to pass secrets from powershell to bicep without exposing their values.
One can argue that you shouldn't pass secrets as args, you can access an existing azure kv and retrieve the secret directly on bicep.. and that might be the "best practice" however, while PowerShell supports using, generating, etc.. SecureStrings, people will keep using it.
Seems that there is a misaligment between the PowerShell team and the .Net Core... because... if we're not supposed to use it, PowerShell should remove it's support for it and update the documentation accordingly...
This is not about security, it's just that, PowerShell doesn't output the values of SecureStrings, they are masked/removed on output.. I think I read that somewhere on this repo.. there's a rule to don't output SecureStrings...
I hope this makes sense. I'm very appreciated for your help and attention, but I think we're talking about different things.
Thanks for the extra clarification. I discussed with the PowerShell team their current stance on supporting SecureString and given they support it, I've reopened #12481. Sorry for the spam on this issue as it is unrelated to the recent discussion, but wanted to close the loop here.
This is not about security, it's just that, PowerShell doesn't output the values of SecureStrings, they are masked/removed on output.. I think I read that somewhere on this repo.. there's a rule to don't output SecureStrings...
Could you clarify this a bit? There are SecureStrings in PowerShell (ConvertTo-SecureString $str -AsPlainText
) and there are SecureStrings in ARM/Bicep (@secure() param adminUsername string
), but they are not related despite having the same name. PowerShell will prevent its SecureStrings from being output to the screen if you reference the value (> Write-Host $aSecureValue
). ARM will prevent values with a type of secureString
or secureObject
from being included in API responses. Which kind of output are you looking to prevent?
This is not about preventing output. That part is already working fine.
The issue is that passing secureString from powerShell to bicep only work as arguments to powershell functions.
If you use a PSObject, or a bicep user defined type, there will be a parsing error.
Apparently that was suggested as an issue on the way Powershell parses the SecureString.
Bicep version Bicep CLI version 0.18.4 (1620479ac6)
Describe the bug User defined types are unable to be defined as secure parameters.
To Reproduce