Obsługa usługi KeyVaultReference dla aplikacji usługi Service Fabric wdrożonych na platformie Azure

Typowym wyzwaniem podczas tworzenia aplikacji w chmurze jest ustalenie, jak bezpiecznie dystrybuować wpisy tajne do aplikacji i zarządzać nimi. Obsługa usługi Service Fabric KeyVaultReference ułatwia. Po skonfigurowaniu można odwoływać się do adresu URL wpisu tajnego przechowywanego w usłudze Key Vault w definicji aplikacji, a usługa Service Fabric będzie obsługiwać pobieranie tego wpisu tajnego i aktywowanie aplikacji za pomocą niego. W przypadku korzystania z funkcji "zarządzanej przez sf" usługa Service Fabric może również monitorować usługę Key Vault i automatycznie wyzwalać uaktualnienia parametrów aplikacji stopniowej podczas rotacji wpisów tajnych w magazynie.

Opcje dostarczania wpisów tajnych do aplikacji w usłudze Service Fabric

Klasycznym sposobem dostarczania wpisów tajnych do aplikacji usługi Service Fabric było zadeklarowanie zaszyfrowanych parametrów. Dotyczyło to szyfrowania wpisów tajnych względem certyfikatu szyfrowania i przekazywania tych zaszyfrowanych wpisów tajnych do aplikacji. Ta metoda ma kilka wad: konieczność zarządzania certyfikatem szyfrowania, ujawnieniem wpisów tajnych w potoku wdrażania oraz brakiem wglądu w metadane wpisów tajnych dołączonych do wdrożonej aplikacji. Podobnie rotacja wpisów tajnych wymaga wdrożenia aplikacji. Jeśli nie korzystasz z autonomicznego klastra, nie zalecamy już używania zaszyfrowanych parametrów.

Inną opcją jest użycie odwołań do magazynu wpisów tajnych. To środowisko umożliwia centralne zarządzanie wpisami tajnymi aplikacji, lepsze wgląd w metadane wdrożonych wpisów tajnych i umożliwia centralne zarządzanie certyfikatem szyfrowania. Niektórzy mogą preferować ten styl zarządzania wpisami tajnymi podczas uruchamiania autonomicznych klastrów usługi Service Fabric.

Obecnie zaleca się zmniejszenie zależności od wpisów tajnych wszędzie tam, gdzie to możliwe, przy użyciu tożsamości zarządzanych dla aplikacji usługi Service Fabric. Tożsamości zarządzane mogą służyć do uwierzytelniania bezpośrednio w usłudze Azure Storage, usłudze Azure SQL i nie tylko. Oznacza to, że nie ma potrzeby zarządzania oddzielnymi poświadczeniami podczas uzyskiwania dostępu do usług platformy Azure, które obsługują uwierzytelnianie firmy Microsoft Entra.

Jeśli nie można użyć tożsamości zarządzanej jako klienta, zalecamy użycie funkcji KeyVaultReferences. Aby przejść bezpośrednio do usługi Key Vault, należy użyć funkcji KeyVaultReferences, a nie używania tożsamości zarządzanej. KeyVaultReferences pomagają zwiększyć dostępność aplikacji, ponieważ wymusza ona wprowadzanie zmian wpisów tajnych podczas uaktualniania stopniowego. Zwiększa również skalowalność, ponieważ wpisy tajne są buforowane i obsługiwane z poziomu klastra. Jeśli aplikacja używa obecnie szyfrowanych parametrów, w kodzie aplikacji są wymagane tylko minimalne zmiany, aby używać funkcji KeyVaultReferences. Aplikacja może nadal oczekiwać utworzenia pojedynczego wpisu tajnego, a dla tego wpisu tajnego będzie taka sama w okresie istnienia procesu.

