Azure Bicep is rapidly gaining popularity and is increasingly seen as a replacement for ARM templates. In this article, I will discuss some essential security practices when using Bicep.

If you are unfamiliar with Bicep, I recommend referring to the Microsoft Learn Documentation for more information.

Avoid Including Secrets in Source Control

It is crucial to keep secrets out of source control, as they can easily be accidentally committed when testing Bicep configurations locally. Here are some ways to prevent this:

  • Pass parameters via the command line.
  • Utilize a parameters JSON file that is ignored by source control. For example, add it to your .gitignore file if you are using Git.

Secure Input Parameters

While passing parameters from external sources, it is important to ensure that secrets remain secure and are not exposed in outputs. Bicep provides an “@secure” decorator for String and Object type parameters to address this concern. For example:

@secure()
param adminPassword string

@secure()
param adminCredentials object

Be Mindful of Outputs

Adding outputs to Bicep modules can be beneficial, but it is important to be aware of potential security risks. If an output appears to contain a secret value, Bicep will issue a warning about potentially exposing secrets.

For example, the following output for a connection string to a Storage Account would trigger such a warning:

output connectionString = 'DefaultEndpointsProtocol=https;AccountName=${storageaccount.name};EndpointSuffix=${environment().suffixes.storage};AccountKey=${listKeys(storageaccount.id, storageaccount.apiVersion).keys[0].value}'

However, if the value is assigned to a variable before being used in the output, no warning will be shown, making it easy to overlook:

var connectionString = 'DefaultEndpointsProtocol=https;AccountName=${storageaccount.name};EndpointSuffix=${environment().suffixes.storage};AccountKey=${listKeys(storageaccount.id, storageaccount.apiVersion).keys[0].value}'
output connectionString = connectionString

Exercise Caution with Output Values

When deploying a storage account resource to Azure using Bicep, the defined outputs can be viewed in the Deployments section of the resource group. It’s important to note that these outputs, including the account key, are displayed in plain text.

To maintain a good security posture, it is recommended not to return secrets as outputs in Bicep. Hopefully, Bicep will support the use of the “@secure” decorator for outputs in the future to ensure the safe handling of secrets.

Handling Secrets between Modules

If returning secrets from Bicep is a concern, there are alternative methods for sharing secrets between modules. One option is to access an existing resource using the “existing” keyword. For example:

param storageName string

resource storageaccount 'Microsoft.Storage/storageAccounts@2022-05-01' existing = {
  name: storageName  
}

var connectionString = 'DefaultEndpointsProtocol=https;AccountName=${storageName};EndpointSuffix=${environment().suffixes.storage};AccountKey=${listKeys(storageaccount.id, storageaccount.apiVersion).keys[0].value}'

This way, the connection string can be used as input for another resource.

Utilizing Key Vault for Secrets

In addition to accessing existing resources, Bicep also supports retrieving secrets from a Key Vault. The “existing” keyword is used in a similar manner, but the “getSecret” method can only be used when assigning to a module parameter with the “@secure” decorator.

IaC Scanning with Bicep

Scanning Infrastructure as Code (IaC) for security issues is becoming increasingly popular. While direct support for Bicep in scanning tools may be limited, it is possible to scan the underlying ARM templates generated by Bicep.

Tools like Snyk offer a free CLI that can perform IaC scans locally against security and compliance standards. By installing the Bicep CLI and the Snyk CLI, you can compile Bicep to ARM format and then run the Snyk scan.

Final Remarks

Security is an ongoing concern that requires constant attention. By adopting good security practices and staying informed, we can better protect our Azure resources. I hope this article has provided valuable insights and guidance on securing your Bicep configurations.

Leave a Reply

Your email address will not be published. Required fields are marked *