Howdy,Kloudy!
January 29, 2023

Dapr Secret Store Component Demonstration Using Minikube With a PowerShell App

Posted on January 29, 2023  •  6 minutes  • 1237 words  
Views
Table of contents

Introduction

The content curation process for this blog post exhausted me, and the reason is a distraction. Read and enjoy the funny story! I made a lot of trial and error before sharing it with you all. My previous blog post discussed using Dapr on Minikube with a PowerShell app. You can refer to the link below to learn about the use case of state store component

Fix the gap in handling secrets

I hope you read my previous blogs. If not, it’s okay! Here is the problem for which we get a fix.

Secrets in the YAML are bad - Key Vault

apiVersion: dapr.io/v1alpha1
kind: Component
metadata:
  name: azurekeyvault
spec:
  type: secretstores.azure.keyvault
  version: v1
  metadata:
  - name: vaultName
    value: "kv-howdykloudy-dev"
  - name: azureTenantId
    value: "d15f83d0-ed59-4e08-925a-e7445f64efe8"
  - name: azureClientId
    value: "9d5b1b0c-4a87-45b1-a012-de2d83e81ce8"
  - name: azureClientSecret
    value: "{YOUR-SUPER-SECRET}"

Secret Store

apiVersion: dapr.io/v1alpha1
kind: Component
metadata:
  name: eventregistrationresponse
spec:
  type: state.azure.tablestorage
  version: v1
  metadata:
    - name: accountName
      value: {STORAGE-ACCOUNT-NAME}
    - name: accountKey
      value: {STORAGE-ACCOUNT-KEY}
    - name: tableName
      value: {TABLE-NAME}
    - name: cosmosDbMode
      value: true    

I have secrets in YAML and also in the app. How to handle it securely?

App Secrets

What is covered in this blog post?

I value your time and recorded the Dapr secret store component demo using Minikube with a PowerShell app. Feel free to share your comments and feedback to improvise the content are most welcome

About the Secret Store Component

The Dapr Secret Store component is a feature in Dapr that enables you to store, manage, and retrieve secrets, such as passwords, keys, and certificates, in a secure and scalable manner. The Dapr Secret Store component is designed to be used in a microservices architecture, allowing you to independently store and manage secrets for each microservice.

Here are some key features of the Dapr Secret Store component:

Solution

This time, we only focus on running the PowerShell web application on the Minikube cluster and not locally! The image below depicts the high-level logical flow

high-level

Deploy a pod with a web application and inject a Dapr sidecar. The Dapr sidecar’s responsibility is to securely retrieve secrets from the Azure Key vault and communicate with Azure table storage. I know it’s much theory. Let me walk through the steps

Azure App Registration With Certificate

You can use the existing service principal with a certificate or secret key. Follow the steps if you need a new SPN with a certificate.

You can use Az CLI, PowerShell or REST API.

# Create a resource group
az group create -n "{RESOURCE-GROUP}" --location "{LOCATION}"

# Create a key vault
az keyvault create --location "{LOCATION}" --name "{KEY-VAULT-NAME}" --resource-group "{RESOURCE-GROUP}"

# Create a service principal and configure its access to Azure resources.
az ad sp create-for-rbac --name "{SPN-NAME}" --create-cert --cert "{CERT-NAME}" --keyvault "{KEY-VAULT-NAME}" --skip-assignment --years 1

# Set Key Vault Policy
az keyvault set-policy --name "{KEY-VAULT-NAME}" --object-id "{SPN-OBJECT-ID}" --secret-permissions get

# Download and store the PFX in a secure location
az keyvault secret download --vault-name "{KEY-VAULT-NAME}" --name "{CERT-NAME}" --encoding base64 --file "{CERT-NAME}.pfx"

Set up a local Docker registry

docker run -d -p 5000:5000 --restart=always --name registry registry:2

Docker Build & Tag

docker build -t localhost:5000/podeux:v1 . --no-cache

Push the image to the local registry

docker push localhost:5000/podeux:v1

Work with Minikube

# Start the Minikube
minikube start --vm-driver=hyperv

# Create a secret using kubectl - This is used in kubernetes
kubectl create secret generic dapr-cert --from-file=daprpcert.pfx
kubectl create secret generic tableparameter --from-literal=accountName='{STORAGE-ACCOUNT-NAME}' --from-literal=accountKey='{YOUR-STORAGE-ACCOUNT-KEY}' --from-literal=tableName='{TABLE-NAME}'

