Use the Conformity Knowledge Base AI to help improve your Cloud Posture

Use Key Vaults to Store App Service Application Secrets

Trend Cloud One™ – Conformity is a continuous assurance tool that provides peace of mind for your cloud infrastructure, delivering over 1000 automated best practice checks.

Risk Level: Medium (should be achieved)
Rule ID: AppService-018

Enable working with secrets from the Azure Key Vaults within your App Service applications without requiring any code changes. Azure Key Vault is a cloud service that provides centralized secrets management with full control over access policies and audit history.

This rule resolution is part of the Conformity Security & Compliance tool for Azure.

Security

To maintain the security of the secrets used by your Microsoft Azure App Service applications, it is highly recommended to store them in an Azure Key Vault and reference them from that key vault. Storing these secrets externally and referencing them in the application configuration also enables key rotation without having to redeploy the app service.


Audit

To determine if the Azure Key Vaults are used to store App Services application secrets, perform the following actions:

Using Azure Portal

01 Sign in to the Azure Management Console.

02 Navigate to App Services blade at https://portal.azure.com/#blade/HubsExtension/BrowseResourceBlade/resourceType/Microsoft.Web%2Fsites.

03 Click on the name (link) of the App Services application that you want to examine.

04 In the blade navigation panel, under Settings, choose Configuration and select the Application settings tab to access the settings available for the selected application.

05 Check the names of the application settings to determine if any of the defined settings should be stored as secrets. To ensure the Conformity rule is able to check the appropriate application settings, save rule configuration settings to check string names using either exact or partial match.

06 In the Azure portal under the Application settings section, check the Source column for each application setting defined. If there are no application settings with the Source set to Key vault Reference (displaying a green 'tick'), the Azure Key Vault service is not used to store secrets for the selected Microsoft Azure App Services application. If your App Services application already has a secret partially configured, where the Key vault Reference is displayed with a red 'x', the application setting indicates that there is a misconfiguration with the access.

