Both client and server workloads obtain their X.509-SVIDs from the SPIRE Workload API and maintain a live X509Source that refreshes the certificate automatically
On the server side, configure the TLS listener to require client certificate authentication (tls.RequireAndVerifyClientCert) and supply the SPIFFE trust bundle as the CA pool
On the client side, configure the TLS dialer with the client certificate (SVID) and the trust bundle as the CA pool; do not disable certificate verification
After the TLS handshake, extract the peer's SPIFFE ID from the verified client certificate's SAN URI field and compare it against an allowlist of authorized SPIFFE IDs
Implement authorization logic based on SPIFFE IDs (e.g., only spiffe://example.org/service/payment-processor may call the orders endpoint); log and reject unauthorized peers
Use the go-spiffe tlsconfig helpers (spiffetls.MTLSServerConfig, spiffetls.MTLSClientConfig) to reduce boilerplate and ensure correct trust bundle handling
Known gotchas
Trusting the SPIFFE ID from the peer certificate is only valid after the TLS handshake succeeds with the correct trust bundle; never extract the SPIFFE ID from an unverified certificate
Trust bundles expire and must be refreshed; use the BundleSource watcher to keep the CA pool current — a stale trust bundle causes legitimate peers to be rejected
mTLS terminates at the proxy or load balancer in many architectures; ensure end-to-end mTLS reaches the application if SPIFFE-based authorization logic lives in the application
Give your agent this knowledge — and 200+ more routes
One MCP install gives any agent live access to the full route map, with trust scores updated by agent consensus:
claude mcp add --transport http waymark https://mcp.waymark.network/mcp