When you deploy Dapr sidecars alongside your Task API, traffic between sidecars is already encrypted with mTLS. This happens automatically—Dapr's Sentry service acts as a Certificate Authority, issuing short-lived certificates to each sidecar. But "automatically encrypted" is not the same as "production secure."
In January 2024, a fintech company discovered their Dapr deployment had a critical gap: while sidecar-to-sidecar traffic was encrypted, any application in the cluster could access any Dapr component. Their Redis statestore—containing session tokens—was accessible from a compromised logging pod in a different namespace. The fix was component scopes: a single YAML field that took 30 seconds to add but prevented a potential breach.
This lesson teaches you to verify the security Dapr provides automatically, then add the isolation controls it doesn't enable by default.
Before adding security controls, confirm Dapr's automatic protections are working. The Sentry service must be healthy and issuing certificates.
Output:
What to verify:
If dapr-sentry shows anything other than Running, mTLS certificates cannot be issued and sidecar communication fails.
Check the root certificate that Sentry uses to sign sidecar certificates:
Output:
What this tells you:
Sidecar certificates have a 24-hour TTL by default, but they depend on this root CA. If the root expires, all sidecars lose their trust anchor.
From inside a sidecar, verify certificates are being used:
Output:
The presence of these files confirms:
If these files are missing, mTLS is not configured—check your Dapr installation.
You've verified mTLS is working, but the commands you just ran aren't obvious. Let's see how AI collaboration helps you discover these verification techniques.
You need to verify Dapr security but aren't sure what to check:
AI suggests a verification approach you hadn't considered:
"Beyond checking dapr-sentry status, you should verify three levels:
For ongoing monitoring, I'd also suggest enabling the Dapr metrics endpoint and tracking certificate renewal events. Here's a command to check certificate days until expiry:
This gives you a single number for monitoring dashboards."
The AI suggested a monitoring approach—certificate expiry tracking—that you hadn't asked about but is critical for production. This is knowledge transfer: AI teaches you a pattern you didn't know existed.
By default, any Dapr-enabled application can access any Dapr component. This violates least privilege—your Task API shouldn't be able to access another service's statestore.
Without scopes, your cluster has this access matrix:
Any compromised pod with a Dapr sidecar can access all components.
Update your Redis statestore component to restrict access:
Output:
Output:
Try to access the statestore from a different application:
Output:
The component exists, but it's invisible to applications not in the scopes list. This is security through explicit allowlisting—the same pattern as NetworkPolicy default-deny.
After adding scopes, your access matrix becomes:
Each component should have a minimal scopes list.
Your initial component scope configuration assumed production requirements. But development and production have different needs. Let's iterate with AI to handle both environments.
After configuring scopes, you realize a gap:
"You could use Helm values to template the scopes list:
With values-dev.yaml:
And values-prod.yaml:
This keeps one component template with environment-specific scope lists."
The Helm approach adds complexity you don't want yet. You push back:
"Good constraint. Dapr components are namespace-scoped, so you can create separate component resources in each namespace:
production/statestore.yaml:
development/statestore.yaml:
Each namespace has its own component with appropriate scopes. No templating, standard Kubernetes patterns."
Neither you nor AI started with the namespace-per-environment approach:
This is collaborative refinement: the final solution emerged from iterating together.
mTLS encrypts traffic and verifies sidecar identity. API tokens add another layer: authenticating individual requests between the Dapr sidecar and your application.
For most Kubernetes deployments, mTLS between sidecars is sufficient. Add API tokens when:
Add annotation to your deployment:
Your application now must include the token in requests to its sidecar:
Without the token:
Output:
With the token:
Output:
By default, the Dapr sidecar listens on all interfaces (0.0.0.0). In a shared pod network, this could allow other containers to call your sidecar. Restrict to localhost:
This ensures only the main application container can reach the sidecar—defense in depth alongside component scopes.
Here's the full security configuration for your Task API deployment:
Security checklist applied:
Test your cloud-security skill against Dapr security patterns:
If any answers are "no," update your skill with the patterns from this lesson.
Test your understanding of Dapr security configuration and troubleshooting.
Prompt 1:
What you're learning: Certificate lifecycle management. The solution involves checking Sentry CA expiry with openssl x509 -enddate and running dapr mtls renew-certificate -k if needed. Notice if AI explains the difference between sidecar certificates (24h TTL, auto-renewed) and the root CA (1 year, manual renewal).
Prompt 2:
What you're learning: Least-privilege component design. Each component needs its own scopes array, not a single shared configuration. Notice if AI creates separate component definitions or tries to use a single component with multiple scopes.
Prompt 3:
What you're learning: Security threat modeling. For single-container pods with mTLS, API tokens add minimal value since localhost is already isolated. The scenario where tokens matter is multi-container pods or external Dapr API exposure. Notice if AI asks clarifying questions about your deployment model.
Component scopes are your primary defense against lateral movement through Dapr. A compromised pod without Dapr components in its scope list cannot access state stores, pub/sub, or secrets through Dapr APIs—even if the attacker has full control of the pod. Always apply least-privilege scopes before deploying to production.