Zero Trust Microservices: Implementing SPIFFE/SPIRE & mTLS for Kubernetes Services
In modern cloud-native Kubernetes environments, relying on perimeter firewalls, network security groups, or hardcoded API keys for microservice-to-microservice authentication is no longer sufficient. If an attacker compromises a single pod inside a VPC, unauthenticated internal networks allow lateral movement across the entire cluster.
Zero Trust Architecture (NIST SP 800-207) dictates a fundamental shift: Never Trust, Always Verify. In this article, we explore how to establish cryptographic workload identity using SPIFFE/SPIRE and enforce Mutual TLS (mTLS) via Envoy sidecar proxies.
What is SPIFFE/SPIRE?โ
- SPIFFE (Secure Production Identity Framework for Everyone): A set of open standards defining how workloads acquire short-lived, cryptographically verifiable identities represented as SPIFFE IDs (e.g.,
spiffe://example.org/ns/prod/sa/payment-service) in X.509 certificates (SVIDs). - SPIRE (SPIFFE Runtime Environment): The production-ready reference implementation that performs node and workload attestation (verifying Kubernetes namespace, service account, pod UID, and binary hash) before issuing SVID certificates.
Step-by-Step Production Architectureโ
1. Workload Attestationโ
When a pod requests an identity certificate, the local SPIRE Agent queries the Kubernetes API server to verify:
- Pod Namespace (
prod) - ServiceAccount Name (
payment-sa) - Container Image SHA-256 Digest
2. SVID Certificate Rotationโ
SPIRE automatically issues short-lived X.509 SVIDs (typically valid for 1 hour) directly into container memory via the SPIFFE Workload API, eliminating disk storage of private keys.
3. Envoy Sidecar mTLS Verificationโ
Envoy proxies intercept incoming gRPC/REST traffic, validate the client certificate chain against the SPIRE Trust Bundle, and assert the client's SPIFFE ID in SPIFFE SAN URI extensions.
# Envoy Proxy Hardened TLS Context Configuration
static_resources:
listeners:
- name: ingress_listener
address:
socket_address: { address: 0.0.0.0, port_value: 8443 }
filter_chains:
- transport_socket:
name: envoy.transport_sockets.tls
typed_config:
"@type": type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.DownstreamTlsContext
common_tls_context:
tls_certificates:
- certificate_chain: { filename: "/spiffe-workload-api/svid.pem" }
private_key: { filename: "/spiffe-workload-api/svid_key.pem" }
validation_context:
trusted_ca: { filename: "/spiffe-workload-api/bundle.pem" }
match_typed_subject_alt_names:
- san_type: URI
matcher:
exact: "spiffe://appsecatlas.org/ns/prod/sa/order-service"
Summary & Next Stepsโ
Cryptographic workload identity with SPIFFE/SPIRE eliminates hardcoded credentials, defends against SSRF/lateral movement, and satisfies NIST SP 800-207 Zero Trust requirements.
For complete hands-on Terraform/Kubernetes manifests and Python/Go code samples, check out the Zero Trust Architecture Guide and Container & K8s Security Guide in AppSec Atlas.