07 Check the Value column for each application setting defined. If there is no application setting with the Value set to @Microsoft.KeyVault(SecretUri=https://<key-vault-name>.vault.azure.net/secrets/<secret-name>/) or @Microsoft.KeyVault(VaultName=<key-vault-name>;SecretName=<secret-name>), where <key-vault-name> is the name of your key vault and the <secret-name> is the name of the secret used, the Azure Key Vault service is not used to store secrets for the selected Microsoft Azure App Services application.

08 In the blade navigation panel, under Settings, choose Identity, and select the System assigned tab. If the Status is set to Off, there is no system assigned identity set for your application. Because Azure Key Vault access policies rely on assigning a Principal to grant access, if there is no system assigned identity set for your application, the relevant Key Vault access policy can't have the Principal correctly defined.

09 To check the Key Vault configuration, navigate to the Key Vaults blade at https://portal.azure.com/#blade/HubsExtension/BrowseResource/resourceType/Microsoft.KeyVault%2Fvaults and click on the name of the Azure Key Vault that should host the intended secret. If there are no Key Vault available in your subscription, the Audit process ends here, otherwise continue the process with the next step.

10 In the blade navigation panel, under Settings, choose Secrets and click on the name of the secret that should be configured for your application. If there is no relevant secret defined, the Audit process stops here.

11 Return to the Key Vault navigation panel, and under Settings, choose Access policies. In the Current Access Policies section, under APPLICATION, check the Name and the Secret Permissions values available for the list of policies defined. If there are no policies that match the name of your chosen application, or don't have the correct Secret Permissions of Get, List and Set, the selected Key Vault is not properly configured to allow your application to access the secret.

12 Repeat steps no. 3 – 11 for each Azure App Services application available within the current subscription.

13 Repeat steps no. 3 – 12 for other subscriptions created in your Microsoft Azure cloud account.

Using Azure CLI

01 Run webapp list command (Windows/macOS/Linux) with custom query filters to list the name of each App Services application (and the name of its associated resource group) deployed in the current Azure subscription:

az webapp list
  --output table
  --query '[*].{name:name, resourceGroup:resourceGroup}'

02 The command output should return a table with requested information:

Name ResourceGroup
------------------- ------------------------------
cc-project5-webapp  cloud-shell-storage-westeurope
cc-node10-prod-app  cloud-shell-storage-westeurope

03 Run webapp config appsettings list command (Windows/macOS/Linux) using the name of the application that you want to examine as the identifier parameter, to describe the application settings defined for the selected App Services application:

az webapp config appsettings list
  --name cc-project5-webapp
  --resource-group cloud-shell-storage-westeurope

04 The command output should return the name and the value of each application setting defined:

[
  {
    "name": "APPINSIGHTS_INSTRUMENTATIONKEY",
    "slotSetting": false,
    "value": "1234abcd-1234-abcd-1234-abcd1234abcd"
  },
  {
    "name": "APPLICATIONINSIGHTS_CONNECTION_STRING",
    "slotSetting": false,
    "value":
    "InstrumentationKey=1234abcd-1234-abcd-1234-abcd1234abcd;IngestionEndpoint=https://westeurope-5.in.applicationinsights.azure.com/"
  },
  {
    "name": "ApplicationInsightsAgent_EXTENSION_VERSION",
    "slotSetting": false,
    "value": "~2"
  },
  {
    "name": "XDT_MicrosoftApplicationInsights_Mode",
    "slotSetting": false,
    "value": "default"
  }
]

Check the "name" attribute to determine if the application setting is one that should be stored as a secret. You can ensure the Conformity rule cross-checks the appropriate settings via the rule configuration section within the Conformity application. From the CLI response, check the "value" attribute value defined for each application setting returned by the webapp config appsettings list command output. If none of the application settings have their value set to @Microsoft.KeyVault(SecretUri=https:// <key-vault-name>.vault.azure.net/secrets/<secret-name>/) or @Microsoft.KeyVault(VaultName=<key-vault-name>;SecretName= <secret-name>), where <key-vault-name> is the name of your key vault and the <secret-name> is the name of the secret used, the Azure Key Vault service is not used to store secrets for the selected Microsoft Azure App Services application.

05 Run webapp identity show command (Windows/macOS/Linux) using the name of the App Services application that you want to examine as the identifier parameter:

az webapp identity show
  --name cc-project5-webapp
  --resource-group cloud-shell-storage-westeurope

06 The webapp identity show command should return one of the following outputs:

  1. If the command does not produce an output, there is no system assigned identity defined, therefore it will not be possible for the Key Vault access policy to define the application as a Principal. This means that the desired secret can’t be used for the selected application and the Audit process ends here.
  2. If the command output returns the "principalId" property and the "type" property is set to "SystemAssigned", as shown in the example below, continue the Audit process with the next step:
    {
      "principalId": "abcd1234-1234-1234-1234-abcd1234abcd",
      "tenantId": "1234abcd-1234-1234-1234-1234abcd1234",
      "type": "SystemAssigned",
      "userAssignedIdentities": null
    }
    

07 Run keyvault list command (Windows/macOS/Linux) with custom query filters to list the name of Key Vault (and the name of its associated resource group) deployed in the current Azure subscription:

az keyvault list
  --output table
  --query '[*].{name:name, resourceGroup:resourceGroup}'

08 The command should return a table with requested information, as shown in the output example below. Otherwise, if the keyvault list command does not produce an output, there are no Azure Key Vaults created in the selected resource group:

Name ResourceGroup
------------------- ------------------------------
cc-keyvault-1       cloud-shell-storage-westeurope
cc-keyvault-2       cloud-shell-storage-westeurope

09 Run keyvault secret list command (Windows/macOS/Linux) using the name of the key vault that you want to examine as the identifier parameter, to list the secrets stored within the selected Key Vault. The command output should return the list of secrets managed by the selected Key Vault. If the command does not produce an output, there are no secrets stored within the selected Key Vault, therefore the Audit process ends here:

az keyvault secret list
  --vault-name cc-keyvault-1

10 Run keyvault show command (Windows/macOS/Linux) to describe the access policy settings available for the selected Key Vault:

az keyvault show
  --name cc-keyvault-1
  --query 'properties.accessPolicies'

If the keyvault show command output does not return an "accessPolicies" object value that includes both the "objectId" that matches the "principalId" listed at step no. 6 and the "permission.secrets" values of "Get", "List", and "Set", then the permissions are not correctly configured to allow your App Services application to access the secret:
[
  {
    "applicationId": null,
    "objectId": "abcd1234-1234-1234-1234-abcd1234abcd",
    "permissions": {
      "certificates": [
        "Get",
        "List",
        "Update",
        "Create",
        "Import",
        "Delete",
        "Recover",
        "Backup",
        "Restore",
        "ManageContacts",
        "ManageIssuers",
        "GetIssuers",
        "ListIssuers",
        "SetIssuers",
        "DeleteIssuers"
      ],
      "keys": [
        "Get",
        "List",
        "Update",
        "Create",
        "Import",
        "Delete",
        "Recover",
        "Backup",
        "Restore"
      ],
      "secrets": [
        "Get",
        "List",
        "Set",
        "Delete",
        "Recover",
        "Backup",
        "Restore"
      ],
      "storage": null
    },
    "tenantId": "1234abcd-1234-1234-1234-1234abcd1234"
  }
]

11 Repeat steps no. 3 - 10 for each Azure App Services application deployed in the current subscription.

12 Repeat steps no. 1 – 11 for each subscription created within your Microsoft Azure cloud account.

Remediation / Resolution

To use the Microsoft Azure Key Vault service to store App Services application secrets, perform the following actions:

Using Azure Portal

01 Sign in to the Azure Management Console.

02 Navigate to App Services blade at https://portal.azure.com/#blade/HubsExtension/BrowseResourceBlade/resourceType/Microsoft.Web%2Fsites.

03 Click on the name of the App Service application that you want to reconfigure.

04 In the blade navigation panel, under Settings, choose Identity.

05 Select the System assigned tab, toggle Status to On, then choose Save to apply the changes. You will be asked to confirm that your application will be added to Microsoft Entra ID so it can be granted permissions to access resources protected by Microsoft Entra ID. Choose Yes and note the Object (principal) ID that is now assigned to your App Service application.

06 Navigate to Key Vaults blade at https://portal.azure.com/#blade/HubsExtension/BrowseResource/resourceType/Microsoft.KeyVault%2Fvaults and click + Create to create the Azure Key Vault that will store your App Services application secret.

07 On the Create key vault setup page, perform the following commands:

  1. For Basics, choose the appropriate subscription and resource group, provide a unique name for the new key vault, then select the Azure cloud region where the vault will be deployed. You can also choose the pricing tier for the key vault at this point. Choose Next : Access policy > to continue.
  2. For Access policy, select Vault access policy for Permission model, and choose + Add Access Policy to create the policy. For Secret permissions, select Get, List, and Set. For Select principal, choose the name of your application (confirming that the Object ID matches the one listed at step no. 5). Once the access policy is configured, choose Add to attach it to the Key Vault. Choose Next : Networking > to continue the setup process.
  3. For Networking, configure the network access control for the new key vault. Select the Connectivity method that you want to use and ensure that only trusted Azure services and/or networks can access your vault. Choose Next : Tags > to continue.
  4. For Tags, use the Name and Value fields to create tags that will help organize the identity of the key vault. Choose Next : Review + create > to validate the setup.
  5. For Review + create, review the resource configuration details, then choose Create to create your new Azure Key Vault.

08 Click on the name of the newly created Microsoft Azure Key Vault.

09 In the blade navigation panel, under Settings, select Secrets, then choose + Generate/Import to create a Key Vault secret that can be used by your App Services application.

10 On the Create a secret setup page, provide a valid secret name, a single-line secret value, configure an activation and an expiration date (optional), set the Enabled flag to Yes, then choose Create to generate your new Key Vault secret. After selecting a secret name, ensure the rule settings within the Conformity application also store a value that can match the name of the chosen secret, to ensure the application can successfully scan the appropriate application setting.

11 Navigate to App Services blade at https://portal.azure.com/#blade/HubsExtension/BrowseResourceBlade/resourceType/Microsoft.Web%2Fsites.

12 Click on the name of the App Services application that you want to reconfigure.

13 In the blade navigation panel, under Settings, choose Configuration and select the Application settings tab to access the settings available for the selected application.

14 Choose + New application setting, provide a unique name for the setting in the Name field and paste the following Key Vault reference in the Value field: @Microsoft.KeyVault(SecretUri=https://<key-vault-name>.vault.azure.net/secrets/ <secret-name>/) or @Microsoft.KeyVault(VaultName=<key-vault-name>;SecretName=<secret-name>), where <key-vault-name> and <secret-name> is the name of the Key Vault and the secret created earlier in the Remediation process. Choose OK to apply the changes. Your application now can reference the secret through its key as normal. No code changes are required.

15 Repeat steps no. 3 – 14 for each Azure App Services application available within the current subscription.

16 Repeat steps no. 1 – 15 for other subscriptions created in your Microsoft Azure cloud account.

Using Azure CLI

01 Run webapp identity assign command (Windows/macOS/Linux) to allocate a system assigned identity to your App Services application:

az webapp identity assign
  --name cc-project5-webapp
  --resource-group cloud-shell-storage-westeurope

02 The command output should return the new Principal identifier, i.e. "principalId":

{
  "principalId": "thisismy-new1-web2-app3-4identifier5”,
  "tenantId": "6b5a32ca-1234-1234-1234-12341aa347d2",
  "type": "SystemAssigned",
  "userAssignedIdentities": null
}

03 Run keyvault create command (Windows/macOS/Linux) to create the Microsoft Azure Key Vault where the application secret will be placed:

az keyvault create
  --name cc-main-key-vault
  --resource-group cloud-shell-storage-westeurope
  --location westeurope
  --enabled-for-deployment true
  --enabled-for-template-deployment true
  --query 'id'

04 The command output should return the ID of the new Microsoft Azure Key Vault:

"/subscriptions/abcd1234-abcd-1234-abcd-abcd1234abcd/resourceGroups/cloud-shell-storage-westeurope/providers/Microsoft.KeyVault/vaults/cc-main-key-vault"

05 Run keyvault set-policy command (Windows/macOS/Linux) using the principal ID of the application which you want to be able to access using the secret (listed at step no. 2) and the name of the newly created Key Vault as the identifier parameters, to assign the right permissions for the selected vault:

az keyvault set-policy
  --name cc-main-key-vault
  --object-id thisismy-new1-web2-app3-4identifier5
  --secret-permissions get list set
  --query 'properties.accessPolicies'

06 The command output should return the modified key vault access policy configuration metadata:

[
  {
    "applicationId": null,
    "objectId": "2a64e9d1-1234-1234-1234-12349dcf079d",
    "permissions": {
      "certificates": [
        "Get",
        "List",
        "Update",
        "Create",
        "Import",
        "Delete",
        "Recover",
        "Backup",
        "Restore",
        "ManageContacts",
        "ManageIssuers",
        "GetIssuers",
        "ListIssuers",
        "SetIssuers",
        "DeleteIssuers"
      ],
      "keys": [
        "Get",
        "List",
        "Update",
        "Create",
        "Import",
        "Delete",
        "Recover",
        "Backup",
        "Restore"
      ],
      "secrets": [
        "Get",
        "List",
        "Set",
        "Delete",
        "Recover",
        "Backup",
        "Restore"
      ],
      "storage": null
    },
    "tenantId": "6b5a32ca-1234-1234-1234-12341aa347d2"
  },
  {
    "applicationId": null,
    "objectId": "thisismy-new1-web2-app3-4identifier5",
    "permissions": {
      "certificates": null,
      "keys": null,
      "secrets": [
        "set",
        "list",
        "get"
      ],
      "storage": null
    },
    "tenantId": "6b5a32ca-1234-1234-1234-12341aa347d2"
  }
]

07 Run keyvault secret set command (Windows/macOS/Linux) to create the Key Vault secret required to be used with your Azure App Services application:

az keyvault secret set
  --name "web-api-key"
  --value "enter-the-secret-value-here"
  --vault-name "cc-main-key-vault"
  --disabled false --query 'name'

08 The command output should return the name of the new Key Vault secret:

"web-api-key"

Ensure the Conformity rule setting is configured within the application to be able to match the chosen secret name to enable ongoing monitoring.

09 Run webapp config appsettings set command (Windows/macOS/Linux) to create a new application setting for your Microsoft Azure App Services application. Use the following format when you define the Key Vault reference for the application setting: @Microsoft.KeyVault(SecretUri=https://<key-vault-name>.vault.azure.net/secrets/<secret-name>/) or @Microsoft.KeyVault(VaultName=<key-vault-name>;SecretName=<secret-name>), where <key-vault-name> and <secret-name> is the name of the Key Vault and the secret created at the previous steps:

az webapp config appsettings set
  --name "cc-project5-webapp"
  --resource-group "cloud-shell-storage-westeurope"
  --settings API_KEY="@Microsoft.KeyVault(VaultName=<key-vault-name>;SecretName=<secret-name>)"

10 The command output should return the new list of application settings:

[
  {
    "name": "APPINSIGHTS_INSTRUMENTATIONKEY",
    "slotSetting": false,
    "value": "1234abcd-1234-abcd-1234-abcd1234abcd"
  },
  {
    "name": "APPLICATIONINSIGHTS_CONNECTION_STRING",
    "slotSetting": false,
    "value":
    "InstrumentationKey=1234abcd-1234-abcd-1234-abcd1234abcd;IngestionEndpoint=https://westeurope-5.in.applicationinsights.azure.com/"
  },
  {
    "name": "ApplicationInsightsAgent_EXTENSION_VERSION",
    "slotSetting": false,
    "value": "~2"
  },
  {
    "name": "XDT_MicrosoftApplicationInsights_Mode",
    "slotSetting": false,
    "value": "default"
  },
  {
    "name": "API_KEY",
    "slotSetting": false,
    "value": "@Microsoft.KeyVault(VaultName=<key-vault-name>;SecretName=<secret-name>)"
  }
]

11 Repeat step no. 1 – 10 for each Azure App Services application deployed in the current subscription.

12 Repeat steps no. 1 – 11 for each subscription created within your Microsoft Azure cloud account.

References

Publication date Oct 23, 2021