Dapr mTLS Setup and Configuration Summary
Overview
Dapr supports in-transit encryption between Dapr instances using the Sentry service, which acts as a central Certificate Authority (CA). You can either bring your own certificates or let Dapr automatically create self-signed certificates.
Key Features:
- Automatic self-signed certificate generation (valid for 1 year)
- Support for custom certificates
- Certificate rotation capabilities
- Monitoring and alerting for certificate expiration
Configuration Structure
Control Plane Configuration
mTLS is configured through a Dapr Configuration resource:
apiVersion: dapr.io/v1alpha1
kind: Configuration
metadata:
name: daprsystem
namespace: default
spec:
mtls:
enabled: true
workloadCertTTL: "24h"
allowedClockSkew: "15m"
Kubernetes Deployment
Default Setup
- mTLS enabled by default when deploying Dapr to Kubernetes
- Certificates persisted to Kubernetes secrets in the Dapr system namespace
- Sentry service installed via Helm or Dapr CLI
Configuration Management
View current configuration:
kubectl get configurations/daprsystem --namespace <DAPR_NAMESPACE> -o yaml
Edit configuration:
kubectl edit configurations/daprsystem --namespace <DAPR_NAMESPACE>
Restart control plane after changes:
kubectl rollout restart deploy/dapr-sentry -n <DAPR_NAMESPACE>
kubectl rollout restart deploy/dapr-operator -n <DAPR_NAMESPACE>
kubectl rollout restart statefulsets/dapr-placement-server -n <DAPR_NAMESPACE>
Disabling mTLS
Via Helm:
kubectl create ns dapr-system
helm install \
--set global.mtls.enabled=false \
--namespace dapr-system \
dapr \
dapr/dapr
Via CLI:
dapr init --kubernetes --enable-mtls=false
Bring Your Own Certificates
Generate certificates using OpenSSL:
- Create configuration files (
root.conf
andissuer.conf
) - Generate root certificate and key:
openssl ecparam -genkey -name prime256v1 | openssl ec -out root.key
openssl req -new -nodes -sha256 -key root.key -out root.csr -config root.conf -extensions v3_req
openssl x509 -req -sha256 -days 365 -in root.csr -signkey root.key -outform PEM -out root.pem -extfile root.conf -extensions v3_req
- Generate issuer certificate and key:
openssl ecparam -genkey -name prime256v1 | openssl ec -out issuer.key
openssl req -new -sha256 -key issuer.key -out issuer.csr -config issuer.conf -extensions v3_req
openssl x509 -req -in issuer.csr -CA root.pem -CAkey root.key -CAcreateserial -outform PEM -out issuer.pem -days 365 -sha256 -extfile issuer.conf -extensions v3_req
Install with custom certificates:
kubectl create ns dapr-system
helm install \
--set-file dapr_sentry.tls.issuer.certPEM=issuer.pem \
--set-file dapr_sentry.tls.issuer.keyPEM=issuer.key \
--set-file dapr_sentry.tls.root.certPEM=root.pem \
--namespace dapr-system \
dapr \
dapr/dapr
Certificate Renewal
CLI-based renewal (Recommended):
Generate new certificates:
# Brand new certificates with new root key
dapr mtls renew-certificate -k --valid-until <days> --restart
# New certificates with existing root key (no downtime)
dapr mtls renew-certificate -k --private-key <private_key_file_path> --valid-until <days>
# Using custom certificates
dapr mtls renew-certificate -k --ca-root-certificate <ca.crt> --issuer-private-key <issuer.key> --issuer-public-certificate <issuer.crt> --restart
Manual certificate rotation:
# Update certificates via Helm
helm upgrade \
--set-file dapr_sentry.tls.issuer.certPEM=issuer.pem \
--set-file dapr_sentry.tls.issuer.keyPEM=issuer.key \
--set-file dapr_sentry.tls.root.certPEM=root.pem \
--namespace dapr-system \
dapr \
dapr/dapr
Avoiding Downtime
- Critical: Always sign new certificates with the same private root key
- If using different root key, restart Sentry service and all control plane components
- Restart application deployments:
kubectl rollout restart deploy/myapp
Self-Hosted Deployment
Setup Requirements
- mTLS disabled by default in self-hosted mode
- Manual configuration required
Running Sentry Service
# Create certificate directory
mkdir -p $HOME/.dapr/certs
# Run Sentry service
./sentry --issuer-credentials $HOME/.dapr/certs --trust-domain cluster.local
Dapr Instance Configuration
Configuration file:
apiVersion: dapr.io/v1alpha1
kind: Configuration
metadata:
name: daprsystem
namespace: default
spec:
mtls:
enabled: true
Environment variables (Linux/Mac):
export DAPR_TRUST_ANCHORS=`cat $HOME/.dapr/certs/ca.crt`
export DAPR_CERT_CHAIN=`cat $HOME/.dapr/certs/issuer.crt`
export DAPR_CERT_KEY=`cat $HOME/.dapr/certs/issuer.key`
export NAMESPACE=default
Environment variables (Windows):
$env:DAPR_TRUST_ANCHORS=$(Get-Content -raw $env:USERPROFILE\.dapr\certs\ca.crt)
$env:DAPR_CERT_CHAIN=$(Get-Content -raw $env:USERPROFILE\.dapr\certs\issuer.crt)
$env:DAPR_CERT_KEY=$(Get-Content -raw $env:USERPROFILE\.dapr\certs\issuer.key)
$env:NAMESPACE="default"
Run Dapr with mTLS:
# Using Dapr CLI
dapr run --app-id myapp --config ./config.yaml node myapp.js
# Using daprd directly
daprd --app-id myapp --enable-mtls --sentry-address localhost:50001 --config=./config.yaml
Custom Certificates (Self-Hosted)
Using step tool:
# Create root certificate
step certificate create cluster.local ca.crt ca.key --profile root-ca --no-password --insecure
# Create issuer certificate
step certificate create cluster.local issuer.crt issuer.key --ca ca.crt --ca-key ca.key --profile intermediate-ca --not-after 8760h --no-password --insecure
# Launch Sentry with custom certificates
./sentry --issuer-credentials $HOME/.dapr/certs --trust-domain cluster.local
Monitoring and Alerting
Certificate Expiration Monitoring
- Warning logs: Emitted 30 days before certificate expiration
- Log format: Hourly warnings in Sentry service logs
-
CLI status: Shows certificate expiration when running
dapr status -k
Example warning log:
{
"instance": "dapr-sentry-68cbf79bb9-gdqdv",
"level": "warning",
"msg": "Dapr root certificate expiration warning: certificate expires in 2 days and 15 hours",
"scope": "dapr.sentry",
"time": "2022-04-01T23:43:35.931825236Z",
"type": "log",
"ver": "1.6.0"
}
View Sentry logs:
kubectl logs --selector=app=dapr-sentry --namespace <DAPR_NAMESPACE>
Advanced Features
Token Validators
JWKS Validator Configuration:
kind: Configuration
apiVersion: dapr.io/v1alpha1
metadata:
name: sentryconfig
spec:
mtls:
enabled: true
tokenValidators:
- name: jwks
options:
minRefreshInterval: 2m
requestTimeout: 1m
source: "https://localhost:1234/"
caCertificate: "<optional ca certificate bundle string>"
Static JWKS Configuration:
kind: Configuration
apiVersion: dapr.io/v1alpha1
metadata:
name: sentryconfig
spec:
mtls:
enabled: true
tokenValidators:
- name: jwks
options:
minRefreshInterval: 2m
requestTimeout: 1m
source: |
{"keys":[ "12345.." ]}
Best Practices
Certificate Management
- Always use the same private root key when rotating certificates to avoid downtime
- Monitor certificate expiration 30 days in advance
- Set up automated alerts for certificate expiration warnings
- Test certificate rotation in non-production environments first
Production Considerations
- Configure monitoring for Sentry service logs
- Implement automated certificate renewal where possible
- Plan maintenance windows for certificate rotation if downtime is unavoidable
- Document certificate rotation procedures for your team
Security
- Protect private keys with appropriate file permissions
- Use strong certificate validity periods (not too short, not too long)
- Regular certificate rotation as part of security hygiene
- Audit certificate usage and access patterns
Top comments (0)
Some comments may only be visible to logged-in visitors. Sign in to view all comments.