← Week 2: SPIRE Internals and Attestation

Day 8: SPIRE Architecture — Server, Agent, Workload

Phase 4 · August 12, 2026

← Week 2: SPIRE Internals and Attestation

Agenda (2–3 hours)

  • Read (60 min): SPIRE architecture docs; SPIRE server + agent config reference
  • Study (60 min): Understand the three-tier model before you deploy it
  • Sketch (30 min): Draw the data flow for SVID issuance
← Week 2: SPIRE Internals and Attestation

The Three Tiers

┌─────────────────────────────────────────────────────────────┐
│                      SPIRE Server                           │
│  - CA (signs SVIDs)           - Registration entries DB    │
│  - Node API (attests agents)  - Bundle endpoints           │
│  - gRPC port :8081            - Datastore (SQLite/Postgres) │
└─────────────────────────────┬───────────────────────────────┘
                              │  mutual TLS (bootstrap cert)
┌─────────────────────────────┴───────────────────────────────┐
│                      SPIRE Agent                            │
│  - Node attestation (at startup)                            │
│  - Workload attestation (per PID)                           │
│  - Caches SVIDs locally                                     │
│  - Serves Workload API (Unix socket)                        │
│  - One agent per node (VM, EC2 instance, k8s node)         │
└─────────────────────────────┬───────────────────────────────┘
                              │  Unix socket (no auth, kernel-attested)
┌─────────────────────────────┴───────────────────────────────┐
│                      Workload                               │
│  - Calls Workload API to receive SVID + trust bundle        │
│  - Uses SVID for mTLS or JWT-SVID for HTTP                 │
│  - No knowledge of SPIRE internals                         │
└─────────────────────────────────────────────────────────────┘
← Week 2: SPIRE Internals and Attestation

SPIRE Server Internals

The server has four main responsibilities:

1. CA — signs X.509 SVIDs for workloads

  • Can use its own in-memory CA (development)
  • Or delegate to an upstream CA (production: ACM PCA, Vault, etc.)
  • Key rotation happens automatically

2. Registration API — stores entries like:

Entry: spiffe://leo.amazon.com/ns/prod/svc/provisioning
  Parent SPIFFE ID: spiffe://leo.amazon.com/node/i-0abc123  ← the agent node
  Selectors: [unix:uid:1001, unix:path:/opt/svc/provisioning]

3. Node API — accepts attestation from agents, issues agent SVIDs
4. Bundle endpoint — HTTPS endpoint publishing the trust bundle JWK Set

← Week 2: SPIRE Internals and Attestation

SPIRE Agent Internals

The agent runs on each compute node (one per host):

Node attestation (once at agent startup):

  • Agent proves to the server that it's running on a legitimate node
  • On AWS: uses the Instance Identity Document (IID) + signature from AWS
  • Receives an agent SVID from the server

Workload attestation (per connecting workload):

  • When a process connects to the Workload API socket, the agent inspects:
    • /proc/<pid>/exe (binary path)
    • Process UID, GID
    • k8s pod labels (via k8s API)
    • Docker container metadata
  • Matches against registered entries → issues the matching SVID

SVID cache:

  • Agent caches SVIDs and refreshes them before expiry
  • Workloads stream updates from the agent — no polling needed
← Week 2: SPIRE Internals and Attestation

Key Config Files

SPIRE server (server.conf):

server {
  bind_address = "0.0.0.0"
  bind_port = "8081"
  trust_domain = "leo.amazon.com"
  data_dir = "/opt/spire/data/server"
  log_level = "INFO"
  ca_ttl = "168h"        // CA cert TTL
  default_svid_ttl = "1h"  // leaf SVID TTL
}

plugins {
  DataStore "sql" { ... }
  NodeAttestor "x509pop" { ... }
  KeyManager "memory" { ... }   // swap for disk or HSM in prod
  UpstreamAuthority "disk" { ... }  // or "aws_pca" for production
}

SPIRE agent (agent.conf):

agent {
  data_dir = "/opt/spire/data/agent"
  trust_domain = "leo.amazon.com"
  server_address = "spire-server"
  server_port = "8081"
}
plugins {
  NodeAttestor "aws_iid" { ... }
  WorkloadAttestor "unix" { ... }
  KeyManager "memory" { ... }
}
← Week 2: SPIRE Internals and Attestation

The SVID Issuance Flow

1. Agent starts → node attestation
   Agent → sends IID to Server
   Server → verifies IID with AWS → issues agent SVID

2. Workload connects to socket
   Agent → reads /proc/<pid>/exe, UID, GID
   Agent → queries: what entries match selectors [unix:uid:1001, path:...]?
   Server → returns matching entry: spiffe://leo.amazon.com/ns/prod/svc/provisioning

3. Agent → signs CSR with cached CA material → issues leaf SVID to workload
   (The agent caches the CA's signing cert; actual signing may happen on-agent or on-server)

4. Workload → receives X509SVIDResponse:
   cert DER + private key DER + trust bundle DER

Note: the workload never sends a CSR. The agent generates the key pair on behalf
of the workload and delivers the complete key + cert bundle.

← Week 2: SPIRE Internals and Attestation

Challenge Assignment

Study the SPIRE docs and answer these questions in your notes:

  1. What happens when the SPIRE server goes down? Can workloads still get SVIDs?
    (Hint: look at the agent's cache behavior)
  2. What is the default SVID TTL in SPIRE and how does it relate to the CA TTL?
  3. If you use SPIRE with an UpstreamAuthority "aws_pca" plugin, what does
    ACM PCA sign? The leaf SVIDs, or the intermediate CA cert?
  4. What plugin enables AWS IID node attestation? What does the agent send to
    prove it's on a legitimate EC2 instance?
  5. SPIRE's KeyManager "memory" means the CA key is in process memory.
    What are the security implications? What would KeyManager "disk" improve?
    What about an HSM-backed KeyManager?

Save answers in spiffe-analysis.md under "SPIRE Internals Notes."

← Week 2: SPIRE Internals and Attestation

Resources

  • SPIRE architecture: spiffe.io/docs/latest/architecture/spire
  • SPIRE server config reference: spiffe.io/docs/latest/deploying/spire_server
  • SPIRE agent config reference: spiffe.io/docs/latest/deploying/spire_agent
  • SPIRE plugins: github.com/spiffe/spire/tree/main/doc/plugin_server_*.md