Workload identity and SPIFFE
When a pipeline, a Kubernetes pod, or an AI agent calls your MCP server, how does the server know what is calling — not just that someone holds a valid secret? That's the problem workload identity solves.
The credential ladder
AuthSec supports three M2M credential types. They form a security ladder:
| Method | What proves identity | What can leak |
|---|---|---|
| Client secret | A shared string | The secret itself — anyone who has it is the caller |
| Private-key JWT | A signed assertion | The private key file — but it never crosses the wire |
| SPIFFE SVID | Platform attestation | Nothing — identity is bound to the running workload, not a stored file |
The first two are something you know (a secret or a key). SPIFFE is something you are — the platform itself vouches that this pod, in this namespace, running this service account, is the workload it claims to be.
What is SPIFFE?
SPIFFE (Secure Production Identity Framework For Everyone) is an open standard that gives every workload a cryptographic identity — without secrets, certificates you manage, or credentials you rotate.
The key concepts:
| Term | What it is |
|---|---|
| SPIFFE ID | A URI that uniquely identifies a workload: spiffe://trust-domain/path (e.g. spiffe://acme.prod/ns/default/sa/order-service) |
| SVID | SPIFFE Verifiable Identity Document — a short-lived JWT or X.509 cert that proves the workload holds that SPIFFE ID |
| Trust domain | A boundary of trust (your org, cluster, or environment). Workloads in the same trust domain can verify each other's SVIDs. |
| SPIRE | The production-ready runtime that implements SPIFFE. It runs an agent on each node that attests workloads and issues SVIDs. |
| Attestation | The process SPIRE uses to verify a workload's identity before issuing an SVID — checking runtime attributes (K8s namespace, service account, pod labels, Unix UID) against registered selectors. |
Why it matters for AI workloads
AI agents and MCP server callers run in environments where traditional credentials break down:
The problems with stored secrets
- Secrets leak. Config files, env vars, container images, logs — every place a secret touches is a place it can be extracted.
- Secrets don't identify workloads. A client secret proves someone has the secret, not what is presenting it. Two pods sharing a secret are indistinguishable in audit logs.
- Rotation is a deployment event. Changing a secret requires coordinated rollouts. Miss one instance and it breaks.
- Secrets live forever unless someone actively rotates them. A leaked secret from six months ago still works.
What SPIFFE changes
- No stored credential. The SPIRE agent attests the pod at runtime based on what it is (namespace, service account, image), not what it holds. There is nothing to leak.
- Unique identity per workload. Every pod gets its own SVID with its own SPIFFE ID. Two pods running the same image in different namespaces have different identities.
- Auto-rotation. SVIDs live ~5 minutes. The SDK renews them transparently. No deployment coordination.
- Cryptographic proof. An SVID is a signed JWT that AuthSec can verify against the trust domain's OIDC discovery endpoint. No shared secret between the workload and AuthSec.
How SPIFFE fits into AuthSec
The trust chain:
- SPIRE attests the pod based on its runtime attributes.
- AuthSec trusts the SPIRE trust domain (registered once in the dashboard under Trusted Issuers).
- The MCP server trusts AuthSec (via the SDK's token validation).
No party stores or transmits a secret. Identity flows from the platform up through the token chain.
When to use SPIFFE vs other methods
| Use case | Recommended method | Why |
|---|---|---|
| Quick start, dev/test | Client secret | Simplest; security isn't the priority |
| Production service, no K8s | Private-key JWT | No secret on the wire; works anywhere with a keypair |
| Kubernetes workload | SPIFFE | Zero stored credentials; platform-native identity |
| Multi-cluster / multi-cloud | SPIFFE | One trust domain spans clusters; SPIRE handles federation |
| Compliance / zero-trust | SPIFFE | No secrets to audit, rotate, or leak; cryptographic proof of identity |
| AI agent acting for a user | ID-JAG (not M2M) | The agent needs user permissions, not machine identity |
SPIFFE beyond AuthSec
SPIFFE is not an AuthSec invention — it's a CNCF graduated project used across the industry:
- Service mesh identity — Istio, Linkerd, and Consul Connect use SPIFFE IDs for mTLS between services
- Secret management — HashiCorp Vault can authenticate workloads via SPIFFE SVIDs
- CI/CD identity — GitHub Actions OIDC tokens follow the same pattern (platform-attested identity for pipeline workloads)
- Multi-cloud federation — SPIRE can federate trust domains across AWS, GCP, Azure, and on-prem
AuthSec uses the same standard: register your SPIRE trust domain once, and any workload attested by that SPIRE deployment can authenticate to your MCP servers — no per-workload secret management.
Next steps
- Connect a Kubernetes workload — the step-by-step dashboard guide with screenshots
- SPIFFE SDK reference (Python) — the
SpiffeWorkloadIdentityandSpiffeSvidAuthclasses - SPIFFE SDK reference (Go) — the Go equivalent
- M2M method comparison — compare all three credential types