kubernetes distributedsystem/microservice
Introduction to SPIFFE
SPIFFE Overview
Attestation & Workload Identity
Tldr
SPIFFE defines a standard identity for workloads (
spiffe://...), while SPIRE is the system that automatically discovers workloads, verifies them, issues identities, rotates certificates, and enables secure mTLS communication between services.SPIFFE is an identity system, not a networking system
SPIFFE’s job is to answer one question: “Who is this workload?” It issues cryptographic identity documents (SVIDs) — what you do with that identity is entirely up to you. mTLS is just one consumer of those SVIDs.
Introduction
SPIFFE and SPIRE are technoligies used to give workloads (applications, services, containers, VMs, etc.) a secure, cryptographically verifiable identity in distribited systems, especially cloud-native envoroment like Kubernetes.
A simple way to think about them:
- SPIFFE = the identity standard (“what identities look like”)
- SPIRE = a reference implementation (“software that issues and manages those identities”)
Why do they exist ?
In a Microservices architecture, hundreds or thousands of services communicate with each other.
Questions arise:
- How does Service A know it’s really talking to Service B?
- How can workloads authenticate without hardcoded passwords or API keys?
- How can identities be managed across multiple clusters or clouds?
SPIFFE and SPIRE solve these problems using workload identities and Mutual TLS (mTLS).
SPIFFE
SPIFFE stands for Secure Production Identity Framework For Everyone.
It is an open standard that defines:
- How workloads are identified
- How identities are represented
- How identities are verified
SPIFFE ID
Every workload gets a unique identifier similar to a URI: spiffe://example.org/payment-service
Examples:
spiffe://company.com/frontend
spiffe://company.com/backend
spiffe://company.com/database
These IDs are:
- Globally unique
- Cryptographically bound to certificates
- Independent of IP addresses
Unlike IP addresses, identities stay meaningful even when workloads move between nodes or clouds.
SPIFFE Verifiable Identity Document (SVID)
A workload proves its identity using an SVID.
Think of an SVID as:
“A certificate that says this workload owns this SPIFFE ID.”
Common formats:
- X.509 certificates (most common)
- JWT tokens
Example: SPIFFE ID:spiffe://company.com/payment-service
Bound to an X.509 certificate used for mTLS.
SPIRE
SPIRE stands for SPIFFE Runtime Environment.
SPIRE implements the SPIFFE specifications.
Its job is to:
- Discover workloads
- Verify them
- Issue SPIFFE identities
- Rotate certificates automatically
SPIRE Architecture
SPIRE Server
The central authority.
Responsibilities:
- Maintains trust roots
- Issues identities
- Signs certificates
- Stores registration entries
SPIRE Agent
Runs on each node.
Responsibilities:
- 1Attests the node
- Attests workloads
- Requests identities from SPIRE Server
- Delivers certificates to workloads
Attestation
Attestation is one of SPIRE’s most important concepts.
Node Attestation
Before a node can receive identities, SPIRE must trust the node.
Examples:
- AWS EC2 instance identity
- GCP instance identity
- Azure VM identity
- TPM hardware identity
- Kubernetes node identity
Result: "This really is node-123."
Workload Attestation
Once a node is trusted, SPIRE verifies workloads.
Examples:
- Kubernetes service account
- Pod labels
- Namespace
- Container metadata
- Unix UID/GID
Result: "This pod is the payment service."
SPIRE can then issue: spiffe://company.com/payment-service to that workload.
Example Flow
Imagine two services: frontend, backend
Step 1
Frontend starts.
SPIRE Agent identifies it: namespace=webserviceaccount=frontend
SPIRE issues: spiffe://company.com/frontend
Step 2
Backend starts. SPIRE issues: spiffe://company.com/backend
Step 3
Frontend connects to backend using mTLS.
During TLS handshake:
- Frontend presents:
spiffe://company.com/frontend - Backend presents:
spiffe://company.com/backend
Both verify certificates. No passwords, API keys, or shared secrets are needed.
SPIFFE + Service Meshes
SPIFFE is commonly used with service meshes.
Examples include: Istio, Linkerd, Consul
Many service meshes use SPIFFE IDs internally for workload identity.
Example: spiffe://cluster.local/ns/default/sa/frontend
Kubernetes Example
A pod might have:
apiVersion: v1
kind: Pod
metadata:
namespace: payments
spec:
serviceAccountName: payment-saSPIRE can map that pod to: spiffe://company.com/payment-service
The application receives a certificate automatically.
Certificate Rotation
One major advantage of SPIRE:
- Certificates are short-lived
- Automatically renewed
- Automatically distributed
Instead of: Certificate expires in 1 year
you might have: Certificate expires in 1 hour and SPIRE transparently rotates it. This greatly reduces risk if a certificate is compromised.
Federation
One powerful SPIFFE feature is trust federation.
Imagine: Company A, Company B
Each has its own SPIFFE trust domain: spiffe://company-a.com/... , spiffe://company-b.com/...
Federation allows workloads from both organizations to trust each other without sharing internal infrastructure.
How addressed the questions ?
1. How does Service A know it’s really talking to Service B?
Traditional approach
Suppose you have: frontend --> payment-service
The frontend calls: http://payment-service.default.svc.cluster.local
The problem is that DNS names and IP addresses don’t prove identity.
If an attacker manages to:
- Deploy a rogue pod, Spoof traffic, Misconfigure routing
then frontend may unknowingly talk to the wrong service.
With TLS only
You can use TLS certificates: frontend <--TLS--> payment-service
But then you must answer:
- Who issued the certificate?
- Is the certificate really for payment-service?
- How do we rotate it?
Managing this at scale becomes difficult.
With SPIFFE
Payment service gets: spiffe://company.com/payment-service
Frontend gets: spiffe://company.com/frontend
During mTLS: frontend <---- mTLS ----> payment-service
both sides exchange certificates.
The payment service certificate contains:
SPIFFE ID:
spiffe://company.com/payment-serviceFrontend verifies:
- Certificate signed by trusted SPIRE CA
- SPIFFE ID matches expected service
Now frontend doesn’t trust:10.1.2.5orpayment-service.default.svc
It trusts:spiffe://company.com/payment-serviceIdentity instead of location.
Why Identity Is Better Than IP Addresses
Imagine Kubernetes reschedules a pod.
Before: payment-service = 10.1.1.5
After restart: payment-service = 10.1.8.27
IP changed. The SPIFFE identity remains: spiffe://company.com/payment-service
Applications continue working. This is especially useful in Kubernetes because pods are constantly being recreated.
2. How can workloads authenticate without hardcoded passwords or API keys?
This is often the biggest operational benefit.
Traditional API key model
Frontend stores: PAYMENT_API_KEY=abc123xyz
Then:
frontend ---> payment-service
Authorization: Bearer abc123xyzProblems:
- Secrets must be stored
- Secrets must be rotated
- Secrets can leak
- Every service needs secret management
In a large microservice environment: you may end up with hundreds of shared secrets.
With SPIFFE
No API keys.
When frontend starts: SPIRE verifies:
namespace=web
serviceaccount=frontendand issues:
spiffe://company.com/frontendFrontend proves its identity using its certificate.
Payment service checks: Who are you?
Certificate says: spiffe://company.com/frontend
Payment service trusts the certificate because SPIRE signed it. No shared secret exists.
Analogy
API keys are like: Anyone who knows the password can enter.
SPIFFE is like: Show me your government-issued ID. I’ll verify it was issued by a trusted authority.
The workload carries its own identity.
3. How can identities be managed across multiple clusters or clouds?
This becomes important in large organizations.
Suppose you have: AWS Cluster running: frontend, orders, payments and: GCP Cluster running: inventory, shipping,analytics
Without a unified identity system:
AWS certificates
GCP certificates
Different CAs
Different policies
Different trust mechanismsManaging trust becomes complicated.
SPIFFE Trust Domains
A SPIFFE ID contains a trust domain: spiffe://company.com/orders
Think of the trust domain as: company.com All workloads in every cluster share the same identity namespace.
Cluster A : spiffe://company.com/frontend
Cluster B : spiffe://company.com/inventory
Cluster C : spiffe://company.com/shipping
All identities follow the same format.
Federation
Now imagine two organizations:
Company A : spiffe://company-a.com/*
Company B: spiffe://company-b.com/*
Normally they don’t trust each other.
SPIFFE federation allows:
company-a.com
trust
company-b.comwithout sharing infrastructure. A service can verify: This certificate belongs to
spiffe://company-b.com/payments and decide whether to allow access.
Kubernetes Workload API vs SPIFFE Workload API

Comparison with Traditional Approaches
| Traditional | SPIFFE/SPIRE |
|---|---|
| API keys | Cryptographic workload identity |
| Long-lived certificates | Short-lived certificates |
| Manual provisioning | Automatic provisioning |
| Identity tied to machine | Identity tied to workload |
| Difficult rotation | Automatic rotation |
| Trust based on network location | Trust based on verified identity |
Real-World Use Cases
Organizations use SPIFFE/SPIRE for:
- Zero Trust Network
- Don’t trust a workload because it’s inside the cluster. Trust it only if it presents the correct verified identity.
- Service-to-service authentication
- Multi-cluster Kubernetes deployments
- Multi-cloud environments
- Service Meshes
- Secure workload federation between environments
Footnotes
-
Attest means to bear witness, certify, or provide evidence that something is true, genuine, or authentic. It is typically used to confirm a fact based on personal knowledge, expertise, or official observation. ↩