NATS + SPIFFE Setup
NATS provides event-driven messaging between tentacles. Combined with SPIFFE/SPIRE, it enables mTLS-authenticated communication with per-tentacle identity.
Prerequisites
Section titled “Prerequisites”- Kubernetes cluster with the MCP server installed
- Helm 3+
- The exoskeleton Postgres registrar (for NATS authorization storage)
- SPIRE server and agent deployed (for workload identity)
1. Install SPIRE
Section titled “1. Install SPIRE”Deploy the SPIRE server and agent:
# Install SPIRE CRDskubectl apply -f https://github.com/spiffe/spire/releases/latest/download/spire-crds.yaml
# Install SPIRE via Helmhelm install spire spire/spire \ --namespace spire-system \ --create-namespace \ --set global.spire.trustDomain=tentacular.local2. Install NATS with Auth
Section titled “2. Install NATS with Auth”Deploy NATS with resolver-based authorization:
helm install tentacular-nats nats/nats \ --namespace tentacular-system \ --set auth.enabled=true \ --set auth.resolver.type=full \ --set config.jetstream.enabled=true3. Configure the MCP Server
Section titled “3. Configure the MCP Server”Enable NATS and SPIRE registrars:
helm upgrade tentacular-mcp oci://ghcr.io/randybias/tentacular-mcp \ --namespace tentacular-system \ --set exoskeleton.nats.enabled=true \ --set exoskeleton.nats.url=nats://tentacular-nats.tentacular-system.svc:4222 \ --set exoskeleton.spire.enabled=true \ --set exoskeleton.spire.trustDomain=tentacular.local4. Verify SPIRE
Section titled “4. Verify SPIRE”# Check SPIRE agent healthkubectl -n spire-system exec -it spire-agent-0 -- \ /opt/spire/bin/spire-agent healthcheck
# List registered entrieskubectl -n spire-system exec -it spire-server-0 -- \ /opt/spire/bin/spire-server entry show5. Deploy a Tentacle with NATS
Section titled “5. Deploy a Tentacle with NATS”triggers: - type: queue subject: events.incoming
contract: version: "1" dependencies: tentacular-nats:tntc deployThe exoskeleton:
- Creates a SPIRE registration (ClusterSPIFFEID) for the tentacle pod
- Provisions NATS authorization with scoped subject permissions
- Injects NATS credentials and trust bundle into the deployment
How SPIFFE Identity Works
Section titled “How SPIFFE Identity Works”Each tentacle gets a SPIFFE identity:
spiffe://tentacular.local/ns/<namespace>/wf/<workflow-name>This identity is:
- Encoded in an X.509 SVID (SPIFFE Verifiable Identity Document)
- Automatically rotated by the SPIRE agent
- Used for mTLS between the tentacle and NATS server
- Used for authorization decisions (subject access control)
NATS Subject Scoping
Section titled “NATS Subject Scoping”NATS subjects are scoped per-tentacle by the exoskeleton using a deterministic naming convention. You cannot pick arbitrary subject names — they are derived from the tentacle’s identity.
Subject Naming Convention
Section titled “Subject Naming Convention”Each tentacle receives a subject prefix based on its (namespace, workflow-name):
tentacular.<namespace>.<workflow-name>.>For example, a tentacle named hn-digest in namespace tent-dev gets:
- Subject prefix:
tentacular.tent-dev.hn-digest.> - NATS user:
tentacle.tent-dev.hn-digest
The > suffix is a NATS wildcard — the tentacle can publish and subscribe to any subject under its prefix (e.g., tentacular.tent-dev.hn-digest.events, tentacular.tent-dev.hn-digest.results).
Authorization Modes
Section titled “Authorization Modes”| Mode | Isolation | How It Works |
|---|---|---|
| SPIFFE (recommended) | Cryptographically enforced | Per-workflow mTLS certificates via SPIRE SVIDs. Authorization ConfigMap contains explicit allow lists per SPIFFE principal. |
| Token (fallback) | Convention-only | Shared token for all workflows. Subject isolation is by naming convention, not enforced. |
In SPIFFE mode, each tentacle’s authorization entry looks like:
User: spiffe://tentacular/ns/tent-dev/tentacles/hn-digestPublishAllow: [tentacular.tent-dev.hn-digest.>]SubscribeAllow: [tentacular.tent-dev.hn-digest.>]Queue Triggers
Section titled “Queue Triggers”Tentacles with queue triggers subscribe to NATS subjects matching their scoped prefix:
triggers: - type: queue subject: tentacular.tent-dev.hn-digest.events- Connection: TLS + token auth via
config.nats_urlandsecrets.nats.token - Request-reply: If a message has a reply subject, the execution result is sent back
- Graceful shutdown: SIGTERM/SIGINT drain subscriptions before exit
Cross-Tentacle Communication
Section titled “Cross-Tentacle Communication”Tentacles can communicate through NATS by publishing to another tentacle’s subject prefix. In SPIFFE mode, explicit authorization entries must be added to allow cross-tentacle publish/subscribe.
Verification
Section titled “Verification”- SPIRE agents are healthy on all nodes
- Tentacles receive SVIDs (check pod logs for SPIFFE handshake)
- NATS queue triggers receive and process messages
tntc logs my-tentacleshows successful NATS connection
Troubleshooting
Section titled “Troubleshooting”| Symptom | Cause | Fix |
|---|---|---|
NATS connection refused | NATS not running or wrong URL | Check NATS pod status and service endpoint |
TLS handshake failed | SVID not issued | Check SPIRE agent logs, verify ClusterSPIFFEID exists |
authorization violation | Wrong subject permissions | Check NATS auth config, re-register via MCP |
| Queue trigger not firing | Subject mismatch | Verify subject in trigger matches publisher |
nats_url missing | Config not set | Add nats_url to workflow config |