Introducción a Dapr .NET SDK (3/N): Secrets


Continuando con la serie de posts sobre #Dapr, en este en particular vamos a ver como usar secretos para evitar tener información sensible (como texto plano) en los componentes Dapr. Delegando así esta responsabilidad de seguridad en otros components, los «Secrets«.

A continuación, el listado completo de posts relacionados sobre los que iré trabajando y publicando:

  1. Introducción a Dapr .NET SDK (1/N) y Service-to-service invocation
  2. Introducción a Dapr .NET SDK (2/N): State management
  3. [ ->] Introducción a Dapr .NET SDK (3/N): Secrets
  4. Introducción a Dapr .NET SDK (4/N): Pub/Sub
  5. Introducción a Dapr .NET SDK (5/N): Bindings y Triggers
  6. Introducción a Dapr .NET SDK (6/N): Debugging (VSCode y VS) + Sidekick
  7. Introducción a Dapr .NET SDK (7/N): Docker Compose and HTTPS
  8. Introducción a Dapr .NET SDK (8/N): Kubernetes mode
  9. Introducción a Dapr .NET SDK (9/N): Azure Container Apps mode

Azure Key Vault

En concreto, los siguientes ejemplos se basan en los mismos del post anterior, con la diferencia de que adaptaremos los componentes para que usen Secretos y, en particular, Azure Key Vault.

En primer lugar, creamos un nuevo recurso en Azure de tipo Key Vault para el que seguiremos los siguientes pasos:

1. Crear un ServicePrincipalName (spn) con certificado en Key Vault. Ejecutamos para ello desde línea de comandos la siguiente instrucción. Para lo que previamente, es imprescindible tener instalado AZ CLI y haber realizado previamente el login en Azure asi como haber establecido/seleccionado la subscripción predeterminada con la que trabajar (en resumen, haber ejecutado: «az login» y «az account set -s <SUBSCRIPTION-ID>»).

az ad sp create-for-rbac --name dapr-ServicePrincipalName --create-cert --cert dapr-CertName --keyvault dapr-keyvault

2. Tras ejecutar la instrucción anterior, obtenemos una salida similar a la siguiente:

{
  "appId": "b8ec9999-d99d-999d-9999-333b3333a33a",
  "displayName": "dapr-ServicePrincipalName",
  "name": "b8ec9999-d99d-999d-9999-333b3333a33a",
  "password": null,
  "tenant": "38f99999-9c99-99d9-9c9c-f9999b9a9999"
}

Nota: En cualquier momento, podemos obtener el appId ejecutando: «az ad sp list –display-name ServicePrincipal«.

3. Descargar el certificado (.pfx), bien desde el portal de Azure o bien mediante la siguiente instrucción:

az keyvault secret download --vault-name dapr-keyvault --name CertName --encoding base64 --file c:\users\jlguerrero\dapr-keyvault.pfx

4. Ahora que ya tenemos disponible Azure Key Vault, creamos un nuevo secreto de tipo «Manual» con los siguientes valores:

  • Name: «redis-password
  • Value: Copiamos el valor de la clave (o key) de Azure Redis, según vimos en el post anterior y la pegamos aquí.
Configuración del secreto en Azure Key Vault

En este punto, ya estamos en disposición de crear el nuevo componente «secretstore«, de tipo «secretstore.azure.keyvault«, y que guardaremos en la carpeta «components/azure/secrets», con el nombre «azure-keyvault.yaml«.

apiVersion: dapr.io/v1alpha1
kind: Component
metadata:
  name: secretstore
  namespace: default
spec:
  type: secretstores.azure.keyvault        
  version: v1
  metadata:
  - name: vaultName
    value: dapr-keyvault
  - name: spnTenantId
    value: "<TENANT-ID>"
  - name: spnClientId
    value: "<SERVICE-PRINCIPAL-NAME-ID>"
  - name: spnCertificateFile
    value : "C:\\Users\\jlguerrero\\dapr-keyvault.pfx"

Ya tenemos el componente Secret, veamos pues como realizar su integración/consumo desde nuestro componente statestore.

Azure Redis

Creamos un nuevo componente en la carpeta «./components/azure/secrets», con el nombre: «azure-redis-with-keyvault.yaml»

Ahora, nuestra password de Azure Redis, la almacena Azure Key Vault, por tanto, tenemos que decirle a nuestro componente que utilice Key Vault en lugar de que use el valor en texto plano. La propiedad «secretKeyRef» indica esta referencia. Además, la sección «auth«, permite especificar el nombre del componente que tendrá la información del secreto (Key Vault).

apiVersion: dapr.io/v1alpha1
kind: Component
metadata:
  name: statestore
  namespace: default
spec:
  type: state.redis
  version: v1
  metadata:
  - name: redisHost
    value: dapr.redis.cache.windows.net:6380
  - name: redisPassword
    secretKeyRef:
      name: redis-password
      key:  redis-password
  - name: enableTLS   # <-- This is the important part missing in the docs
    value: "true"   
auth:
  secretStore: secretstore

Azure Table Storage

Creamos el nuevo componente en la carpeta «./components/azure/secrets», con el nombre: «azure-tablestorage-with-keyvault.yaml«. Recordemos que el nombre del componente es el valor referenciado por «metadata.name». es decir: «statestore«. Igualmente, hacemos uso de la propiedad «secretKeyRef» y especificamos en la sección «auth» la referencia al componente de secreto.

apiVersion: dapr.io/v1alpha1
kind: Component
metadata:
  name: statestore
  namespace: default
spec:
  type: state.azure.tablestorage
  version: v1
  metadata:
  - name: accountName
    value: "daprdemo1" 
  - name: accountKey
    secretKeyRef:
      name: azureStorageKey
      key:  azureStorageKey
  - name: tableName
    value: daprdemotable 
auth:
  secretStore: secretstore 

Para finalizar, ejecutamos el programa con la siguiente instrucción

dapr run --app-id DaprClient --components-path ./components/azure/secrets -- dotnet run 0

En ambos ejemplos hemos usado Key Vault como Secret para el almacenamiento de información sensible, si bien, podríamos haber utilizado cualesquiera de los actualmente soportados. ¡Sería suficiente con sustituir el componente «secretstore»!

Nota: Si durante la ejecución obtenemos un error con un mensaje similar a este: «StatusCode = «FailedPrecondition»,  Detail = secret store is not configured«, es posible que el formato de los ficheros «.yaml» de los componentes no sea el correcto. ¡Revisémoslo!

Happy #Dapr Coding !!!

Referencias:

Anuncio publicitario

7 comentarios sobre “Introducción a Dapr .NET SDK (3/N): Secrets

Deja una respuesta

Introduce tus datos o haz clic en un icono para iniciar sesión:

Logo de WordPress.com

Estás comentando usando tu cuenta de WordPress.com. Salir /  Cambiar )

Imagen de Twitter

Estás comentando usando tu cuenta de Twitter. Salir /  Cambiar )

Foto de Facebook

Estás comentando usando tu cuenta de Facebook. Salir /  Cambiar )

Conectando a %s

Este sitio usa Akismet para reducir el spam. Aprende cómo se procesan los datos de tus comentarios.