Compatibilidad de KeyVaultReference para aplicaciones de Service Fabric implementadas en Azure

Un desafío común al compilar aplicaciones en la nube es pensar en cómo distribuir de manera segura los secretos entre las aplicaciones y administrarlos. La compatibilidad de KeyVaultReference con Service Fabric facilita la tarea. Una vez configurado, puede hacer referencia a la dirección URL del secreto que está almacenado en Key Vault en la definición de la aplicación, y Service Fabric administrará la captura de ese secreto y la activación de la aplicación con ella. Al usar la versión "administrada por SF" de la característica, Service Fabric también puede supervisar Key Vault y desencadenar automáticamente las actualizaciones graduales de parámetros de aplicación a medida que los secretos roten en el almacén.

Opciones para entregar secretos a aplicaciones en Service Fabric

La manera clásica de entregar secretos a una aplicación de Service Fabric era declarar parámetros cifrados. Esto implicaba el cifrado de secretos con un certificado de cifrado y el paso de esos secretos cifrados a la aplicación. Este método tiene algunas desventajas: la necesidad de administrar el certificado de cifrado, la exposición de los secretos en la canalización de implementación y la falta de visibilidad de los metadatos de los secretos asociados a una aplicación implementada. De forma similar, la rotación de secretos requiere una implementación de aplicación. A menos que ejecute un clúster independiente, ya no se recomienda usar parámetros cifrados.

Otra opción es el uso de referencias de almacén de secretos. Esta experiencia permite la administración central de los secretos de la aplicación, una mejor visibilidad de los metadatos de los secretos implementados y permite la administración central del certificado de cifrado. Algunos pueden preferir este estilo de administración de secretos al ejecutar clústeres de Service Fabric independientes.

La recomendación actual es reducir la dependencia de los secretos siempre que sea posible mediante el uso de identidades administradas para aplicaciones de Service Fabric. Las identidades administradas se pueden usar para autenticarse directamente en Azure Storage, Azure SQL, etc. Esto significa que no es necesario administrar una credencial independiente al acceder a los servicios de Azure que admiten la autenticación de Microsoft Entra.

Cuando no sea posible usar la identidad administrada como cliente, se recomienda usar KeyVaultReferences. Debe usar KeyVaultReferences en lugar de usar la identidad administrada para ir directamente a Key Vault. KeyVaultReferences ayuda a aumentar la disponibilidad de la aplicación porque exige que se produzcan los cambios en los secretos durante las actualizaciones graduales. También se escala mejor a medida que los secretos se almacenan en caché y se sirven desde dentro del clúster. Si la aplicación usa parámetros cifrados hoy en día, solo se necesitan cambios mínimos en el código de la aplicación para usar KeyVaultReferences. La aplicación puede seguir esperando obtener un único secreto, y que ese secreto sea el mismo en toda la duración del proceso.

Requisitos previos

  • Identidad administrada para aplicaciones de Service Fabric

    La compatibilidad de KeyVaultReference con Service Fabric utiliza la identidad administrada de una aplicación para obtener secretos en nombre de la aplicación. Debe implementar la aplicación mediante ARM y asignarle una identidad administrada. Siga este documento para habilitar la identidad administrada para la aplicación.

  • Almacén central de secretos (CSS).

    El Almacén central de secretos (CSS) es la caché de secretos local cifrada de Service Fabric. Esta característica usa CSS para proteger y conservar los secretos una vez que se capturan de Key Vault. Es necesario habilitar este servicio del sistema para usar KeyVaultReferences. Siga este documento para habilitar y configurar CSS.

  • Concesión de permiso de acceso a Key Vault a la identidad administrada de la aplicación

    Consulte este documento para ver cómo conceder acceso a Key Vault a la identidad administrada. Además, tenga en cuenta que si usa una identidad administrada asignada por el sistema, la identidad administrada solo se crea después de la implementación de la aplicación. Esto puede crear condiciones de carrera en las que la aplicación intenta tener acceso al secreto antes de que se pueda conceder acceso al almacén a la identidad. El nombre de la identidad asignada por el sistema será {cluster name}/{application name}/{service name}.

