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.
| Property | Value |
|---|---|
| Server Image | ghcr.io/spiffe/spire-server:1.11.1 |
| Agent Image | ghcr.io/spiffe/spire-agent:1.11.1 |
| Containers | spire-server, spire-agent |
| Trust Domain | ravenhelm.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:
- Missing upstream CA files
- Data directory permissions
- 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:
- Verify both on same Docker network
- Check server is listening on 0.0.0.0
- 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:
- Verify registration entry exists
- Check selectors match container
- Verify agent is attested