Skip to main content

Zero Trust Microservices: Implementing SPIFFE/SPIRE & mTLS for Kubernetes Services

ยท 3 min read
Animesh Shaw
Founder & Lead Security Architect, AppSec Atlas
AppSec Atlas Research Team
Core Security Research & Contributor Group

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.