Workload identity (SPIFFE/SPIRE)
Audience: DevOps / Platform engineers, Security architects
Time: ~25 min
Prerequisites: Custom (Kubernetes / Helm) or Kickstart Control Plane + at least one Bouncer.
Control Core v3.5 makes SPIFFE/SPIRE workload identity the default platform baseline. Every Bouncer and Control Plane component obtains a short-lived X.509 SVID, and internal traffic uses mutual TLS (mTLS) with hot certificate rotation. Static Bouncer API keys remain available only through an audited legacy flag (removed in a future major release).
TL;DR
- Helm chart ships SPIRE Server + Agent with
global.spire.enabled: true. - Bouncer env:
REQUIRE_WORKLOAD_IDENTITY=true,SPIFFE_ENDPOINT_SOCKET=unix:///run/spire/sockets/agent.sock. - SVIDs rotate at ≤4 hours (configurable); Bouncer SDS reloads certs in memory (0 ms downtime design).
- For upgrades without SPIRE on day 1: set
ALLOW_LEGACY_STATIC_AUTH=true(emitsSECURITY_WARNING_DEPRECATED_STATIC_AUTH_ACTIVE).
Architecture (operator view)
| Component | SPIFFE ID pattern | Attestor |
|---|---|---|
| Control Plane API | spiffe://controlcore.internal/ns/{env}/sa/control-plane | k8s_psat / aws_iid |
| Control Bridge (policy sync) | spiffe://controlcore.internal/ns/{env}/sa/control-bridge | k8s_psat |
| Bouncer PEP | spiffe://controlcore.internal/ns/{env}/sa/bouncer-{id} | k8s / docker / unix |
| PIP cache | spiffe://controlcore.internal/ns/{env}/sa/pip-redis-cache | k8s / systemd |
Trust domain default: controlcore.internal. Override with global.spire.trustDomain / SPIFFE_TRUST_DOMAIN.
Helm values
global:
spire:
enabled: true
trustDomain: "controlcore.internal"
serverPort: 8081
workloadSocketPath: "/run/spire/sockets/agent.sock"
svidMaxTTLHours: 4
requireWorkloadIdentity: true
allowLegacyStaticAuth: false
attestors:
k8sPsat: true
awsIid: true
unix: true
Troubleshooting: If Bouncer pods crash with
FATAL_SPIFFE_ATTESTATION_FAILED, confirm the SPIRE Agent DaemonSet is Ready and the socket is mounted at/run/spire/sockets/agent.sock. Checkkubectl logs -l app.kubernetes.io/component=spire-agent. Common causes: Agent not scheduled on the node, wrongSPIFFE_ENDPOINT_SOCKET, orREQUIRE_WORKLOAD_IDENTITY=truebefore SPIRE is healthy.
Bouncer environment variables
| Variable | Default | Purpose |
|---|---|---|
REQUIRE_WORKLOAD_IDENTITY | true | Abort startup if Workload API unreachable |
SPIFFE_ENDPOINT_SOCKET | unix:///run/spire/sockets/agent.sock | Workload API UDS |
SPIFFE_TRUST_DOMAIN | controlcore.internal | Trust domain |
SPIFFE_SVID_MAX_TTL_HOURS | 4 | Max SVID lifetime (defence may set 1) |
ALLOW_LEGACY_STATIC_AUTH | false | Audited Bearer API_KEY fallback |
SPIRE_ENABLED | true (Helm) | Enable SDS mTLS + agent |
Legacy Control Bridge WebSocket auth tokens are deprecated — prefer SPIFFE mTLS on the policy-sync stream.
Migration (v2.x → v3.5)
v3.5 REQUIRE_WORKLOAD_IDENTITY=true (default)
ALLOW_LEGACY_STATIC_AUTH=false
v3.6 Legacy flag requires explicit CISO audit log
Later Static auth engine removed
- Install SPIRE Server/Agent (chart default).
- Confirm Bouncer registers with a SPIFFE peer (Control Plane audit / PEP list).
- Set
ALLOW_LEGACY_STATIC_AUTH=falseafter validation. - Rotate away long-lived Bouncer API keys.
Troubleshooting: If registration fails with HTTP 401
SPIFFE workload identity required, either mount a valid SVID path or temporarily setALLOW_LEGACY_STATIC_AUTH=truewhile you finish SPIRE bring-up. Legacy mode logsSECURITY_WARNING_DEPRECATED_STATIC_AUTH_ACTIVEto SIEM.
Certificate rotation monitoring
- SPIRE Agent rotates SVIDs at 50% of TTL (e.g. every 2 hours for a 4-hour cert).
- Bouncer pulls updates via SDS over the Workload API socket — no Bouncer restart.
- Alert if Agent memory exceeds 64 MB or if
FATAL_SPIFFE_ATTESTATION_FAILEDappears in Bouncer logs.
Compliance mapping
Supports continuous identity verification for NIST SP 800-207, SOC 2 CC6.8, CCCP / CPCSC Level 3, OSFI B-13, and FIPS 140-3 crypto providers used by SPIRE.