Compartilhar via


Usar referências do Key Vault como configurações de aplicativo no Serviço de Aplicativo do Azure e Azure Functions

Este artigo mostra como usar segredos do Azure Key Vault como valores de configurações de aplicativo ou cadeias de conexão em seus aplicativos do Serviço de Aplicativo do Azure ou do Azure Functions.

O Key Vault é um serviço que fornece gerenciamento centralizado de segredos, com controle total sobre políticas de acesso e histórico de auditoria. Quando uma configuração de aplicativo ou cadeia de conexão é uma referência do Key Vault, o código do aplicativo pode usá-lo como qualquer outra configuração de aplicativo ou cadeia de conexão. Dessa forma, você pode manter segredos além da configuração do aplicativo. As configurações do aplicativo são criptografadas com segurança em repouso, mas se você precisar de recursos para gerenciar segredos, elas deverão entrar em um cofre de chaves.

Permitir ao aplicativo acesso a um cofre de chaves

Para ler segredos de um cofre de chaves, primeiro você precisa criar um cofre e conceder permissão ao aplicativo para acessá-lo:

  1. Crie um cofre de chaves seguindo o início rápido do Key Vault .

  2. Crie uma Identidade gerenciada para seu aplicativo.

    Referências ao Key Vault usam a identidade atribuída pelo sistema do aplicativo por padrão, mas você pode especificar uma identidade atribuída pelo usuário.

  3. Autorize o acesso de leitura a segredos no cofre de chaves para a identidade gerenciada que você criou. Como fazer isso depende do modelo de permissões do cofre de chaves:

Acessar cofres restritos à rede

Se o cofre estiver configurado com restrições de rede, garanta que o aplicativo tenha acesso à rede. Os cofres não devem depender dos endereços IP de saída públicos do aplicativo porque o endereço IP de origem da solicitação secreta pode ser diferente. Em vez disso, o cofre deve ser configurado para aceitar o tráfego de uma rede virtual que o aplicativo usa.

  1. Verifique se o aplicativo tem recursos de rede de saída configurados, conforme descrito nos recursos de rede do Serviço de Aplicativo e nas opções de rede do Azure Functions.

    Atualmente, os aplicativos Linux que se conectam a pontos de extremidade privados devem ser configurados explicitamente para rotear todo o tráfego pela rede virtual. Para definir essa configuração, execute o seguinte comando:

    az webapp config set --resource-group <group-name>  --subscription <subscription> --name <app-name> --generic-configurations '{"vnetRouteAllEnabled": true}'
    
  2. Garanta que a configuração do cofre dá permissão à rede ou à sub-rede que seu aplicativo usa para acessá-lo.

Observe que, mesmo que você tenha configurado corretamente o cofre para aceitar o tráfego da sua rede virtual, os registros de auditoria do cofre ainda poderão mostrar um evento SecretGet com falha (403 - Forbidden) do IP público de saída do aplicativo. Isso será seguido por um evento SecretGet bem-sucedido realizado pelo IP privado do aplicativo, e isso é intencional.

Acessar cofres com uma identidade atribuída pelo usuário

Alguns aplicativos precisam se referir a segredos no momento da criação, quando uma identidade atribuída pelo sistema ainda não está disponível. Nesses casos, crie uma identidade atribuída pelo usuário e dê a ela acesso ao cofre com antecedência.

Depois de conceder permissões à identidade atribuída pelo usuário, siga estas etapas:

  1. Atribua a identidade ao seu aplicativo.

  2. Configure o aplicativo para usar essa identidade para operações de referência do Key Vault definindo a keyVaultReferenceIdentity propriedade como a ID do recurso da identidade atribuída pelo usuário:

    identityResourceId=$(az identity show --resource-group <group-name> --name <identity-name> --query id -o tsv)
    az webapp update --resource-group <group-name> --name <app-name> --set keyVaultReferenceIdentity=${identityResourceId}
    

Essa configuração se aplica a todas as referências do Key Vault para o aplicativo.

Entender a rotação

