Skip to content

Commit

Permalink
Fix to support @secure() values in Bicep (#25586)
Browse files Browse the repository at this point in the history
  • Loading branch information
anthony-c-martin authored Jul 24, 2024
1 parent a69f35c commit 5eb3173
Show file tree
Hide file tree
Showing 7 changed files with 210 additions and 116 deletions.
24 changes: 21 additions & 3 deletions src/Resources/ResourceManager/Json/PSJsonSerializer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,9 @@
using System.Management.Automation.Internal;
using System.Management.Automation.Language;
using System.Reflection;
using System.Security;
using Microsoft.Azure.Commands.ResourceManager.Cmdlets.Extensions;
using Microsoft.WindowsAzure.Commands.Common;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;

Expand All @@ -31,17 +33,20 @@ public static class PSJsonSerializer
{
public struct SerializeContext
{
public SerializeContext(int maxDepth)
public SerializeContext(int maxDepth, bool serializeSecureString)
{
this.MaxDepth = maxDepth;
this.SerializeSecureString = serializeSecureString;
}

public int MaxDepth { get; }

public bool SerializeSecureString { get; }
}

public static string Serialize(object value)
public static string Serialize(object value, bool serializeSecureString = false)
{
var context = new SerializeContext(1024);
var context = new SerializeContext(1024, serializeSecureString);

return Serialize(value, context);
}
Expand Down Expand Up @@ -77,6 +82,19 @@ private static object ProcessValue(object value, int currentDepth, SerializeCont
value = psObject.BaseObject;
}

if (value is SecureString secureString)
{
// This requires a conscious opt-in, rather than being the default behavior - to avoid accidentally leaking sensitive information.
if (context.SerializeSecureString)
{
return secureString.ConvertToString();
}
else
{
throw new InvalidOperationException("Unable to serialize secure string value");
}
}

if (value == NullString.Value || value == DBNull.Value)
{
return null;
Expand Down
3 changes: 2 additions & 1 deletion src/Resources/ResourceManager/Utilities/BicepUtility.cs
Original file line number Diff line number Diff line change
Expand Up @@ -128,7 +128,8 @@ public BicepBuildParamsStdout BuildBicepParamFile(string bicepParamFilePath, IRe
{
CheckMinimalVersionRequirement(MinimalVersionRequirementForBicepparamFileBuildWithInlineOverrides);
writeVerbose?.Invoke($"Overriding the following parameters: {string.Join(", ", overrideParams.Keys)}");
envVars["BICEP_PARAMETERS_OVERRIDES"] = PSJsonSerializer.Serialize(overrideParams);
// As per https://github.com/Azure/bicep/issues/12481, secure string parameters must be serialized.
envVars["BICEP_PARAMETERS_OVERRIDES"] = PSJsonSerializer.Serialize(overrideParams, serializeSecureString: true);
}

var stdout = RunBicepCommand(
Expand Down
10 changes: 8 additions & 2 deletions src/Resources/Resources.Test/ScenarioTests/DeploymentTests.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -976,7 +976,8 @@ function Test-NewDeploymentFromBicepparamFileWithOverrides
"def": "ghi"
},
"int": 42,
"bool": true
"bool": true,
"secureString": "glabble"
}
'@ | ConvertFrom-Json

Expand All @@ -986,7 +987,12 @@ function Test-NewDeploymentFromBicepparamFileWithOverrides
New-AzResourceGroup -Name $rgname -Location $rglocation

$deployment = New-AzResourceGroupDeployment -Name $rname -ResourceGroupName $rgname -TemplateParameterFile deployWithParamOverrides.bicepparam `
-myArray @("abc") -myObject @{"def" = "ghi";} -myString "hello" -myInt 42 -myBool $true
-myArray @("abc") `
-myObject @{"def" = "ghi";} `
-myString "hello" `
-myInt 42 `
-myBool $true `
-mySecureString (ConvertTo-SecureString -String "glabble" -AsPlainText -Force)

# Assert
Assert-AreEqual Succeeded $deployment.ProvisioningState
Expand Down

Large diffs are not rendered by default.

4 changes: 4 additions & 0 deletions src/Resources/Resources.Test/deployWithParamOverrides.bicep
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,15 @@ param myString string
param myObject object
param myInt int
param myBool bool
@secure()
param mySecureString string

output all object = {
array: myArray
string: myString
object: myObject
int: myInt
bool: myBool
#disable-next-line outputs-should-not-contain-secrets
secureString: mySecureString
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,3 +5,4 @@ param myObject = {}
param myString = ''
param myInt = 0
param myBool = false
param mySecureString = ''
1 change: 1 addition & 0 deletions src/Resources/Resources/ChangeLog.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
-->

## Upcoming Release
* Fixed overriding of Bicep parameters in Deployment cmdlets to support `SecureString` parameters.
* Added Test cmdlets for Deployment Stacks.

## Version 7.2.0
Expand Down

0 comments on commit 5eb3173

Please sign in to comment.