Skip to main content

SPIRE

SPIFFE Runtime Environment for workload identity and service-to-service authentication.


Overview

SPIRE provides cryptographic identities (SVIDs) to workloads, enabling mutual TLS (mTLS) between services without managing certificates manually.

PropertyValue
Server Imageghcr.io/spiffe/spire-server:1.11.1
Agent Imageghcr.io/spiffe/spire-agent:1.11.1
Containersspire-server, spire-agent
Trust Domainravenhelm.dev
Status⚠️ Deployed, Agent Attestation Issues

Architecture

┌─────────────────────────────────────────────────────────────┐
│ SPIRE SERVER │
│ - Issues SVIDs (X.509 certificates, JWT tokens) │
│ - Maintains registration entries │
│ - Trust domain: spiffe://ravenhelm.dev │
└─────────────────────────────────────────────────────────────┘

Agent Attestation

┌─────────────────────────────────────────────────────────────┐
│ SPIRE AGENT │
│ - Runs on each node (Docker host) │
│ - Attests workloads via Docker API │
│ - Provides Workload API (Unix socket) │
└─────────────────────────────────────────────────────────────┘

Workload Attestation

┌─────────────────────────────────────────────────────────────┐
│ WORKLOADS │
│ - Request SVIDs from Agent │
│ - Use for mTLS, JWT authentication │
│ - Identity: spiffe://ravenhelm.dev/service/name │
└─────────────────────────────────────────────────────────────┘

Configuration

SPIRE Server (/data/spire/server/server.conf)

server {
bind_address = "0.0.0.0"
bind_port = "8081"
trust_domain = "ravenhelm.dev"
data_dir = "/opt/spire/data"
log_level = "INFO"

# Certificate TTLs
ca_ttl = "168h" # CA: 7 days
default_x509_svid_ttl = "1h" # X.509: 1 hour
default_jwt_svid_ttl = "5m" # JWT: 5 minutes
}

plugins {
DataStore "sql" {
plugin_data {
database_type = "sqlite3"
connection_string = "/opt/spire/data/datastore.sqlite3"
}
}

NodeAttestor "join_token" {
plugin_data {}
}

KeyManager "disk" {
plugin_data {
keys_path = "/opt/spire/data/keys.json"
}
}

UpstreamAuthority "disk" {
plugin_data {
key_file_path = "/opt/spire/conf/server/dummy_upstream_ca.key"
cert_file_path = "/opt/spire/conf/server/dummy_upstream_ca.crt"
}
}
}

SPIRE Agent (/data/spire/agent/agent.conf)

agent {
data_dir = "/opt/spire/data"
log_level = "INFO"
server_address = "spire-server"
server_port = "8081"
trust_domain = "ravenhelm.dev"
insecure_bootstrap = true
join_token = "<token>"
}

plugins {
NodeAttestor "join_token" {
plugin_data {}
}

KeyManager "memory" {
plugin_data {}
}

WorkloadAttestor "docker" {
plugin_data {}
}
}

SPIFFE Identity Format

spiffe://ravenhelm.dev/<path>

Examples:
spiffe://ravenhelm.dev/service/docs/AI-ML-Platform/norns-agent
spiffe://ravenhelm.dev/service/bifrost-api
spiffe://ravenhelm.dev/workload/n8n

Quick Commands

# Check server health
docker exec spire-server /opt/spire/bin/spire-server healthcheck

# Check agent health
docker exec spire-agent /opt/spire/bin/spire-agent healthcheck

# View server logs
docker logs spire-server

# View agent logs
docker logs spire-agent

# List registration entries
docker exec spire-server /opt/spire/bin/spire-server entry show

# Generate new join token
docker exec spire-server /opt/spire/bin/spire-server token generate -spiffeID spiffe://ravenhelm.dev/agent/odin

# List agents
docker exec spire-server /opt/spire/bin/spire-server agent list

Register a Workload

# Create registration entry for a Docker container
docker exec spire-server /opt/spire/bin/spire-server entry create \
-parentID spiffe://ravenhelm.dev/agent/odin \
-spiffeID spiffe://ravenhelm.dev/service/docs/AI-ML-Platform/norns-agent \
-selector docker:label:com.docker.compose.service:norns-agent

Current Issues

Agent Attestation Failure

Symptoms:

error="Invalid argument: failed to attest: join token does not exist or has already been used"

Cause: Join tokens are single-use and expire after use or timeout.

Resolution:

# Generate new join token
docker exec spire-server /opt/spire/bin/spire-server token generate \
-spiffeID spiffe://ravenhelm.dev/agent/odin

# Update agent config with new token
# Edit /data/spire/agent/agent.conf
# Restart agent
docker restart spire-agent

Integration Roadmap

Phase 1: Basic Setup (Current)

  • Deploy SPIRE server
  • Deploy SPIRE agent
  • Fix agent attestation
  • Register initial workloads

Phase 2: Service Integration

  • Enable mTLS for Norns ↔ Bifrost
  • Enable mTLS for internal APIs
  • Integrate with Traefik

Phase 3: Full Mesh

  • All services use SPIFFE identity
  • Service mesh integration (optional)
  • Federated trust (if multi-cluster)

Troubleshooting

Server Won't Start

Diagnosis:

docker logs spire-server 2>&1 | head -50

Common Causes:

  1. Missing upstream CA files
  2. Data directory permissions
  3. Port 8081 conflict

Agent Can't Reach Server

Diagnosis:

docker exec spire-agent ping spire-server
docker exec spire-agent nc -zv spire-server 8081

Solutions:

  1. Verify both on same Docker network
  2. Check server is listening on 0.0.0.0
  3. Verify firewall rules

Workload Can't Get SVID

Diagnosis:

# Check workload API socket
docker exec spire-agent ls -la /tmp/spire-agent/public/api.sock

Solutions:

  1. Verify registration entry exists
  2. Check selectors match container
  3. Verify agent is attested

References