Gebruik Key Vault verwijzingen als app-instellingen in Azure App Service en Azure Functions

In dit artikel wordt beschreven hoe u geheimen uit Azure Key Vault gebruikt als waarden van app-instellingen of verbindingsreeksen in uw App Service- of Azure Functions-apps.

Azure Key Vault is een service die gecentraliseerd geheimenbeheer biedt, met volledige controle over toegangsbeleid en controlegeschiedenis. Wanneer een app-instelling of connection string een sleutelkluisreferentie is, kan uw toepassingscode deze net als elke andere app-instelling of connection string gebruiken. Op deze manier kunt u geheimen onderhouden buiten de configuratie van uw app. App-instellingen worden veilig versleuteld at rest, maar als u mogelijkheden voor geheimbeheer nodig hebt, moeten ze naar een sleutelkluis gaan.

Uw app toegang verlenen tot een sleutelkluis

Als u geheimen uit een sleutelkluis wilt lezen, moet u een kluis hebben gemaakt en uw app toestemming geven om deze te openen.

  1. Maak een sleutelkluis door de quickstart Key Vault te volgen.

  2. Maak een beheerde identiteit voor uw toepassing.

    Sleutelkluisverwijzingen maken standaard gebruik van de door het systeem toegewezen identiteit van de app, maar u kunt een door de gebruiker toegewezen identiteit opgeven.

  3. Autoriseer leestoegang tot geheimen van uw sleutelkluis voor de beheerde identiteit die u eerder hebt gemaakt. Hoe u dit doet, is afhankelijk van het machtigingenmodel van uw sleutelkluis:

Toegang tot kluizen met netwerkbeperkingen

Als uw kluis is geconfigureerd met netwerkbeperkingen, moet u ervoor zorgen dat de toepassing netwerktoegang heeft. Kluizen mogen niet afhankelijk zijn van de openbare uitgaande IP-adressen van de app, omdat het oorspronkelijke IP-adres van de geheime aanvraag anders kan zijn. In plaats daarvan moet de kluis worden geconfigureerd voor het accepteren van verkeer van een virtueel netwerk dat door de app wordt gebruikt.

  1. Zorg ervoor dat voor de toepassing uitgaande netwerkmogelijkheden zijn geconfigureerd, zoals beschreven in App Service netwerkfuncties en Azure Functions netwerkopties.

    Linux-toepassingen die verbinding maken met privé-eindpunten, moeten expliciet worden geconfigureerd om al het verkeer via het virtuele netwerk te routeren. Deze vereiste wordt verwijderd in een volgende update. Voer de volgende opdracht uit om deze instelling te configureren:

    az webapp config set --subscription <sub> -g <group-name> -n <app-name> --generic-configurations '{"vnetRouteAllEnabled": true}'
    
  2. Zorg ervoor dat de configuratie van de kluis toegang biedt tot het netwerk of subnet dat uw app gebruikt.

Toegang tot kluizen met een door de gebruiker toegewezen identiteit

Sommige apps moeten naar geheimen verwijzen tijdens het maken, wanneer een door het systeem toegewezen identiteit nog niet beschikbaar is. In dergelijke gevallen kan een door de gebruiker toegewezen identiteit vooraf worden gemaakt en toegang tot de kluis worden gegeven.

Nadat u machtigingen hebt verleend aan de door de gebruiker toegewezen identiteit, voert u de volgende stappen uit:

  1. Wijs de identiteit toe aan uw toepassing als u dat nog niet hebt gedaan.

  2. Configureer de app om deze identiteit te gebruiken voor sleutelkluisverwijzingsbewerkingen door de keyVaultReferenceIdentity eigenschap in te stellen op de resource-id van de door de gebruiker toegewezen identiteit.

    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}
    

Deze instelling is van toepassing op alle key vault-verwijzingen voor de app.

Rotatie

Als de geheime versie niet is opgegeven in de verwijzing, gebruikt de app de nieuwste versie die bestaat in de sleutelkluis. Wanneer nieuwere versies beschikbaar komen, zoals bij een rotatie-gebeurtenis, wordt de app automatisch bijgewerkt en wordt de nieuwste versie binnen 24 uur gebruikt. De vertraging komt doordat App Service de waarden van de sleutelkluisverwijzingen in de cache opslaat en deze elke 24 uur opnieuw ophaalt. Elke configuratiewijziging in de app veroorzaakt een herstart van de app en een onmiddellijke refetch van alle geheimen waarnaar wordt verwezen.