# Initiate the Dapr inside the Minikube cluster (kubernetes)
dapr init --runtime-version 1.0.0-rc.3 --kubernetes 

# Load the image (local registry)
minikube image load localhost:5000/podeux:v1 --overwrite=true

Explore the infrastructure

List the pods
kubectl get pods -A
Access the dashboard
# access the minikube dashboard
minikube dashboard

# access the dapr dashboard
dapr dashboard -k

Deploy the state store component

apiVersion: dapr.io/v1alpha1
kind: Component
metadata:
  name: azurekeyvault
  namespace: default
spec:
  type: secretstores.azure.keyvault
  version: v1
  metadata:
  - name: vaultName
    value: kv-dapr-dev
  - name: spnTenantId
    value: "{TENANT-ID}"
  - name: spnClientId
    value: "{CLIENT-ID}"
  - name: spnCertificate
    secretKeyRef:
      name: dapr-cert
      key:  daprpcert.pfx
auth:
    secretStore: kubernetes  
kubectl apply -f .\components\azurekeyvault.yaml

Deploy the App & Service

kind: Service
apiVersion: v1
metadata:
  name: podeux
  labels:
    app: podeux
spec:
  selector:
    app: podeux
  ports:
    - port: 3000
---
kind: Deployment
apiVersion: apps/v1
metadata:
  name: podeux
  labels:
    app: podeux
spec:
  replicas: 1
  selector:
    matchLabels:
      app: podeux
  template:
    metadata:
      labels:
        app: podeux
      annotations:
        dapr.io/enabled: "true"
        dapr.io/app-id: "podeux"
        dapr.io/app-port: "3000"
        dapr.io/log-as-json: "true"
        dapr.io/enable-debug: "true"
    spec:
      containers:
        - name: podeux
          image: localhost:5000/podeux:v1
          imagePullPolicy: Never
          ports:
            - containerPort: 3000
          resources: {}
kubectl apply -f .\manifest\deployment.yaml

Rollout

# To see the Deployment rollout status, run kubectl rollout status
kubectl rollout status deploy/podeux

Expose the Service

# Access the app through port 3000 (both app & target port in 3000)
kubectl port-forward service/podeux 3000:3000

# Alternative - Access the app through port 3500 (localhost)
kubectl port-forward service/podeux 3500:3000

Now, access the application from your local host - http://localhost:3000

Click on telegram button, the below code does the magic (access the secrets from KV through the Dapr API)

#region - Telegram
Add-PodeRoute -Method Get -Path '/telegram' -ScriptBlock {
    $Telegramtoken = (Invoke-RestMethod -Uri 'http://localhost:3500/v1.0/secrets/azurekeyvault/Telegramtoken' -ContentType 'application/json').Telegramtoken
    $Telegramchatid = (Invoke-RestMethod -Uri 'http://localhost:3500/v1.0/secrets/azurekeyvault/Telegramchatid' -ContentType 'application/json').Telegramchatid
    [Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12
    try {
        $Body = [PSCustomObject]@{
            Message = 'Secure Message Test'
        } | ConvertTo-Json -Compress
        Invoke-RestMethod -Uri "https://api.telegram.org/bot$($Telegramtoken)/sendMessage?chat_id=$($Telegramchatid)&text=$($Body)"
    }
    catch {
        Write-PodeHost -Object $($_.Exception.Response)
    } 
}
#endregion

To insert records, the below code calls Dapr API to communicate with Table Storage

$employeeId = $([string]::Concat($(Get-Random -Minimum 50), '-', 'empid'))
$key = $($employeeId)
$data = [PSCustomObject]@{
    first_name = $($WebEvent.Data.first_name)
    last_name  = $($WebEvent.Data.last_name)
}
$State = @(
    [ordered]@{
        key   = $key
        value = $($data)
    }
)
$Body = ConvertTo-Json -InputObject $State -Compress
Write-PodeHost -Object $($Body)
Invoke-RestMethod -Uri "http://localhost:3500/v1.0/state/eventregistrationresponse" -Method Post -Body $($Body) -ContentType 'application/json' -Verbose -ErrorAction Stop

References

Summary

The Dapr Secret Store component is a powerful tool for managing secrets in microservices applications, providing security, scalability, and ease of use. An exciting and essential feature, right? Go for it! Invest your time in building Darized / Dockerized apps and run them on Kubernetes.

Social Networking

Let us stay connected to learn, share and grow!