Wymagania wstępne

  • Tożsamość zarządzana dla aplikacji usługi Service Fabric

    Obsługa usługi Service Fabric KeyVaultReference używa tożsamości zarządzanej aplikacji do pobierania wpisów tajnych w imieniu aplikacji. Aplikację należy wdrożyć za pomocą usługi ARM i przypisać jej tożsamość zarządzaną. Postępuj zgodnie z tym dokumentem , aby włączyć tożsamość zarządzaną dla aplikacji.

  • Centralny magazyn wpisów tajnych (CSS).

    Centralny magazyn wpisów tajnych (CSS) to zaszyfrowana lokalna pamięć podręczna wpisów tajnych usługi Service Fabric. Ta funkcja używa arkuszy CSS do ochrony i utrwalania wpisów tajnych po pobraniu ich z usługi Key Vault. Włączenie tej usługi systemowej jest wymagane do korzystania z usługi KeyVaultReferences. Postępuj zgodnie z tym dokumentem , aby włączyć i skonfigurować arkusz CSS.

  • Udzielanie tożsamości zarządzanej aplikacji uprawnień dostępu do usługi Key Vault

    Zapoznaj się z tym dokumentem , aby dowiedzieć się, jak udzielić tożsamości zarządzanej dostępu do usługi Key Vault. Należy również pamiętać, że jeśli używasz tożsamości zarządzanej przypisanej przez system, tożsamość zarządzana jest tworzona dopiero po wdrożeniu aplikacji. Może to spowodować utworzenie warunków wyścigu, w których aplikacja próbuje uzyskać dostęp do wpisu tajnego, zanim tożsamość będzie mogła uzyskać dostęp do magazynu. Nazwa tożsamości przypisanej przez system będzie mieć {cluster name}/{application name}/{service name}wartość .

KeyVaultReferences vs. Managed KeyVaultReferences

Podstawową ideą funkcji KeyVaultReferences jest ustawienie wartości parametru aplikacji jako wpisu tajnego, ustawienie go na adres URL usługi Key Vault, który następnie zostanie rozpoznany jako wartość wpisu tajnego po aktywacji aplikacji. Na przykład https://my.vault.azure.net/secrets/MySecret/ w usłudze Key Vault pojedynczy wpis tajny może mieć wiele wersji, na przykład https://my.vault.azure.net/secrets/MySecret/<oid1> i <oid2>. W przypadku korzystania z funkcji KeyVaultReference wartość powinna być odwołaniem do wersji (https://my.vault.azure.net/secrets/MySecret/<oid1>). W przypadku rotacji tego wpisu tajnego w magazynie, na przykład do <oid2>, należy wyzwolić uaktualnienie aplikacji do nowego odwołania. Jeśli używasz klasy ManagedKeyVaultReference, wartość powinna być odwołaniem bez wersji (https://my.vault.azure.net/secrets/MySecret/). Usługa Service Fabric rozpozna najnowsze wystąpienie <oid1> i aktywuje aplikację przy użyciu tego wpisu tajnego. Jeśli zmienisz wpis tajny w magazynie na <oid2>, usługa Service Fabric automatycznie wyzwoli uaktualnienie parametru aplikacji, aby przejść do <oid2> w Twoim imieniu.

Uwaga

Obsługa kluczy KeyVaultReference (wersjonowanych wpisów tajnych) dla aplikacji usługi Service Fabric jest ogólnie dostępna, począwszy od usługi Service Fabric w wersji 7.2 CU5. Zaleca się uaktualnienie do tej wersji przed użyciem tej funkcji.

Uwaga

Obsługa funkcji Managed KeyVaultReference (wpisów tajnych bez wersji) dla aplikacji usługi Service Fabric jest ogólnie dostępna, począwszy od usługi Service Fabric w wersji 9.0.

Używanie funkcji KeyVaultReferences w aplikacji

Można używać funkcji KeyVaultReferences

Jako zmienna środowiskowa

<EnvironmentVariables>
      <EnvironmentVariable Name="MySecret" Type="KeyVaultReference" Value="<KeyVaultURL>"/>
</EnvironmentVariables>
string secret =  Environment.GetEnvironmentVariable("MySecret");

Zainstalowane jako plik w kontenerze

  • Dodawanie sekcji do pliku settings.xml

    Definiowanie MySecret parametru z typem KeyVaultReference i wartością <KeyVaultURL>

    <Section Name="MySecrets">
        <Parameter Name="MySecret" Type="KeyVaultReference" Value="<KeyVaultURL>"/>
    </Section>
    
  • Odwołuj się do nowej sekcji w pliku ApplicationManifest.xml <ConfigPackagePolicies>

    <ServiceManifestImport>
        <Policies>
        <IdentityBindingPolicy ServiceIdentityRef="MyServiceMI" ApplicationIdentityRef="MyApplicationMI" />
        <ConfigPackagePolicies CodePackageRef="Code">
            <!--Linux container example-->
            <ConfigPackage Name="Config" SectionName="MySecrets" EnvironmentVariableName="SecretPath" MountPoint="/var/secrets"/>
            <!--Windows container example-->
            <!-- <ConfigPackage Name="Config" SectionName="dbsecrets" EnvironmentVariableName="SecretPath" MountPoint="C:\secrets"/> -->
        </ConfigPackagePolicies>
        </Policies>
    </ServiceManifestImport>
    
  • Korzystanie z wpisów tajnych z kodu usługi

    Każdy parametr wymieniony w obszarze <Section Name=MySecrets> będzie plikiem w folderze wskazywanym przez EnvironmentVariable SecretPath. Poniższy fragment kodu w języku C# pokazuje, jak odczytać ciąg MySecret z aplikacji.

    string secretPath = Environment.GetEnvironmentVariable("SecretPath");
    using (StreamReader sr = new StreamReader(Path.Combine(secretPath, "MySecret"))) 
    {
        string secret =  sr.ReadToEnd();
    }
    

    Uwaga

    Program MountPoint steruje folderem, w którym będą instalowane pliki zawierające wartości wpisów tajnych.

