Suporte do KeyVaultReference para aplicativos do Service Fabric implantados no Azure

Um desafio comum ao criar aplicativos em nuvem é descobrir como distribuir de maneira segura e gerenciar os segredos para seus aplicativos. O suporte do KeyVaultReference do Service Fabric facilita isso. Depois de configurado, você pode referenciar a URL do segredo armazenado no Key Vault na definição do aplicativo e o Service Fabric buscará esse segredo e ativará seu aplicativo com ele. Ao usar a versão "gerenciada por SF" do recurso, o Service Fabric também pode monitorar seu Key Vault e disparar automaticamente atualizações de parâmetro de aplicativo sem interrupção à medida que seus segredos alternarem no cofre.

Opções para fornecer segredos a aplicativos no Service Fabric

A maneira clássica de fornecer segredos a um aplicativo Service Fabric era declarar parâmetros criptografados. Isso envolveu a criptografia de segredos em um certificado de criptografia e a passagem desses segredos criptografados para seu aplicativo. Esse método tem algumas desvantagens: a necessidade de gerenciar o certificado de criptografia, a exposição dos segredos no pipeline de implantação e a falta de visibilidade dos metadados dos segredos anexados a um aplicativo implantado. Da mesma forma, a rotação de segredos exige uma implantação de aplicativo. A menos que você esteja executando um cluster autônomo, não recomendamos usar parâmetros criptografados.

Outra opção é usar referências do repositório secreto. Essa experiência permite o gerenciamento central dos segredos do aplicativo, uma melhor visibilidade dos metadados de segredos implantados e permite o gerenciamento central do certificado de criptografia. Alguns podem preferir esse estilo de gerenciamento de segredo ao executar clusters Service Fabric autônomos.

A recomendação hoje é reduzir a dependência de segredos sempre que possível usando identidades gerenciadas para aplicativos Service Fabric. As identidades gerenciadas podem ser usadas para autenticar diretamente no Armazenamento do Microsoft Azure, SQL do Azure e muito mais. Isso significa que não é necessário gerenciar uma credencial separada ao acessar os serviços do Azure que dão suporte à autenticação do Microsoft Entra.

Quando não é possível usar a identidade gerenciada como um cliente, recomendamos o uso de KeyVaultReferences. Você deve usar KeyVaultReferences em vez de usar a identidade gerenciada para ir diretamente para Key Vault. KeyVaultReferences ajudam a aumentar a disponibilidade do aplicativo porque ele impõe que alterações secretas ocorram durante atualizações sem interrupção. Ele também é dimensionado melhor conforme os segredos são armazenados em cache e servidos de dentro do cluster. Se o aplicativo usa parâmetros criptografados hoje, há apenas alterações mínimas necessárias no código do aplicativo para usar KeyVaultReferences. Seu aplicativo pode continuar esperando encontrar um único segredo e que esse segredo seja o mesmo durante o tempo de vida do processo.

Pré-requisitos

  • Identidade gerenciada para aplicativos do Service Fabric

    O suporte do KeyVaultReference para o Service Fabric usa a identidade gerenciada de um aplicativo para buscar segredos em nome do aplicativo. Você deve implantar seu aplicativo por meio do ARM e atribuí-lo a uma identidade gerenciada. Siga este documento para habilitar a identidade gerenciada para seu aplicativo.

  • Repositório Central de Segredos (CSS).

    O CSS (Repositório Central de Segredos) é o cache de segredos locais criptografados do Service Fabric. Este recurso usa CSS para proteger e persistir os segredos depois que eles são buscados do Key Vault. Habilitar esse serviço de sistema é necessário para usar KeyVaultReferences. Siga este documento para habilitar e configurar o CSS.

  • Conceder permissão de acesso de identidade gerenciada do aplicativo para o Key Vault

    Consulte este documento para ver como conceder acesso de identidade gerenciada ao Key Vault. Observe também que, se você estiver usando a identidade gerenciada atribuída pelo sistema, a identidade gerenciada será criada somente após a implantação do aplicativo. Isso pode criar condições de corrida, em que o aplicativo tenta acessar o segredo antes que a identidade receba acesso ao cofre. O nome da identidade atribuída pelo sistema será {cluster name}/{application name}/{service name}.

