Serviço Central de Segredos no Azure Service Fabric

O CSS (Serviço Central de Segredos), também conhecido como Repositório Central de Segredos, é um serviço de sistema do Service Fabric destinado a proteger segredos em um cluster. O CSS facilita o gerenciamento de segredos para aplicativos do SF, eliminando a necessidade de uso de parâmetros criptografados.

O Serviço Central de Segredos é um cache de segredo de cluster durável e replicado. Os segredos armazenados no CSS são criptografados em repouso para um certificado de criptografia fornecido pelo cliente. O CSS tem APIs de cliente para gerenciamento de segredos, acessíveis para entidades que se autenticam como cluster ou usuário administrador de cluster. O modelo de aplicativo de runtime do Service Fabric se integra ao CSS e permite a declaração de parâmetros de aplicativo como referências de segredo de CSS.

O CSS também é fundamental para o provisionamento de segredos de aplicativo declarados como URIs secretos do Key Vault, em combinação com a Identidade Gerenciada para aplicativos Service Fabric implantados pelo Azure.

O Serviço Central de Segredos não deve ser uma substituição para um serviço de gerenciamento de segredos externo dedicado, como o Azure Key Vault.

Observação

Ao ativar o CSS em um cluster do SF que executa uma versão anterior a 7.1. CU3, a ativação poderá falhar e deixar o CSS em um estado permanentemente não íntegro se o cluster estiver configurado para autenticação do Windows, se EncryptionCertificateThumbprint for declarado incorretamente ou se o certificado correspondente não estiver instalado. Em ambos os casos, é aconselhável atualizar o cluster para uma versão de runtime do SF mais recente que 7.1. CU3 antes de continuar.

Habilitar o Serviço Central de Segredos

Para habilitar o Serviço Central de Segredos, atualize a configuração do cluster conforme descrito abaixo. É recomendável usar um certificado de criptografia diferente do seu certificado de cluster. Esse certificado precisa estar instalado em todos os nós.

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

Observação

A definição de configuração "DeployedState", introduzida no Service Fabric versão 8.0, é o mecanismo preferencial para habilitar ou desabilitar o CSS. Essa função foi realizada em versões anteriores pela definição de configuração "IsEnabled", que agora é considerada obsoleta.

Modelo secreto do Serviço Central de Segredos

A API do Serviço Central de Segredos expõe dois tipos: recurso secreto e versão secreta. O tipo de recurso secreto representa, conceitualmente, uma família de versões de um único segredo usado para uma finalidade específica, por exemplo, uma cadeia de conexão, uma senha, um certificado de ponto de extremidade. Um objeto do tipo de recurso secreto contém metadados associados a esse segredo, especificamente tipo, tipo de conteúdo e descrição. O tipo de versão secreta representa uma instância específica do segredo associado e armazena o texto não criptografado secreto (criptografado), por exemplo, uma versão secreta contém o valor da senha atual, um objeto de certificado válido até o fim do mês etc. Após a renovação desses segredos, novas versões secretas devem ser produzidas (e adicionadas ao CSS).

Para formalizar o modelo, veja a seguir as regras implementadas e impostas na implementação do CSS:

  • Um recurso secreto pode ter zero ou mais versões
  • Cada versão secreta é filha de um recurso secreto específico; uma versão só pode ter um recurso pai
  • Uma versão de segredo individual pode ser excluída sem afetar outras versões do mesmo segredo
  • A exclusão de um recurso secreto causa a exclusão de todas as suas versões
  • O valor de uma versão secreta é imutável

Declarar um recurso secreto

Você pode criar um recurso secreto usando a API REST.

Observação

Se o cluster usar a autenticação do Windows sem um certificado HttpGateway, a solicitação REST será enviada por um canal HTTP não seguro. Para habilitar o TLS para esse canal, a definição de cluster deve ser atualizada para especificar um certificado do servidor de gateway http.

Para criar um recurso secreto supersecret usando a API REST, faça uma solicitação PUT a https://<clusterfqdn>:19080/Resources/Secrets/supersecret?api-version=6.4-preview. Você precisará autenticar usando um certificado de cluster ou um certificado do cliente de administrador para criar um recurso secreto.

$json = '{"properties": {"kind": "inlinedValue", "contentType": "text/plain", "description": "supersecret"}}'
Invoke-WebRequest  -Uri https://<clusterfqdn>:19080/Resources/Secrets/supersecret?api-version=6.4-preview -Method PUT -CertificateThumbprint <CertThumbprint> -Body $json

Definir o valor do segredo

Use o script abaixo para usar a API REST para definir o valor secreto.

$Params = '{"properties": {"value": "mysecretpassword"}}'
Invoke-WebRequest -Uri https://<clusterfqdn>:19080/Resources/Secrets/supersecret/values/ver1?api-version=6.4-preview -Method PUT -Body $Params -CertificateThumbprint <ClusterCertThumbprint>

Examinar o valor secreto

Invoke-WebRequest -CertificateThumbprint <ClusterCertThumbprint> -Method POST -Uri "https:<clusterfqdn>/Resources/Secrets/supersecret/values/ver1/list_value?api-version=6.4-preview"

Usar o segredo em seu aplicativo

