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:

  1. How workloads are identified
  2. How identities are represented
  3. 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-sa

SPIRE 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-service

Frontend verifies:

  1. Certificate signed by trusted SPIRE CA
  2. SPIFFE ID matches expected service
    Now frontend doesn’t trust: 10.1.2.5 or payment-service.default.svc
    It trusts: spiffe://company.com/payment-service Identity 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 abc123xyz

Problems:

  • 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=frontend

and issues:

spiffe://company.com/frontend

Frontend 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 mechanisms

Managing 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.com

without 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

TraditionalSPIFFE/SPIRE
API keysCryptographic workload identity
Long-lived certificatesShort-lived certificates
Manual provisioningAutomatic provisioning
Identity tied to machineIdentity tied to workload
Difficult rotationAutomatic rotation
Trust based on network locationTrust 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

  1. 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. ↩