Module 6: Working with SVIDs and the Workload API
How applications consume and use SPIFFE identities
3 hours. 3 hands-on labs. Free course module.
Learning Objectives
- Use the SPIFFE Workload API programmatically
- Integrate SPIFFE into Go, Python, and Java applications
- Build mTLS connections between microservices
- Implement automatic certificate rotation in applications
Why This Matters
A workload identity system is useless if applications cannot consume the identities. This module bridges the gap between infrastructure (SPIRE) and application code — the integration point where most real-world problems occur.
Lesson Content
A workload identity system is only useful if applications can actually use the identities. This module covers how to integrate SPIFFE into applications — from zero-code approaches (SPIFFE Helper) to native library integration (go-spiffe, py-spiffe).
Integration Approaches
There are three ways to consume SPIFFE identities:
- SPIFFE Helper (zero code changes): A sidecar that fetches SVIDs and writes them as certificate files. Your application reads the files like any TLS certificate. Works with any language.
- Native libraries (code integration): Use go-spiffe, py-spiffe, or java-spiffe to call the Workload API directly. Provides automatic rotation callbacks and richer integration.
- Envoy sidecar (proxy-based): Envoy handles mTLS transparently. Your application communicates in plain HTTP; Envoy adds the identity layer. Covered in Module 8.
Using go-spiffe
package main
import (
"context"
"net/http"
"github.com/spiffe/go-spiffe/v2/spiffetls/tlsconfig"
"github.com/spiffe/go-spiffe/v2/workloadapi"
)
func main() {
ctx := context.Background()
// Connect to the Workload API
source, err := workloadapi.NewX509Source(ctx)
if err != nil {
log.Fatal(err)
}
defer source.Close()
// Create an mTLS server
tlsConfig := tlsconfig.MTLSServerConfig(
source, // Serve our SVID
source, // Verify client SVIDs
tlsconfig.AuthorizeAny(), // Or use AuthorizeID for specific SPIFFE IDs
)
server := &http.Server{
Addr: ":8443",
TLSConfig: tlsConfig,
}
server.ListenAndServeTLS("", "") // Certs from SPIRE, not files
}
Using SPIFFE Helper
# spiffe-helper.conf
agent_address = "/run/spire/sockets/agent.sock"
cmd = "/app/server" # Your application command
cert_dir = "/run/spire/certs" # Where to write certificates
svid_file_name = "svid.pem"
svid_key_file_name = "svid_key.pem"
svid_bundle_file_name = "bundle.pem"
renew_signal = "SIGHUP" # Signal to send when certs rotate
# Your app reads /run/spire/certs/svid.pem and svid_key.pem
# When certs rotate, your app gets SIGHUP to reload
Building mTLS Between Microservices
With SVIDs, two services can establish mTLS without manually managing certificates:
# Service A (client) connects to Service B (server):
# 1. Both services get SVIDs from SPIRE via Workload API
# 2. Service A presents its SVID as the client certificate
# 3. Service B presents its SVID as the server certificate
# 4. Both verify the other's SVID against the trust bundle
# 5. Connection established — both identities proven
# No manual certificate generation
# No certificate files to manage
# No expiration alerts — SPIRE handles rotation
Secure gRPC Communication
# gRPC with SPIFFE identity (Go):
# Server:
source, _ := workloadapi.NewX509Source(ctx)
creds := grpc.Creds(credentials.NewTLS(
tlsconfig.MTLSServerConfig(source, source, authorize),
))
server := grpc.NewServer(creds)
# Client:
source, _ := workloadapi.NewX509Source(ctx)
creds := grpc.WithTransportCredentials(credentials.NewTLS(
tlsconfig.MTLSClientConfig(source, source, authorize),
))
conn, _ := grpc.Dial("service-b:8443", creds)
Real-World Use Cases
- Go microservices using go-spiffe for native mTLS
- Legacy Java applications using SPIFFE Helper for zero-code integration
- Python services using py-spiffe for Workload API access
- gRPC services with SPIFFE TLS credentials for inter-service auth
Production Notes
- For new services: use go-spiffe or py-spiffe for native integration. For legacy services: use SPIFFE Helper to write certs to disk with zero code changes.
- Always configure a renewal signal (SIGHUP) with SPIFFE Helper so applications reload certificates on rotation.
- In production, use the Envoy sidecar approach when you cannot modify application code and need mTLS transparently.
Common Mistakes
- Not handling SVID rotation callbacks — applications crash when certs expire
- Hardcoding socket paths instead of using the SPIFFE_ENDPOINT_SOCKET environment variable
- Using SPIFFE Helper without configuring the renew_signal — certs rotate but the app keeps using old ones
- Fetching SVIDs on every request instead of caching and watching for rotation
Design Tradeoffs
SPIFFE Helper (sidecar)
Pros
- Zero application code changes
- Works with any language
- Writes standard PEM files
Cons
- Requires sidecar management
- Signal-based reload can miss rotations
- Extra process per pod
go-spiffe (library)
Pros
- Native API integration
- Automatic rotation callbacks
- Fine-grained control
Cons
- Go-only
- Requires code changes
- Adds dependency
Envoy sidecar (proxy)
Pros
- Transparent mTLS
- No app changes
- L7 features (routing, auth)
Cons
- Resource overhead
- Complex config
- Latency from proxy hop
Key Terms
- SPIFFE Helper
- Sidecar that writes SVIDs as PEM files to disk
- go-spiffe
- Official Go library for Workload API integration
- Workload API Socket
- Unix domain socket at /run/spire/sockets/agent.sock
- SIGHUP
- Signal sent to applications to trigger certificate reload
Hands-On Labs
-
Getting SVIDs with SPIFFE Helper
Use SPIFFE Helper for zero-code SVID integration.
- Deploy SPIFFE Helper as a sidecar container
- Configure certificate file paths
- Verify SVIDs are written to disk
- Configure an Nginx server to use the SVID certificates
-
Building mTLS Between Microservices
Establish mutual TLS between two Go services using go-spiffe.
- Build a Go server that serves with its SVID
- Build a Go client that authenticates with its SVID
- Verify mTLS connection with both identities
- Test that a service without a valid SVID is rejected
-
Secure gRPC Communication
Secure gRPC services with SPIFFE identities.
- Create a gRPC server with SPIFFE TLS credentials
- Create a gRPC client with SPIFFE TLS credentials
- Verify mutual authentication via SPIFFE IDs
- Implement SPIFFE ID-based authorization in the server
Key Takeaways
- SPIFFE Helper enables zero-code integration — writes certs to files
- go-spiffe provides native Workload API integration with auto-rotation
- mTLS between services requires no manual certificate management with SPIRE
- gRPC integrates natively with SPIFFE via TLS credentials
- Choose your approach: sidecar (any language), library (Go/Python/Java), or proxy (Envoy)