KeyVaultReferences vs. ManagedKeyVaultReferences

A ideia básica de KeyVaultReferences é, em vez de definir o valor do parâmetro do aplicativo como seu segredo, defini-lo como a URL Key Vault, que será resolvida para o valor secreto após a ativação do seu aplicativo. No Key Vault, um único segredo, por exemplo, https://my.vault.azure.net/secrets/MySecret/ pode ter várias versões, por exemplo, https://my.vault.azure.net/secrets/MySecret/<oid1> e <oid2>. Quando você usa um KeyVaultReference, o valor deve ser uma referência com versão (https://my.vault.azure.net/secrets/MySecret/<oid1>). Se você fizer a rotação desse segredo no cofre, por exemplo, para <oid2>, deverá disparar uma atualização de aplicativo para a nova referência. Quando você usa um ManagedKeyVaultReference, o valor deve ser uma referência sem versão (https://my.vault.azure.net/secrets/MySecret/). O Service Fabric resolverá a instância <oid1> mais recente e ativará o aplicativo com esse segredo. Se você fizer a rotação do segredo no cofre para <oid2>, o Service Fabric vai disparar automaticamente uma atualização de parâmetro de aplicativo para mover <oid2> em seu nome.

Observação

O suporte do KeyVaultReference (segredos com versão) para aplicativos do Service Fabric está em disponibilidade geral, começando com o Service Fabric versão 7.2 CU5. É recomendável que você atualize para esta versão antes de usar esse recurso.

Observação

O suporte do ManagedKeyVaultReference (segredos sem versão) para aplicativos do Service Fabric está em disponibilidade geral, começando com o Service Fabric versão 9.0.

Usar o KeyVaultReferences em seu aplicativo

O KeyVaultReferences pode ser consumido

Como uma variável de ambiente

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

Montado como um arquivo no contêiner

  • Adicionar uma seção a settings.xml

    Definir parâmetro MySecret com Tipo KeyVaultReference e Valor <KeyVaultURL>

    <Section Name="MySecrets">
        <Parameter Name="MySecret" Type="KeyVaultReference" Value="<KeyVaultURL>"/>
    </Section>
    
  • Fazer referência à nova seção ApplicationManifest.xml no <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>
    
  • Consumir os segredos do código de serviço

    Cada parâmetro listado em <Section Name=MySecrets> será um arquivo na pasta apontada por EnvironmentVariable SecretPath. O snippet de código C# abaixo mostra como ler MySecret do seu aplicativo.

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

    Observação

    O MountPoint controla a pasta onde os arquivos que contêm valores secretos serão montados.

Como referência a uma senha de repositório de contêiner

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

Usar o Managed KeyVaultReferences no seu aplicativo

Primeiro, você deve habilitar o monitoramento de segredo atualizando sua definição de cluster para adicionar a EnableSecretMonitoring configuração, além das outras configurações de CSS necessárias:

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

Observação

O padrão pode se tornar true no futuro

Depois que a atualização do cluster for concluída, seu aplicativo de usuário poderá ser atualizado. Em qualquer lugar que um KeyVaultReference pode ser usado, um ManagedKeyVaultReference também pode ser usado, por exemplo,

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

A principal diferença na especificação de ManagedKeyVaultReferences é que elas não podem ser codificadas no manifesto do tipo de aplicativo. Eles devem ser declarados como parâmetros no nível do aplicativo e, além disso, devem ser substituídos na definição do aplicativo ARM.

Aqui está um trecho de um manifesto bem formado

<?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>

e um trecho da definição de recurso do aplicativo:

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

Tanto declarar o ManagedKeyVaultReference como um parâmetro de aplicativo, quanto substituir esse parâmetro na implantação é necessário para o Service Fabric gerenciar com êxito o ciclo de vida do segredo implantado.

Próximas etapas