
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:
- Introducción a Dapr .NET SDK (1/N) y Service-to-service invocation
- Introducción a Dapr .NET SDK (2/N): State management
- [ ->] Introducción a Dapr .NET SDK (3/N): Secrets
- Introducción a Dapr .NET SDK (4/N): Pub/Sub
- Introducción a Dapr .NET SDK (5/N): Bindings y Triggers
- Introducción a Dapr .NET SDK (6/N): Debugging (VSCode y VS) + Sidekick
- Introducción a Dapr .NET SDK (7/N): Docker Compose and HTTPS
- Introducción a Dapr .NET SDK (8/N): Kubernetes mode
- 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í.
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:
Reblogueó esto en El Bruno.
Me gustaMe gusta