Jako odwołanie do hasła repozytorium kontenerów

 <Policies>
      <ContainerHostPolicies CodePackageRef="Code">
        <RepositoryCredentials AccountName="MyACRUser" Type="KeyVaultReference" Password="<KeyVaultURL>"/>
      </ContainerHostPolicies>

Używanie funkcji Managed KeyVaultReferences w aplikacji

Najpierw należy włączyć monitorowanie wpisów tajnych przez uaktualnienie definicji klastra w celu dodania EnableSecretMonitoring ustawienia oprócz innych wymaganych konfiguracji CSS:

"fabricSettings": [
    {
        "name": "CentralSecretService",     
        "parameters": [
            {
                "name": "EnableSecretMonitoring",
                "value": "true"
            },
            {
                "name":  "DeployedState",
                "value":  "enabled"
            },
            {
                "name" : "EncryptionCertificateThumbprint",
                "value": "<thumbprint>"
            },
            {
                "name":  "MinReplicaSetSize",
                "value":  "<size>"
            },
            {
                "name":  "TargetReplicaSetSize",
                "value":  "<size>"
            }
        ]
    }
],

Uwaga

Wartość domyślna może stać się true w przyszłości

Po zakończeniu uaktualniania klastra można uaktualnić aplikację użytkownika. W dowolnym miejscu, w których można użyć funkcji KeyVaultReference, można również użyć funkcji ManagedKeyVaultReference, na przykład

    <Section Name="MySecrets">
        <Parameter Name="MySecret" Type="ManagedKeyVaultReference" Value="[MySecretReference]"/>
    </Section>

Podstawową różnicą w określaniu wartości ManagedKeyVaultReferences jest to, że nie można ich zakodować w manifeście typu aplikacji. Muszą być zadeklarowane jako parametry na poziomie aplikacji, a następnie muszą zostać zastąpione w definicji aplikacji usługi ARM.

Oto fragment dobrze sformułowanego manifestu

<?xml version="1.0" encoding="utf-8"?>
<ApplicationManifest ApplicationTypeName="MyAppType" ApplicationTypeVersion="1.0.0">
  <Parameters>
    <Parameter Name="MySecretReference" DefaultValue="" />
  </Parameters>
  <ServiceManifestImport>
    <EnvironmentOverrides CodePackageRef="Code">
      <EnvironmentVariable Name="MySecret" Value="[MySecretReference]" Type="ManagedKeyVaultReference" />
    </EnvironmentOverrides>
    <Policies>
      <IdentityBindingPolicy ServiceIdentityRef="MySvcIdentity" ApplicationIdentityRef="MyAppIdentity" />
    </Policies>
  </ServiceManifestImport>
  <Principals>
    <ManagedIdentities>
      <ManagedIdentity Name="MyAppIdentity" />
    </ManagedIdentities>
  </Principals>
</ApplicationManifest>

oraz fragment definicji zasobu aplikacji:

{
    "type": "Microsoft.ServiceFabric/clusters/applications",
    "name": "MyApp",
    "identity": {
        "type" : "userAssigned",
        "userAssignedIdentities": {
            "[variables('userAssignedIdentityResourceId')]": {}
        }
    },
    "properties": {
        "parameters": {
            "MySecretReference": "https://my.vault.azure.net/secrets/MySecret/"
        },
        "managedIdentities": [
            {
            "name" : "MyAppIdentity",
            "principalId" : "<guid>"
            }
        ]
    }
}

Zarówno deklarowanie parametru ManagedKeyVaultReference jako parametru aplikacji, jak i zastępowanie tego parametru we wdrożeniu jest wymagane, aby usługa Service Fabric mogła pomyślnie zarządzać cyklem życia wdrożonego wpisu tajnego.

Następne kroki