Configuration Reference¶
Configuration is provided via a YAML config file. The serve command exposes a subset of commonly-used options as CLI flags, each with a corresponding SHUNT_-prefixed environment variable. CLI flags override config file values.
Settings without a CLI flag can only be set in the YAML config file.
CLI Flag Overrides¶
These flags (and their env vars) are available on the serve command and override the corresponding config file values:
| CLI Flag | Env Var | Config Key | Default | Description |
|---|---|---|---|---|
-c / --config |
SHUNT_CONFIG |
— | shunt.yaml |
Path to config file |
--nats-url |
SHUNT_NATS_URL |
nats.urls |
nats://localhost:4222 |
NATS server URLs (comma-separated) |
--log-level |
SHUNT_LOG_LEVEL |
logging.level |
info |
debug, info, warn, error |
--metrics-enabled |
SHUNT_METRICS_ENABLED |
metrics.enabled |
true |
Enable Prometheus metrics endpoint |
--metrics-addr |
SHUNT_METRICS_ADDR |
metrics.address |
:2112 |
Metrics server listen address |
--metrics-path |
SHUNT_METRICS_PATH |
metrics.path |
/metrics |
Metrics endpoint path |
--gateway-enabled |
SHUNT_GATEWAY_ENABLED |
gateway.enabled |
false |
Enable HTTP gateway subsystem |
--kv-enabled |
SHUNT_KV_ENABLED |
kv.enabled |
false |
Enable KV data enrichment |
--worker-count |
SHUNT_WORKER_COUNT |
nats.consumers.workerCount |
2 |
Concurrent workers per subscription |
NATS Connection¶
| Config Key | Type | Default | Description |
|---|---|---|---|
nats.urls |
[]string |
["nats://localhost:4222"] |
NATS server URLs |
nats.username |
string |
Username authentication | |
nats.password |
string |
Password authentication | |
nats.token |
string |
Token authentication | |
nats.nkey |
string |
NKey seed file path | |
nats.credsFile |
string |
Path to JWT credentials file | |
nats.tls.enable |
bool |
false |
Enable TLS |
nats.tls.certFile |
string |
Client certificate path | |
nats.tls.keyFile |
string |
Client key path | |
nats.tls.caFile |
string |
CA certificate path | |
nats.tls.insecure |
bool |
false |
Skip TLS verification |
nats.connection.maxReconnects |
int |
-1 |
Max reconnection attempts (-1 = unlimited) |
nats.connection.reconnectWait |
duration |
50ms |
Delay between reconnection attempts |
Only one authentication method may be used at a time.
JetStream Consumers¶
| Config Key | Type | Default | Description |
|---|---|---|---|
nats.consumers.consumerPrefix |
string |
shunt |
Prefix for JetStream consumer names |
nats.consumers.workerCount |
int |
2 |
Concurrent workers per subscription (max: 1000). Also settable via --worker-count / SHUNT_WORKER_COUNT. |
nats.consumers.fetchBatchSize |
int |
1 |
Messages per pull request (max: 10000) |
nats.consumers.fetchTimeout |
duration |
5s |
Max wait time when fetching messages |
nats.consumers.maxAckPending |
int |
1000 |
Max unacknowledged messages (max: 100000) |
nats.consumers.ackWaitTimeout |
duration |
30s |
Time before redelivery of unacked messages |
nats.consumers.maxDeliver |
int |
3 |
Max redelivery attempts |
nats.consumers.deliverPolicy |
string |
new |
all, new, last, by_start_time, by_start_sequence |
nats.consumers.replayPolicy |
string |
instant |
instant or original |
Publish¶
| Config Key | Type | Default | Description |
|---|---|---|---|
nats.publish.mode |
string |
jetstream |
jetstream (durable) or core (fire-and-forget) |
nats.publish.ackTimeout |
duration |
5s |
JetStream publish ack timeout |
nats.publish.maxRetries |
int |
3 |
Max publish retry attempts |
nats.publish.retryBaseDelay |
duration |
50ms |
Base delay for exponential backoff |
Per-Rule Publish Mode Override¶
Each NATS action can override the global nats.publish.mode by setting mode directly on the action block. When omitted, the global setting is used. Valid values: core (fire-and-forget, low-latency) or jetstream (durable, acknowledged).
The right delivery guarantee depends on the action, not the input. A single consumed JetStream message can trigger multiple rules with different output guarantees.
Notifications to simple subscribers¶
Notification sidecars (ntfy, Gotify, Slack webhook agents) are typically plain core NATS subscribers — they don't consume from streams. Core publish works without provisioning a stream for the output subject.
# Message: {"temperature": 47.3, "device_id": "sensor-12", "location": "warehouse-b"}
- trigger:
nats:
subject: sensors.temperature.>
conditions:
operator: and
items:
- field: "{temperature}"
operator: gt
value: 45
action:
nats:
subject: notify.slack.alerts
mode: core
payload: '{"text": "High temp: {temperature}C on {device_id}"}'
Real-time dashboards and WebSocket bridges¶
Sensor data published to subjects a WebSocket gateway fans out to browsers. If no browser is connected, persisting these messages is pointless — the next reading supersedes it.
- trigger:
nats:
subject: sensors.energy.>
action:
nats:
subject: dashboard.energy.{@subject.2}
mode: core
passthrough: true
Fan-out with mixed guarantees¶
One consumed message triggers two rules: a durable audit log and an ephemeral live status display.
# Message: {"door_id": "front", "event": "opened", "user": "alice"}
# Audit log — must persist
- trigger:
nats:
subject: access.door.>
action:
nats:
subject: audit.access.log
mode: jetstream
payload: '{"door": "{door_id}", "action": "{event}", "time": "{@timestamp()}"}'
# Live status board — ephemeral
- trigger:
nats:
subject: access.door.>
action:
nats:
subject: display.door.status.{door_id}
mode: core
payload: '{"door": "{door_id}", "state": "{event}"}'
Metrics re-publishing¶
Enriched telemetry re-published to a subject a metrics collector (Telegraf, Prometheus pushgateway) subscribes on. Missing a single data point is acceptable — the next one arrives in seconds.
- trigger:
nats:
subject: zigbee2mqtt.>
action:
nats:
subject: metrics.zigbee.{@subject.1}
mode: core
payload: '{"device": "{@subject.1}", "battery": {battery}, "linkquality": {linkquality}}'
Global core, selective durability¶
A homelab where most rules are simple forwarding (nats.publish.mode: core globally), but one rule publishes safety-critical events that must not be lost.
# Global config: nats.publish.mode: core
# This rule overrides to jetstream for safety-critical events
- trigger:
nats:
subject: sensors.gas.>
conditions:
operator: and
items:
- field: "{ppm}"
operator: gt
value: 500
action:
nats:
subject: safety.gas.alarm
mode: jetstream
payload: '{"sensor": "{sensor_id}", "ppm": {ppm}, "time": "{@timestamp()}"}'
KV Store¶
| Config Key | Type | Default | Description |
|---|---|---|---|
kv.enabled |
bool |
false |
Enable KV data enrichment. Also settable via --kv-enabled / SHUNT_KV_ENABLED. |
kv.buckets |
[]string |
[] |
KV buckets to watch (config file only — lists cannot be set via env var) |
kv.autoProvision |
bool |
true |
Auto-create KV buckets if missing |
kv.localCache.enabled |
bool |
true (when kv.enabled) |
Enable in-memory KV cache |
Rules¶
| Config Key | Type | Default | Description |
|---|---|---|---|
rules.kvBucket |
string |
rules |
KV bucket for rule definitions |
Per-Rule Fields¶
These fields are set on individual rules in rule YAML files, not in the server config.
| Field | Type | Default | Description |
|---|---|---|---|
debounce |
duration string |
(disabled) | Suppress rapid re-fires within a time window (e.g., "30s", "5m"). See Debounce. |
Security¶
| Config Key | Type | Default | Description |
|---|---|---|---|
security.verification.enabled |
bool |
false |
Enable NKey signature verification |
security.verification.publicKeyHeader |
string |
Nats-Public-Key |
Header containing signer's public key |
security.verification.signatureHeader |
string |
Nats-Signature |
Header containing Ed25519 signature |
Logging¶
| Config Key | Type | Default | Description |
|---|---|---|---|
logging.level |
string |
info |
debug, info, warn, error. Also settable via --log-level / SHUNT_LOG_LEVEL. |
logging.encoding |
string |
json |
json or console |
logging.outputPath |
string |
stdout |
Output destination |
Metrics¶
| Config Key | Type | Default | Description |
|---|---|---|---|
metrics.enabled |
bool |
true |
Enable Prometheus metrics endpoint. Also settable via --metrics-enabled / SHUNT_METRICS_ENABLED. |
metrics.address |
string |
:2112 |
Metrics server listen address. Also settable via --metrics-addr / SHUNT_METRICS_ADDR. |
metrics.path |
string |
/metrics |
Metrics endpoint path. Also settable via --metrics-path / SHUNT_METRICS_PATH. |
metrics.updateInterval |
string |
15s |
System metrics update interval |
HTTP Gateway¶
These settings apply when gateway.enabled is true. The gateway toggle is also settable via --gateway-enabled / SHUNT_GATEWAY_ENABLED.
| Config Key | Type | Default | Description |
|---|---|---|---|
gateway.enabled |
bool |
false |
Enable HTTP gateway subsystem |
http.server.address |
string |
:8080 |
HTTP server listen address |
http.server.readTimeout |
duration |
30s |
HTTP read timeout |
http.server.writeTimeout |
duration |
30s |
HTTP write timeout |
http.server.idleTimeout |
duration |
120s |
HTTP idle timeout |
http.server.maxHeaderBytes |
int |
1048576 |
Max header size (1MB) |
http.server.shutdownGracePeriod |
duration |
30s |
Graceful shutdown timeout |
http.server.inboundWorkerCount |
int |
10 |
Workers processing inbound HTTP requests |
http.server.inboundQueueSize |
int |
1000 |
Inbound request queue size (max: 100000) |
http.client.timeout |
duration |
30s |
Outbound HTTP request timeout |
http.client.maxIdleConns |
int |
100 |
Max idle connections |
http.client.maxIdleConnsPerHost |
int |
10 |
Max idle connections per host |
http.client.idleConnTimeout |
duration |
90s |
Idle connection timeout |
http.client.tls.insecureSkipVerify |
bool |
false |
Skip outbound TLS verification |
Auth Manager¶
These settings apply when authManager.enabled is true. All auth manager settings require a config file.
| Config Key | Type | Default | Description |
|---|---|---|---|
authManager.enabled |
bool |
false |
Enable auth manager subsystem |
authManager.storage.bucket |
string |
tokens |
KV bucket for token storage |
authManager.storage.keyPrefix |
string |
Key prefix in token bucket |
Providers are configured as a list under authManager.providers and require a config file:
authManager:
enabled: true
storage:
bucket: tokens
providers:
- id: my-api
type: oauth2 # or "custom-http"
kvKey: my-api-token
tokenUrl: https://auth.example.com/token
clientId: my-client
clientSecret: secret
refreshBefore: 5m
scopes: ["read", "write"]
ForEach¶
| Config Key | Type | Default | Description |
|---|---|---|---|
forEach.maxIterations |
int |
100 |
Max iterations per forEach operation (max: 10000) |