Craton Shield

vs-mqtt-monitor

MQTT protocol intrusion detection for Craton Shield.

Overview

Monitors MQTT traffic for security anomalies on constrained IoT gateways. All state is stack-allocated with fixed-size arrays. No heap required.

Detection Mechanisms

MechanismDescriptionDefault
Topic allowlist/blocklistMQTT wildcard pattern matching (+, #). First-match-wins — rule ordering matters.Allow all
Connect stormSliding window detection of excessive CONNECT packets.5 per 60s
QoS enforcementPer-topic minimum or exact QoS policy.Any QoS
Rate limitingPer-topic token bucket with automatic refill. 32 buckets max (64 / 128 with capacity-large / capacity-xl).Unlimited

Configuration

use vs_mqtt_monitor::{MqttMonitor, TopicAction, QosPolicy};
use vs_types_embedded::MqttQoS;

let mut monitor = MqttMonitor::new();           // allow-by-default
// let mut monitor = MqttMonitor::new_deny_default(); // deny-by-default

// Topic rules (supports MQTT wildcards: + and #).
monitor.add_rule(b"sensors/#", TopicAction::Allow, QosPolicy::Any, 10).unwrap();
monitor.add_rule(b"admin/#", TopicAction::Block, QosPolicy::Any, 0).unwrap();
monitor.add_rule(
    b"critical/#",
    TopicAction::Allow,
    QosPolicy::MinQoS(MqttQoS::AtLeastOnce),
    0,
).unwrap();

// Connect storm tuning.
monitor.set_connect_storm_params(5, 60_000_000); // 5 connects per 60 seconds

Inspection

let result = monitor.inspect(&msg);
// result.allowed    — whether the message should be forwarded
// result.alert_count — number of alerts (0-4)
// result.alerts     — array of SecurityAlert structs

Alert Source IDs

IDMeaning
1Connect storm detected
2Empty topic in Publish/Subscribe
3Topic blocked by rule
4QoS policy violation (advisory — does not block)
5Rate limit exceeded
6Rate-limit bucket capacity exhausted
7Payload size anomaly (EWMA)
8Timestamp anomaly
9Invalid character in Publish topic (NUL / + / #)
10Subscribe to $-prefixed reserved topic without explicit allow
11Subscribe to broad wildcard (#, +, +/#) — firehose advisory

Limits

  • 32 topic rules max (64 with capacity-large, 128 with capacity-xl)
  • 64-byte topic patterns max
  • 32 rate-limit buckets (64 with capacity-large, 128 with capacity-xl)
  • 16 distinct clients tracked for CONNECT storm (LRU eviction when full)
  • 16 connect timestamps per client

Errors

  • VsError::InvalidInput — empty or oversized pattern, malformed wildcard
  • VsError::ResourceExhausted — rule capacity full

Changelog

See the workspace CHANGELOG for version history.

Feature Flags

See core/docs/feature-flags.md for the full workspace feature reference.

License

Apache-2.0. See LICENSE.