Se uma versão de segredo não for especificada na referência, o aplicativo usará a versão mais recente no cofre de chaves. Quando versões mais recentes ficam disponíveis, como com rotação, o aplicativo é atualizado automaticamente e começa a usar a versão mais recente dentro de 24 horas.

O atraso ocorre porque o Serviço de Aplicativo armazena em cache os valores das referências do Key Vault e as refeta a cada 24 horas. Qualquer alteração de configuração no aplicativo causa o reinício do aplicativo e uma busca imediata de todos os segredos referenciados.

Para forçar a resolução das referências do Key Vault do seu aplicativo, faça uma solicitação POST autenticada para o Ponto de Extremidade de API https://management.azure.com/[Resource ID]/config/configreferences/appsettings/refresh?api-version=2022-03-01.

Entender as configurações do aplicativo de origem do Key Vault

Para usar uma referência do Key Vault, defina a referência como o valor da configuração. Seu aplicativo pode fazer referência ao segredo por meio de sua chave normalmente. Nenhuma alteração de código é necessária.

Dica

Como você deve ter cofres separados para cada ambiente, a maioria das configurações de aplicativo que usam referências do Key Vault deve ser marcada como configurações de slot.

Uma referência do Key Vault é do formulário @Microsoft.KeyVault({referenceString}), onde {referenceString} está em um dos seguintes formatos:

Cadeia de caracteres de referência Descrição
SecretUri=<secretUri> O SecretUri deve ser o URI completo do plano de dados de um segredo no cofre. Por exemplo, https://myvault.vault.azure.net/secrets/mysecret. Opcionalmente, inclua uma versão, como https://myvault.vault.azure.net/secrets/mysecret/ec96f02080254f109c51a1f14cdb1931.
VaultName=<vaultName>;SecretName=<secretName>;SecretVersion=<secretVersion> O valor VaultName é necessário e é o nome do cofre. O valor SecretName é necessário, pois é o nome do segredo. O SecretVersion valor é opcional, mas, se presente, indica a versão do segredo a ser usado.

Por exemplo, uma referência completa sem uma versão específica ficaria assim:

@Microsoft.KeyVault(SecretUri=https://myvault.vault.azure.net/secrets/mysecret)

Como alternativa:

@Microsoft.KeyVault(VaultName=myvault;SecretName=mysecret)

Considerações sobre montagem de Arquivos do Azure

Os aplicativos podem usar a configuração de aplicativo WEBSITE_CONTENTAZUREFILECONNECTIONSTRING para montar os Arquivos do Azure como o sistema de arquivos. Essa configuração tem verificações de validação para garantir que o aplicativo possa ser iniciado corretamente.

A plataforma depende de ter um compartilhamento de conteúdo nos Arquivos do Azure. A plataforma pressupõe um nome padrão, a menos que um seja especificado usando a WEBSITE_CONTENTSHARE configuração. Para quaisquer solicitações que modifiquem essas configurações, a plataforma valida que esse compartilhamento de conteúdo existe. Se o compartilhamento de conteúdo não existir, a plataforma tentará criá-lo. Se a plataforma não conseguir localizar ou criar o compartilhamento de conteúdo, ela bloqueará a solicitação.

Quando você usa referências do Key Vault nessa configuração, a verificação de validação falha por padrão, porque o segredo não pode ser resolvido durante o processamento da solicitação de entrada. Para evitar esse problema, você pode ignorar a validação definindo WEBSITE_SKIP_CONTENTSHARE_VALIDATION como 1. Essa configuração informa ao Serviço de Aplicativo para ignorar todas as verificações e não cria o compartilhamento de conteúdo para você. Você deve garantir que o compartilhamento de conteúdo seja criado antecipadamente.

Cuidado

Se você ignorar a validação e a cadeia de conexão ou o compartilhamento de conteúdo for inválido, o aplicativo não iniciará corretamente e criará erros HTTP 500.

Como parte da criação do aplicativo, a tentativa de montagem do compartilhamento de conteúdo pode falhar porque as permissões de identidade gerenciada não estão sendo propagadas ou a integração de rede virtual não está configurada. Você pode adiar a configuração dos Arquivos do Azure até mais tarde no modelo de implantação para acomodar esse comportamento. Para obter mais informações, consulte a implantação do Azure Resource Manager mais adiante neste artigo.

Nesse caso, o Serviço de Aplicativo usa um sistema de arquivos padrão até que Arquivos do Azure seja configurado e os arquivos não sejam copiados. Você deve garantir que nenhuma tentativa de implantação ocorra durante o período provisório antes que os Arquivos do Azure seja montado.

Considerações sobre a instrumentação do Application Insights

Os aplicativos podem usar as configurações de aplicativo APPINSIGHTS_INSTRUMENTATIONKEY ou APPLICATIONINSIGHTS_CONNECTION_STRING para serem integrados ao Application Insights.

Para o Serviço de Aplicativo e o Azure Functions, o portal do Azure também usa essas configurações para exibir dados de telemetria do recurso. Se esses valores forem referenciados do Key Vault, essa abordagem não estará disponível. Em vez disso, você precisa trabalhar diretamente com o recurso do Application Insights para exibir a telemetria. No entanto, esses valores não são considerados segredos, portanto, você pode considerar configurá-los diretamente em vez de usar referências do Key Vault.

Implantação do Azure Resource Manager

Ao automatizar implantações de recursos por meio de modelos do Azure Resource Manager, talvez seja necessário sequenciar suas dependências em uma ordem específica. Defina as configurações do aplicativo como um recurso próprio, em vez de usar uma propriedade siteConfig na definição do aplicativo. O aplicativo precisa ser definido primeiro para que a identidade atribuída pelo sistema seja criada com ele e possa ser usada na política de acesso.

O pseudo-modelo a seguir é um exemplo de como um aplicativo de funções pode ser:

{
    //...
    "resources": [
        {
            "type": "Microsoft.Storage/storageAccounts",
            "name": "[variables('storageAccountName')]",
            //...
        },
        {
            "type": "Microsoft.Insights/components",
            "name": "[variables('appInsightsName')]",
            //...
        },
        {
            "type": "Microsoft.Web/sites",
            "name": "[variables('functionAppName')]",
            "identity": {
                "type": "SystemAssigned"
            },
            //...
            "resources": [
                {
                    "type": "config",
                    "name": "appsettings",
                    //...
                    "dependsOn": [
                        "[resourceId('Microsoft.Web/sites', variables('functionAppName'))]",
                        "[resourceId('Microsoft.KeyVault/vaults/', variables('keyVaultName'))]",
                        "[resourceId('Microsoft.KeyVault/vaults/secrets', variables('keyVaultName'), variables('storageConnectionStringName'))]",
                        "[resourceId('Microsoft.KeyVault/vaults/secrets', variables('keyVaultName'), variables('appInsightsKeyName'))]"
                    ],
                    "properties": {
                        "AzureWebJobsStorage": "[concat('@Microsoft.KeyVault(SecretUri=', reference(variables('storageConnectionStringName')).secretUriWithVersion, ')')]",
                        "WEBSITE_CONTENTAZUREFILECONNECTIONSTRING": "[concat('@Microsoft.KeyVault(SecretUri=', reference(variables('storageConnectionStringName')).secretUriWithVersion, ')')]",
                        "APPINSIGHTS_INSTRUMENTATIONKEY": "[concat('@Microsoft.KeyVault(SecretUri=', reference(variables('appInsightsKeyName')).secretUriWithVersion, ')')]",
                        "WEBSITE_ENABLE_SYNC_UPDATE_SITE": "true"
                        //...
                    }
                },
                {
                    "type": "sourcecontrols",
                    "name": "web",
                    //...
                    "dependsOn": [
                        "[resourceId('Microsoft.Web/sites', variables('functionAppName'))]",
                        "[resourceId('Microsoft.Web/sites/config', variables('functionAppName'), 'appsettings')]"
                    ],
                }
            ]
        },
        {
            "type": "Microsoft.KeyVault/vaults",
            "name": "[variables('keyVaultName')]",
            //...
            "dependsOn": [
                "[resourceId('Microsoft.Web/sites', variables('functionAppName'))]"
            ],
            "properties": {
                //...
                "accessPolicies": [
                    {
                        "tenantId": "[reference(resourceId('Microsoft.Web/sites/', variables('functionAppName')), '2020-12-01', 'Full').identity.tenantId]",
                        "objectId": "[reference(resourceId('Microsoft.Web/sites/', variables('functionAppName')), '2020-12-01', 'Full').identity.principalId]",
                        "permissions": {
                            "secrets": [ "get" ]
                        }
                    }
                ]
            },
            "resources": [
                {
                    "type": "secrets",
                    "name": "[variables('storageConnectionStringName')]",
                    //...
                    "dependsOn": [
                        "[resourceId('Microsoft.KeyVault/vaults/', variables('keyVaultName'))]",
                        "[resourceId('Microsoft.Storage/storageAccounts', variables('storageAccountName'))]"
                    ],
                    "properties": {
                        "value": "[concat('DefaultEndpointsProtocol=https;AccountName=', variables('storageAccountName'), ';AccountKey=', listKeys(variables('storageAccountResourceId'),'2019-09-01').key1)]"
                    }
                },
                {
                    "type": "secrets",
                    "name": "[variables('appInsightsKeyName')]",
                    //...
                    "dependsOn": [
                        "[resourceId('Microsoft.KeyVault/vaults/', variables('keyVaultName'))]",
                        "[resourceId('Microsoft.Insights/components', variables('appInsightsName'))]"
                    ],
                    "properties": {
                        "value": "[reference(resourceId('microsoft.insights/components/', variables('appInsightsName')), '2019-09-01').InstrumentationKey]"
                    }
                }
            ]
        }
    ]
}

Observação

Neste exemplo, a implantação do controle de origem depende das configurações do aplicativo. Essa dependência normalmente não é segura, pois a atualização de configuração do aplicativo se comporta de forma assíncrona. No entanto, como você incluiu a configuração do WEBSITE_ENABLE_SYNC_UPDATE_SITE aplicativo, a atualização é síncrona. A implantação do controle do código-fonte só começa depois que as configurações do aplicativo são totalmente atualizadas. Para obter mais configurações de aplicativo, confira Variáveis de ambiente e configurações de aplicativo no Serviço de Aplicativo do Azure.

Solucionar problemas de referências do Key Vault

Se uma referência não for resolvida corretamente, a cadeia de caracteres da referência será usada em vez disso, por exemplo, @Microsoft.KeyVault(...). Essa situação pode fazer com que o aplicativo gere erros, pois ele está esperando um segredo de um valor diferente.

A falha em resolver geralmente se deve a uma configuração incorreta da política de acesso do Key Vault. No entanto, o motivo também pode ser que um segredo não existe mais ou a referência contém um erro de sintaxe.

Se a sintaxe estiver correta, você poderá exibir outras causas para um erro verificando o status de resolução atual no portal do Azure. Vá para As Configurações do Aplicativo e selecione Editar para a referência em questão. A caixa de diálogo de edição mostra informações do status, incluindo erros. Se você não vir a mensagem de status, isso significa que a sintaxe é inválida e não é reconhecida como uma referência do Key Vault.

Você também pode usar um dos detectores internos para obter mais informações.

Para usar o detector do Serviço de Aplicativo:

  1. No portal do Azure, acesse seu aplicativo.
  2. Selecione Diagnosticar e solucionar problemas.
  3. Selecione Disponibilidade e Desempenho>Aplicativo Web inativo.
  4. Na caixa de pesquisa, pesquise e selecione Diagnóstico de Configurações do Aplicativo do Key Vault.

Para usar o detector para o Azure Functions:

  1. No portal do Azure, acesse seu aplicativo.
  2. Acesse os recursos da Plataforma.
  3. Selecione Diagnosticar e solucionar problemas.
  4. Selecione Disponibilidade e Desempenho>Aplicativo de função em falha ou relatando erros.
  5. Clique em Diagnóstico de Configurações de Aplicativo do Key Vault.