Um aplicativo pode consumir um segredo do CSS declarando-o como uma variável de ambiente ou especificando um caminho em que o texto não criptografado secreto deve ser serializado. Siga estas etapas para fazer referência a um segredo de CSS:

  1. Adicione uma seção ao arquivo settings.xml com o snippet a seguir. Observe aqui que o valor está no formato {secretname:version}.
     <Section Name="testsecrets">
      <Parameter Name="TopSecret" Type="SecretsStoreRef" Value="supersecret:ver1"/
     </Section>
  1. Importe a seção em ApplicationManifest.xml.
<ServiceManifestImport>
<ServiceManifestRef ServiceManifestName="testservicePkg" ServiceManifestVersion="1.0.0" />
<ConfigOverrides />
<Policies>
 <ConfigPackagePolicies CodePackageRef="Code">
   <ConfigPackage Name="Config" SectionName="testsecrets" EnvironmentVariableName="SecretPath" />
   </ConfigPackagePolicies>
</Policies>
</ServiceManifestImport>

Exemplo 1: monte os segredos em um contêiner. A única alteração necessária para disponibilizar os segredos dentro do contêiner é usar specify em um ponto de montagem no <ConfigPackage>. O snippet a seguir é o arquivo ApplicationManifest.xml modificado.

   <ServiceManifestImport>
       <ServiceManifestRef ServiceManifestName="testservicePkg" ServiceManifestVersion="1.0.0" />
       <ConfigOverrides />
       <Policies>
         <ConfigPackagePolicies CodePackageRef="Code">
           <ConfigPackage Name="Config" SectionName="testsecrets" MountPoint="C:\secrets" EnvironmentVariableName="SecretPath" />
           <!-- Linux Container
            <ConfigPackage Name="Config" SectionName="testsecrets" MountPoint="/mnt/secrets" EnvironmentVariableName="SecretPath" />
           -->
         </ConfigPackagePolicies>
       </Policies>
     </ServiceManifestImport>

Os segredos estão disponíveis no ponto de montagem dentro de seu contêiner.

Exemplo 2: associe um segredo a uma variável de ambiente de processo especificando Type='SecretsStoreRef. O snippet a seguir é um exemplo de como associar supersecret versão ver1 à variável de ambiente MySuperSecret no ServiceManifest.xml.

   <EnvironmentVariables>
     <EnvironmentVariable Name="MySuperSecret" Type="SecretsStoreRef" Value="supersecret:ver1"/>
   </EnvironmentVariables>

A variável de ambiente SecretPath aponta para o diretório em que todos os segredos são armazenados. Cada parâmetro listado na seção testsecrets é armazenado em um arquivo separado. O aplicativo agora pode usar o segredo da seguinte maneira:

secretValue = IO.ReadFile(Path.Join(Environment.GetEnvironmentVariable("SecretPath"),  "TopSecret"))

Girar o certificado de criptografia do Serviço Central de Segredos

É importante observar que os certificados permanecem válidos para descriptografia após a expiração. Neste momento, é recomendável continuar provisionando os certificados de criptografia anteriores após o giro, para reduzir a chance de um bloqueio. Siga estas etapas para girar o certificado de criptografia do CSS:

  1. Provisione o novo certificado para cada nó do cluster. Não remova nem continue provisionando o certificado de criptografia anterior.
  2. Inicie uma atualização da configuração do cluster para alterar o valor de EncryptionCertificateThumbprint para a impressão digital do SHA1 do novo certificado. Após a conclusão da atualização, o CSS começará a criptografar novamente o conteúdo atual para o novo certificado de criptografia. Todos os segredos adicionados ao CSS após depois disso serão criptografados diretamente no novo certificado de criptografia. Como a convergência para ter todos os segredos protegidos pelo novo certificado é assíncrona, é importante que o certificado de criptografia anterior permaneça instalado em todos os nós e disponível para o CSS.

Remover o Serviço Central de Segredos do cluster

É preciso fazer duas atualizações para remover o Serviço Central de Segredos de um cluster com segurança. A primeira atualização desabilita funcionalmente o CSS; a segunda remove o serviço da definição do cluster, o que inclui a exclusão permanente do conteúdo. Esse processo de duas etapas evita a exclusão acidental do serviço e ajuda a garantir que não haja dependências órfãs no CSS durante a remoção. Esse recurso está disponível a partir da versão 8.0 do SF.

Etapa 1: atualizar DeployedState para removing no CSS

Atualize a definição de cluster "IsEnabled" = "true" ou "DeployedState" = "enabled" para:

{
    "name":  "DeployedState",
    "value":  "removing"
}

Depois que o Serviço Central de Segredos entrar no estado implantado Removing, ele rejeitará todas as chamadas de API secretas recebidas, sejam chamada REST diretas ou por meio de ativações de serviços que incluem SecretStoreRefs ou KeyVaultReferences. Todos os aplicativos ou componentes no cluster que ainda dependem do CSS entrarão em estado de aviso. Caso isso ocorra, a atualização para o estado implantado Removing deve ser revertida. Se a atualização já tiver sido feita, inicie uma nova atualização para reverter o CSS para DeployedState = Enabled. Caso o Serviço Central de Segredos receba uma solicitação enquanto estiver no estado implantado Removing, o código HTTP 401 (Não autorizado) será exibido e o se colocará em estado de integridade de aviso.

Etapa 2: atualizar DeployedState para disabled no CSS

Atualize a definição de cluster "DeployedState" = "removing" para:

{
    "name":  "DeployedState",
    "value":  "disabled"
}

O Serviço Central de Segredos não deve ser mais executado no cluster e não estará presente na lista de serviços do sistema. O conteúdo do CSS é perdido e não pode ser recuperado.

Próximas etapas