KeyVaultReferences frente a KeyVaultReferences administrado

La idea básica de KeyVaultReferences es que, en lugar de establecer el valor del parámetro de la aplicación como secreto, se establece en la dirección URL de Key Vault, que se resolverá en el valor secreto tras la activación de la aplicación. En Key Vault, un único secreto, por ejemplo, https://my.vault.azure.net/secrets/MySecret/, puede tener varias versiones, por ejemplo, https://my.vault.azure.net/secrets/MySecret/<oid1> y <oid2>. Cuando se usa KeyVaultReference, el valor debe ser una referencia con versiones (https://my.vault.azure.net/secrets/MySecret/<oid1>). Si rota ese secreto en el almacén, por ejemplo, a <oid2>, debe desencadenar una actualización de la aplicación a la nueva referencia. Cuando se usa ManagedKeyVaultReference, el valor debe ser una referencia sin versiones (https://my.vault.azure.net/secrets/MySecret/). Service Fabric resolverá la instancia <oid1> más reciente y activará la aplicación con ese secreto. Si rota el secreto en el almacén a <oid2>, Service Fabric desencadenará automáticamente una actualización de los parámetros de aplicación para pasar a <oid2> en su nombre.

Nota

La compatibilidad con KeyVaultReference (secretos con versiones) para aplicaciones Service Fabric está en disponibilidad general a partir de la versión 7.2 de Service Fabric, actualización acumulativa 5. Se recomienda que actualice a esta versión antes de usar esta característica.

Nota

La compatibilidad con KeyVaultReference administrado (secretos sin versiones) para aplicaciones Service Fabric está en disponibilidad general a partir de la versión 9.0 de Service Fabric.

Uso de KeyVaultReferences en la aplicación

Se puede consumir KeyVaultReferences

Como una variable de entorno

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

Montada como archivo en el contenedor

  • Incorporación de una sección a settings.xml

    Defina el parámetro MySecret con el tipo KeyVaultReference y el valor <KeyVaultURL>.

    <Section Name="MySecrets">
        <Parameter Name="MySecret" Type="KeyVaultReference" Value="<KeyVaultURL>"/>
    </Section>
    
  • Consulte la sección nueva en ApplicationManifest.xml en <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>
    
  • Uso de los secretos del código de servicio

    Cada parámetro incluido en <Section Name=MySecrets> será un archivo en la carpeta a la que apunta EnvironmentVariable SecretPath. A continuación, el fragmento de código de C# muestra cómo leer MySecret en la aplicación.

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

    Nota

    MountPoint controla la carpeta donde se montarán los archivos que contienen valores secretos.

Como referencia a una contraseña de repositorio de contenedor

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

Uso de KeyVaultReferences administrado en la aplicación

En primer lugar, debe habilitar la supervisión de secretos mediante la actualización de la definición del clúster para agregar la configuración EnableSecretMonitoring, además de las demás configuraciones CSS necesarias:

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

Nota:

El valor predeterminado puede convertirse en true en el futuro.

Una vez finalizada la actualización del clúster, se puede actualizar la aplicación de usuario. En cualquier lugar donde se pueda usar KeyVaultReference, también se puede usar ManagedKeyVaultReference, por ejemplo,

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

La principal diferencia en la especificación de ManagedKeyVaultReferences es que no se pueden codificar de forma rígida en el manifiesto de tipo de aplicación. Se deben declarar como parámetros de nivel de aplicación y, además, se deben invalidar en la definición de la aplicación ARM.

Este es un extracto de un manifiesto bien 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>

y un extracto de la definición de recursos de la aplicación:

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

Es necesaria tanto la declaración de ManagedKeyVaultReference como parámetro de aplicación, como la invalidación de ese parámetro en la implementación para que Service Fabric administre correctamente el ciclo de vida del secreto implementado.

Pasos siguientes