Instellingen voor bron-app uit de sleutelkluis

Als u een sleutelkluisreferentie wilt gebruiken, stelt u de verwijzing in als de waarde van de instelling. Uw app kan zoals gebruikelijk verwijzen naar het geheim via de bijbehorende sleutel. Er zijn geen codewijzigingen vereist.

Tip

De meeste app-instellingen die gebruikmaken van key vault-verwijzingen, moeten worden gemarkeerd als site-instellingen, omdat u afzonderlijke kluizen voor elke omgeving moet hebben.

Een sleutelkluisreferentie heeft de vorm @Microsoft.KeyVault({referenceString}), waarbij {referenceString} een van de volgende indelingen is:

Referentietekenreeks Beschrijving
SecretUri=secretUri De SecretUri moet de volledige gegevensvlak-URI van een geheim in de kluis zijn, optioneel inclusief een versie, bijvoorbeeld https://myvault.vault.azure.net/secrets/mysecret/ of https://myvault.vault.azure.net/secrets/mysecret/ec96f02080254f109c51a1f14cdb1931
VaultName=vaultName; SecretName=secretName; SecretVersion=secretVersion De Kluisnaam is vereist en is de naam van de kluis. De SecretName is vereist en is de geheime naam. De SecretVersion is optioneel, maar indien aanwezig geeft de versie van het geheim aan die moet worden gebruikt.

Een volledige verwijzing ziet er bijvoorbeeld uit als de volgende tekenreeks:

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

U kunt ook het volgende doen:

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

Overwegingen voor Azure Files koppelen

Apps kunnen de WEBSITE_CONTENTAZUREFILECONNECTIONSTRING toepassingsinstelling gebruiken om Azure Files te koppelen als het bestandssysteem. Deze instelling bevat validatiecontroles om ervoor te zorgen dat de app correct kan worden gestart. Het platform is afhankelijk van het hebben van een inhoudsshare binnen Azure Files en er wordt uitgegaan van een standaardnaam, tenzij er een is opgegeven via de WEBSITE_CONTENTSHARE instelling. Voor aanvragen die deze instellingen wijzigen, valideert het platform of deze inhoudsshare bestaat en probeert het deze te maken als dat niet het geval is. Als de inhoudsshare niet kan worden gevonden of gemaakt, wordt de aanvraag geblokkeerd.

Wanneer u sleutelkluisverwijzingen in deze instelling gebruikt, mislukt de validatiecontrole standaard, omdat het geheim zelf niet kan worden opgelost tijdens het verwerken van de binnenkomende aanvraag. Om dit probleem te voorkomen, kunt u de validatie overslaan door in te stellen WEBSITE_SKIP_CONTENTSHARE_VALIDATION op '1'. Met deze instelling wordt App Service aangegeven dat alle controles moeten worden overgeslagen en wordt de inhoudsshare niet voor u gemaakt. Zorg ervoor dat deze van tevoren is gemaakt.

Waarschuwing

Als u de validatie overslaat en de connection string of inhoudsshare ongeldig zijn, kan de app niet goed worden gestart en worden alleen HTTP 500-fouten weergegeven.

Als onderdeel van het maken van de app kan het koppelen van de inhoudsshare mislukken omdat machtigingen voor beheerde identiteiten niet worden doorgegeven of de integratie van het virtuele netwerk niet wordt ingesteld. U kunt het instellen van Azure Files uitstellen tot later in de implementatiesjabloon om dit mogelijk te maken. Zie Implementatie van Azure Resource Manager voor meer informatie. In dit geval gebruikt App Service een standaardbestandssysteem totdat Azure Files is ingesteld en bestanden niet worden gekopieerd. U moet ervoor zorgen dat er geen implementatiepogingen plaatsvinden tijdens de tussentijdse periode voordat Azure Files wordt gekoppeld.

