One of the core zero trust principles is "never trust, always verify" -- and that includes service-to-service communication. Here is how I implemented mTLS across AWS, Azure, and GCP using SPIFFE and SPIRE.
Why Not Just Use a Service Mesh?
Service meshes (Istio, Linkerd) handle mTLS beautifully within a single Kubernetes cluster. The problem starts when you need mTLS between:
- Services in Kubernetes and services on EC2 instances
- Services across different cloud providers
- Services running on-premises that need to communicate with cloud workloads
SPIFFE provides a universal identity framework. SPIRE is the reference implementation. Together, they issue short-lived X.509 certificates to workloads regardless of where they run.
Architecture Overview
+-----------------+
| SPIRE Server |
| (Root CA) |
+--------+--------+
|
+--------------+--------------+
| | |
+--------+------+ +----+----+ +-------+------+
| SPIRE Agent | | Agent | | Agent |
| (AWS EKS) | | (Azure) | | (GCP GKE) |
+--------+------+ +----+----+ +-------+------+
| | |
+--------+------+ +----+----+ +-------+------+
| Workload A | | Work. B | | Workload C |
| SVID issued | | SVID | | SVID issued |
+---------------+ +---------+ +--------------+
Key Design Decisions
Certificate TTL of 1 hour. Short-lived certificates mean compromised credentials expire quickly.
Trust domain per organization, not per cloud.
mycompany.comspans all three clouds. Workloads in AWS can validate certificates from GCP workloads because they share a trust domain.Kubernetes PSAT attestation. This ties SPIFFE identity to Kubernetes service accounts.
Debugging mTLS Failures
The most common failure: "certificate signed by unknown authority." This means the client does not trust the SPIRE server CA. Check:
# Verify the SVID was issued
spire-agent api fetch x509 -socketPath /run/spire/sockets/agent.sock
# Check trust bundle
openssl x509 -in svid.pem -text -noout | grep Issuer
Full zero trust architecture guide: Zero Trust Multi-Cloud
Top comments (0)