Overwegingen voor Application Insights-instrumentatie

Apps kunnen de APPINSIGHTS_INSTRUMENTATIONKEY toepassingsinstellingen of APPLICATIONINSIGHTS_CONNECTION_STRING gebruiken om te integreren met Application Insights. De portalervaringen voor App Service en Azure Functions deze instellingen ook gebruiken om telemetriegegevens van de resource op te halen. Als vanuit Key Vault naar deze waarden wordt verwezen, zijn deze ervaringen niet beschikbaar en moet u in plaats daarvan rechtstreeks met de Application Insights-resource werken om de telemetrie weer te geven. Deze waarden worden echter niet beschouwd als geheimen, dus u kunt overwegen ze rechtstreeks te configureren in plaats van sleutelkluisverwijzingen te gebruiken.

Implementatie van Azure Resource Manager

Wanneer u resource-implementaties automatiseert via Azure Resource Manager-sjablonen, moet u mogelijk uw afhankelijkheden in een bepaalde volgorde rangschikken om deze functie te laten werken. Zorg ervoor dat u uw app-instellingen definieert als hun eigen resource, in plaats van een siteConfig eigenschap in de app-definitie te gebruiken. Dit komt omdat de app eerst moet worden gedefinieerd, zodat de door het systeem toegewezen identiteit ermee wordt gemaakt en kan worden gebruikt in het toegangsbeleid.

De volgende pseudosjabloon is een voorbeeld van hoe een functie-app eruit kan zien:

{
    //...
    "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]"
                    }
                }
            ]
        }
    ]
}

Notitie

In dit voorbeeld is de implementatie van broncodebeheer afhankelijk van de toepassingsinstellingen. Dit is normaal gesproken onveilig gedrag, omdat de update van de app-instelling zich asynchroon gedraagt. Omdat we echter de WEBSITE_ENABLE_SYNC_UPDATE_SITE toepassingsinstelling hebben opgenomen, is de update synchroon. Dit betekent dat de implementatie van broncodebeheer pas wordt gestart zodra de toepassingsinstellingen volledig zijn bijgewerkt. Zie Omgevingsvariabelen en app-instellingen in Azure App Service voor meer app-instellingen.

Problemen met key vault-verwijzingen oplossen

Als een verwijzing niet correct wordt omgezet, wordt in plaats daarvan de verwijzingstekenreeks gebruikt (bijvoorbeeld @Microsoft.KeyVault(...)). Dit kan ertoe leiden dat de toepassing fouten genereert, omdat er een geheim van een andere waarde wordt verwacht.

Het oplossen van problemen wordt meestal veroorzaakt door een onjuiste configuratie van het Key Vault-toegangsbeleid. Dit kan echter ook worden veroorzaakt door een geheim dat niet meer bestaat of een syntaxisfout in de verwijzing zelf.

Als de syntaxis juist is, kunt u andere oorzaken van fouten weergeven door de huidige oplossingsstatus in de portal te controleren. Navigeer naar Toepassingsinstellingen en selecteer 'Bewerken' voor de betreffende verwijzing. In het dialoogvenster Bewerken wordt statusinformatie weergegeven, inclusief eventuele fouten. Als u het statusbericht niet ziet, betekent dit dat de syntaxis ongeldig is en niet wordt herkend als een sleutelkluisreferentie.

U kunt ook een van de ingebouwde detectoren gebruiken om aanvullende informatie op te halen.

De detector gebruiken voor App Service

  1. Navigeer in de portal naar uw app.
  2. Selecteer Problemen vaststellen en oplossen.
  3. Kies Beschikbaarheid en prestaties en selecteer Web-app niet beschikbaar.
  4. Zoek en selecteer Key Vault Diagnostische gegevens over toepassingsinstellingen in het zoekvak.

De detector gebruiken voor Azure Functions

  1. Navigeer in de portal naar uw app.
  2. Navigeer naar Platformfuncties.
  3. Selecteer Problemen vaststellen en oplossen.
  4. Kies Beschikbaarheid en prestaties en selecteer Functie-app niet beschikbaar of fouten rapporteren.
  5. Selecteer Key Vault Diagnostische gegevens over toepassingsinstellingen.