The Stages of AI Grief

Assumed audience: People who work with AI daily — or are starting to — and have complicated feelings about it.

I don’t think I’ve ever had so much fun in my programming career as I do now. Which is strange, because a few weeks ago I was in a very different place. I was watching – in horror – as the machine on my desk was taking over my craft. Like most people I guess, I derive quite a lot of my identity from that craft; hence the horror. (Let’s ignore for now whether that’s a good thing or not.)

I just watched it melt away. Like a block of ice in the sun; inexorable. In that moment it felt like I was witnessing an emerging god: an uncontrollable force in the sky asserts its influence over all it touches, and every day, it touches more. It was dreadful. And then the realization dawned upon me: I will never learn another programming language. My aspirations to learn Golang properly. To switch to a career as a Rust programmer. Gone.

But here’s the thing. It’s never been easier to learn a new programming language. These AIs are infinitely patient. Infinitely knowledgeable. You can ask them to explain something ten times. Explain it to me like I’m five. Explain it to me like I’m ten. They will. And they’ll do it well.

Hell, in the past year I taught myself electronics. I had never soldered anything and now I’m regularly ordering PCBs that I’ve designed. Never in my wildest dreams could I have predicted that even two years ago.

So it’s easier than ever to learn something new. And for more and more things every day, it’s just not necessary anymore. That hurts on a level I didn’t know existed.

It feels like grief because it is

Denial. “It can’t do everything, right?” “It cannot do this part!” “Look, it’s making a mistake! Hah! This cannot be trusted! It can’t do it all.” And then, two weeks later, a new model comes out, or an update to the harness. Or you just get smarter with your instructions, and poof, no mistakes anymore. So that argument fails you.

Anger. I don’t know if I had anger myself – I think personally I skipped straight to depression – but I definitely felt it from others. When I showed this tool to people, some of them were truly approaching anger. And if the situation would have been less public, I’m sure they would have been mad at the messenger. I’ve met people who swore they would never code with AI. Went as far as publishing that on LinkedIn. As a public statement. To me that looks somewhere between an almost Amish kind of quaint and watching someone defy a rhino.

Bargaining. How do I stay relevant? If I do this, if I do that. But I was failing. I was failing to see how I was going to stay relevant. I had nothing to bargain with. So I skipped this.

Depression. And I was depressed. Or at least rather shaken and down, for about two weeks. The subject of this was 50% about my craft, and the other 50% was about all crafts. If my work, which is just dealing with letters on a screen, goes away; then I honestly don’t see how anyone else’s work with letters on a screen will stay. Or numbers for that matter. I can’t oversee where this is going, but I can see that it’s going, and there’s no stopping it. Who can compete if the other guy has such a giant leg up?

Acceptance. Okay, this is it then. So now what.

The other side

So if someone builds a brick-laying machine, what we’ve done in history is always: we’ve gone up a level. You become the brick-laying-machine-manager.

Maybe not as fun. Maybe more fun. I don’t know. Personally, I never wanted to be a manager, in IT at least. I think that at least subconsciously I’ve always tried to stay away from that. Mentoring is one thing. Managing, like being responsible for non-deterministic entities like humans? Hell no!

And now I’m constantly responsible for non-deterministic entities. Many of them at the same time. And it’s actually great.

I’ve truly never had more fun programming than now. I don’t sleep enough just because it’s so fun. I build software on a daily basis that I could only have dreamed of doing with weeks of work previously. I’ve taken old projects, half-baked ideas from years ago, and just told the AI: hey, look at this idea I had. Here’s a server. Go give it life! It asks a few questions. I let it rattle for a while, and ten minutes later, it is there, and it is good. It’s better than I could have made it. And then I tell it: that is great, but now make it better. And it makes it even better! It adds security. It plugs holes. It adds a thousand tests if I ask it to.

Before, I got hired to optimize a CI/CD pipeline. Now I just tell it: make one. And it does. Just pick the language.

The replicator

It’s like a 3D printer. Which, if you squint, it really is just a Star Trek replicator, isn’t it? At least the 10 year old me definitely thinks so. There’s this magical space in my house, and I can just cast a spell to fill it with an object. One moment there’s nothing and the next it’s just there.

This is what successful agentic programming feels like. First there is nothing. You have an idea. You press a few buttons, and the idea materializes. And I have a lot more disk-space for bytes than I have house-space for PLA. I feel like a – hopefully benevolent – god, pushing creation into the void to fill it with wonderful things.

The app that I’m dictating this blog on did not exist last week. I had the idea on the bikeride back from bringing my kids to school. I needed a dictation app, and not one of the many in the Play Store, I wanted it to do exactly what I want. But I’ve never done Android development in my life. I’ve had ambitions to, of course, but I never got to it. But now; mhwahah! I have my magical replicator! So, it took 5 minutes to explain. I told it to fetch some best practices for Android app creation, and once I was satisfied with that effort, I plugged my phone into my laptop and told it to make me the app and also a markdown on what everything is in the file tree; to at least fool myself into thinking that I was finally learning Android development. And poof, ten minutes later, I was using that app to ask questions about that markdown!

Made for this

And maybe, just maybe, I was made to do this more than actual programming. I’m pretty good at exactly the level of idea-having and directing that is now required to get these things moving. And I’ve got a few decades of doing IT to draw upon to verify that it keeps making sense. So I keep upgrading the system; now I’m making the AI look at my own sessions and find corrections, and correct the instructions for next time. And this works really well!

I don’t know what’s beyond the horizon. Maybe it’s scary AGI. Maybe it’s nice AGI. (Pretty please…) Maybe there’s no AGI and it’s all just a millennium bug.

But I do know that right now, on the other side of grief, it is better. Yes, the stages are real. But acceptance isn’t the end. It’s where the fun starts.

Originally published at deknijf.com

Transforming Raspberry Pi into an AI-Native Edge IDS for SMBs

The SMB Security Gap: Why the Edge Matters

Small and Medium Businesses (SMBs) are frequently described as the “soft underbelly” of the global supply chain. While large enterprises invest millions in centralized Security Operations Centers (SOCs) and high-end hardware, SMBs often operate with lean IT teams and limited budgets. However, the threats they face—ranging from sophisticated ransomware-as-a-service to targeted lateral movement—are just as potent. The traditional approach of backhauling all traffic to a central firewall is increasingly obsolete in a world of distributed work and IoT expansion. This is where how to set up IDS on raspberry pi becomes a critical question for cost-conscious security engineers.

In the contemporary digital ecosystem, SMBs are no longer flying under the radar of global cyber-adversaries. Historically, large enterprises were the primary targets of sophisticated attacks; however, as enterprise defenses have hardened, threat actors have pivoted toward SMBs. These organizations often possess valuable data—including intellectual property, customer PII, and financial records—but frequently lack the massive security budgets required for enterprise-grade appliances. By leveraging an AI powered intrusion detection system at the edge, SMBs can achieve a level of protection previously reserved for the Fortune 500.

At HookProbe, we believe in the democratization of cyber defense. Our Neural-Kernel cognitive defense is designed to provide autonomous protection where it matters most: at the point of entry. In this guide, we will explore how to transform a Raspberry Pi 5 into a functional, AI-native edge IDS, bridging the gap between affordability and advanced security capabilities.

The Raspberry Pi 5: A Formidable Security Edge Device

Historically, Intrusion Detection Systems (IDS) required significant capital expenditure, relying on high-performance x86 servers to handle deep packet inspection (DPI). However, the release of the Raspberry Pi 5 has shifted the paradigm. With its Broadcom BCM2712 quad-core Arm Cortex-A76 processor running at 2.4GHz, and up to 8GB of LPDDR4X-4267 SDRAM, the Pi 5 offers the computational density required for real-time packet analysis and machine learning inference.

When considering a self hosted security monitoring solution, the Pi 5’s inclusion of a dedicated PCIe 2.0 interface is a game-changer. This allows for high-speed NVMe storage or even external 10GbE network interface cards (NICs), mitigating the traditional I/O bottlenecks associated with older Raspberry Pi models. For an SMB, this means a device costing less than $100 can effectively monitor a standard 1Gbps uplink without significant packet drops, provided the software stack is optimized for the edge.

The Evolution of SMB Network Defense: From Signatures to Intelligence

In the current cybersecurity landscape, traditional IDS like Snort and Suricata are increasingly hitting a performance wall. These legacy systems rely heavily on signature-based detection, which requires comparing every single packet against a massive database of known threat patterns. As network speeds increase and encrypted traffic (TLS 1.3) becomes the norm, this approach leads to significant CPU overhead and high false-positive rates. This is why a suricata vs zeek vs snort comparison is essential for any architect.

  • Snort: The venerable grandfather of IDS. Great for signature matching but struggles with multi-threading in older versions.
  • Suricata: Highly multi-threaded and capable of multi-gigabit throughput. It supports Lua scripting for complex detection but remains largely signature-dependent.
  • Zeek (formerly Bro): A network security monitor that excels at metadata extraction and behavioral analysis, making it a favorite for threat hunters.

However, an AI-native Edge IDS goes beyond these tools by incorporating behavioral models that detect anomalies rather than just matching strings. By utilizing HookProbe’s NAPSE AI-native engine logic, we can shift from reactive blacklisting to proactive behavioral profiling. This is the cornerstone of the HookProbe Neural-Kernel, which combines a 10us kernel reflex with LLM-based reasoning to identify zero-day exploits that lack a signature.

Technical Implementation: Setting Up the Foundation

To transform a Raspberry Pi 5 into an AI-native Edge IDS, we must move away from standard user-space packet processing and embrace eBPF XDP packet filtering. eBPF (Extended Berkeley Packet Filter) allows us to run sandboxed programs within the Linux kernel, enabling us to drop or redirect packets at the earliest possible stage in the network stack—the XDP (Express Data Path) hook.

Step 1: Preparing the Raspberry Pi OS

Start with a clean installation of Raspberry Pi OS Lite (64-bit). Ensure the kernel is updated to support the latest eBPF features.

sudo apt-get update && sudo apt-get upgrade -y
sudo apt-get install clang llvm libelf-dev libcap-dev gcc-multilib build-essential git -y
sudo apt-get install linux-headers-$(uname -r)

Step 2: Implementing eBPF/XDP for High-Speed Filtering

The goal is to use eBPF to pre-filter traffic before it reaches our AI analysis engine. This reduces the load on the CPU by discarding known-bad traffic (based on IP reputation or malformed headers) at the NIC level. Below is a conceptual example of an XDP program in C that drops traffic from a specific blocked CIDR range.

#include <linux/bpf.h>
#include <bpf/bpf_helpers.h>

SEC("xdp")
int xdp_drop_prog(struct xdp_md *ctx) {
    // Packet processing logic here
    // Return XDP_DROP to discard or XDP_PASS to allow
    return XDP_PASS;
}

For those looking for a more robust starting point, the open-source on GitHub repository provides several eBPF templates optimized for ARM64 architectures.

Integrating the NAPSE AI-Native Engine Logic

The core of an AI-native IDS is the ability to perform inference on network flows. On a Raspberry Pi, we cannot run massive transformer models in real-time for every packet. Instead, we utilize a tiered architecture similar to HookProbe’s 7-POD structure.

Tier 1: Feature Extraction

Using a tool like Zeek or a custom eBPF agent, we extract key features from network flows: packet sizes, inter-arrival times, TCP window scaling, and TLS SNI headers. This metadata is much smaller than the raw packet data, allowing for efficient processing.

Tier 2: Edge Inference

We deploy a lightweight Random Forest or Gradient Boosted Machine (GBM) model using TensorFlow Lite or ONNX Runtime. This model is trained to recognize patterns associated with common SMB threats, such as Cobalt Strike beacons or lateral movement via SMB/RPC.

import tflite_runtime.interpreter as tflite
import numpy as np

# Load the pre-trained anomaly detection model
interpreter = tflite.Interpreter(model_path="edge_ids_model.tflite")
interpreter.allocate_tensors()

def predict_anomaly(flow_features):
    input_details = interpreter.get_input_details()
    output_details = interpreter.get_output_details()
    interpreter.set_tensor(input_details[0]['index'], flow_features)
    interpreter.invoke()
    return interpreter.get_tensor(output_details[0]['index'])

The 10us Reflex: Implementing Neural-Kernel at the Edge

One of the most innovative aspects of the HookProbe philosophy is the concept of the “reflex.” In biological systems, a reflex occurs before the brain even processes the pain. In cybersecurity, our Neural-Kernel provides a 10us kernel-level reflex. If the AI model at the edge identifies a flow as 99% likely to be a ransomware heartbeat, the eBPF program can immediately update a kernel map to drop all subsequent packets from that source IP, effectively neutralizing the threat in microseconds.

This is significantly faster than traditional open source SIEM for small business setups, where a log must be generated, sent to a central server, parsed, analyzed, and then a firewall rule pushed back to the edge. By the time that loop completes, the encryption process may have already begun.

Aligning with Industry Best Practices: NIST and MITRE ATT&CK

Building a custom IDS isn’t just about the code; it’s about the framework. SMBs should align their detection strategies with the NIST Cybersecurity Framework (CSF) and the MITRE ATT&CK matrix. Your AI-native IDS on Raspberry Pi should be tuned to detect specific techniques, such as:

  • T1071 (Application Layer Protocol): Detecting non-standard traffic over port 443 or 80.
  • T1046 (Network Service Discovery): Identifying internal port scanning which indicates lateral movement.
  • T1567 (Exfiltration Over Web Service): Monitoring for unusual outbound data volumes to cloud storage providers.

By mapping your AI detections to these categories, you provide IT managers with actionable intelligence rather than just vague alerts. This structured approach is central to HookProbe’s documentation and deployment philosophy, ensuring that even small teams can maintain enterprise-grade situational awareness.

The HookProbe 7-POD Architecture at the Edge

When we talk about the 7-POD architecture in the context of a Raspberry Pi IDS, we are referring to the modularity of the security functions:

  • Ingress POD: eBPF/XDP high-speed packet capture.
  • Parsing POD: Protocol identification and metadata extraction.
  • Neural POD: AI inference and behavioral scoring.
  • Reflex POD: Immediate kernel-level mitigation (The AEGIS system).
  • Context POD: Enrichment with threat intelligence feeds.
  • Storage POD: Efficient logging of high-fidelity alerts.
  • Transmission POD: Securely sending telemetry to a central HookProbe instance or SIEM.

By compartmentalizing these functions, the Raspberry Pi can maintain stability even under heavy load. If the Neural POD is overwhelmed, the Ingress POD continues to pass traffic, ensuring network availability (the ‘A’ in the CIA triad) is not compromised by the security stack.

Challenges and Considerations

While the Raspberry Pi 5 is powerful, it is not a silver bullet. There are several challenges when deploying a DIY AI powered intrusion detection system:

Heat Management

The Pi 5 runs hot under sustained load. An active cooler or a high-quality passive heat-sink case (like the Argon ONE) is mandatory for 24/7 security operations.

Storage Longevity

Standard SD cards will fail quickly under the constant write cycles of an IDS. Use an NVMe SSD via the PCIe hat for reliable logging and database operations.

Encryption (The Blind Spot)

Over 90% of web traffic is encrypted. An edge IDS cannot see inside the payload without SSL/TLS inspection (which is computationally expensive). Instead, focus on Encrypted Traffic Analysis (ETA), looking at packet timing, sizes, and the initial handshake (JA3 fingerprints) to identify threats without decryption.

Conclusion: Scaling SMB Security with HookProbe

Transforming a Raspberry Pi into an AI-native Edge IDS is an excellent way for SMBs to start their journey toward autonomous security. It provides a hands-on understanding of eBPF, machine learning inference, and modern network defense. However, for organizations that require enterprise-grade reliability, 24/7 support, and the full power of the 7-POD architecture, moving to professional deployment tiers is the logical next step.

HookProbe’s platform takes these concepts—the 10us reflex, the NAPSE engine, and the edge-first philosophy—and scales them into a turnkey solution that protects your entire infrastructure. Whether you are a security engineer building a lab or a CISO looking to protect a global supply chain, the move toward AI-native edge defense is no longer optional—it is inevitable.

Ready to see how HookProbe can revolutionize your SOC? Explore our security blog for more deep dives or check out our open-source projects to start building your own edge-first defense today.

Originally published at hookprobe.com. HookProbe is an open-source AI-native IDS that runs on a Raspberry Pi.

GitHub: github.com/hookprobe/hookprobe

Implementing Zero Trust Architecture for Unmanaged IoT at the Network Edge

Why Unmanaged IoT Is the Weakest Link in Your Network

The proliferation of Internet of Things (IoT) devices across enterprise environments has created a security paradox. Organizations deploy thousands of connected devices—IP cameras, building automation controllers, medical equipment, industrial sensors, point-of-sale terminals—to drive operational efficiency. Yet the vast majority of these devices are unmanaged: they cannot run endpoint agents, accept security patches on schedule, or participate in traditional identity frameworks. According to industry estimates, over 75% of IoT devices in production environments operate without any form of endpoint security.

This creates a massive blind spot. Traditional perimeter-based security assumes that everything inside the network is trusted. But a compromised smart thermostat or an unpatched security camera becomes a beachhead for lateral movement, data exfiltration, and persistent access. The 2024 Verkada camera breaches and ongoing Mirai botnet variants demonstrate that attackers actively target these devices as the path of least resistance into otherwise well-defended networks.

Zero Trust Architecture (ZTA) offers a fundamentally different approach: never trust, always verify. But implementing Zero Trust for devices that cannot authenticate themselves, run software agents, or participate in certificate-based mutual TLS presents unique challenges. This guide examines how to solve those challenges using network-level enforcement, AI-native traffic analysis, and autonomous edge defense.

Zero Trust Principles Applied to IoT

The NIST SP 800-207 framework defines Zero Trust as eliminating implicit trust from network architecture. For managed endpoints—laptops, servers, mobile devices—this translates to identity verification, device posture checks, and continuous authorization. For unmanaged IoT, we must adapt these principles to work at the network layer:

1. Identity Without Agents

Unmanaged IoT devices cannot run identity agents or participate in SAML/OIDC flows. Instead, identity must be inferred from network behavior. This includes MAC address fingerprinting, DHCP option analysis, DNS query patterns, and traffic flow profiling. HookProbe’s NAPSE engine performs deep packet inspection (DPI) at the edge to build behavioral fingerprints for every device on the network, creating a passive identity layer that requires zero device-side cooperation.

2. Micro-Segmentation at Wire Speed

Once devices are identified, Zero Trust demands that each device operates within the minimum required network boundary. Traditional VLANs provide coarse segmentation, but they cannot enforce per-device policies at scale. HookProbe leverages eBPF/XDP programs attached directly to the network interface to enforce micro-segmentation decisions in the kernel’s fast path—processing packets in as few as 3 microseconds without copying data to userspace. This enables per-device allow/deny decisions at line rate, even on commodity hardware like Raspberry Pi 5.

3. Continuous Verification Through Traffic Analysis

Zero Trust is not a one-time gate check; it requires continuous verification. For IoT devices, this means monitoring every flow for deviations from established baselines. A security camera that suddenly initiates outbound SSH connections or a building controller that begins scanning internal subnets has violated its behavioral contract. The NAPSE engine evaluates each flow against learned device profiles and flags anomalies in real time, triggering automated containment when confidence thresholds are exceeded.

4. Least-Privilege Network Access

Each device should communicate only with the specific endpoints it requires. An IP camera needs to reach its NVR and firmware update server—nothing else. An HVAC controller communicates with its management platform via a single API endpoint. HookProbe’s policy engine automatically generates least-privilege network rules based on observed legitimate traffic patterns during a learning period, then enforces those rules via XDP programs that drop unauthorized flows before they reach the network stack.

Architecture: Edge-Native Zero Trust with HookProbe

Implementing Zero Trust for IoT requires security enforcement to happen at the network edge, as close to the devices as possible. Backhauling IoT traffic to a centralized cloud for analysis introduces latency that attackers exploit. HookProbe’s architecture places the entire detection and enforcement pipeline on edge nodes deployed in the same network segment as the IoT devices.

The Detection Pipeline

The pipeline processes every packet through four stages, each running at the edge:

┌─────────────┐    ┌──────────────┐    ┌───────────────┐    ┌──────────────┐
│  XDP Filter  │───▶│ NAPSE Engine │───▶│ Hydra Verdict │───▶│ AEGIS Action │
│ (Kernel Fast │    │ (DPI + Flow  │    │ (ML Scoring + │    │ (Autonomous  │
│   Path)      │    │  Analysis)   │    │  Correlation) │    │  Response)   │
└─────────────┘    └──────────────┘    └───────────────┘    └──────────────┘
     3μs               ~50μs              ~200μs               ~10ms

Stage 1: XDP Kernel Filter. eBPF programs attached via XDP inspect every inbound packet at the earliest possible point in the Linux networking stack. Known-malicious source IPs, protocol violations, and rate-limit breaches are dropped immediately—before the packet reaches the kernel’s TCP/IP stack. This stage handles volumetric attacks and known threats with near-zero CPU overhead.

Stage 2: NAPSE Deep Packet Inspection. Packets that pass XDP filtering are analyzed by the NAPSE AI-native engine. NAPSE performs protocol dissection, payload entropy analysis, and flow-level behavioral profiling. It identifies the device type, validates that the traffic matches the device’s behavioral fingerprint, and extracts features for downstream ML scoring. For encrypted traffic, NAPSE uses JA3/JA4 fingerprinting and certificate metadata analysis rather than attempting decryption.

Stage 3: Hydra Verdict Engine. The extracted features are evaluated by the Hydra multi-model ensemble. Hydra combines an Isolation Forest for anomaly detection, a Bayesian threat scorer calibrated on real-world attack data, and a SENTINEL correlation engine that cross-references activity against threat intelligence feeds. The output is a confidence-scored verdict: benign, suspicious, or malicious.

Stage 4: AEGIS Autonomous Response. For high-confidence malicious verdicts, the AEGIS agent system executes automated containment without waiting for human approval. Actions include injecting XDP drop rules for the offending IP, quarantining the compromised device’s network segment, generating an incident record with full forensic context, and alerting the SOC team. The entire pipeline from packet arrival to containment completes in under 15 milliseconds.

Practical Implementation: Step by Step

Step 1: Asset Discovery and Classification

Before enforcing Zero Trust policies, you need a complete inventory of every device on the network. Passive discovery is essential for IoT because active scanning can crash fragile embedded systems. Deploy a HookProbe edge node on each network segment and allow 48-72 hours of passive observation. The NAPSE engine will identify devices by analyzing:

  • DHCP fingerprints (option 55 parameter request lists)
  • DNS query patterns and resolved domains
  • Protocol distribution (HTTP, MQTT, CoAP, Modbus, BACnet)
  • Traffic volume and periodicity
  • TLS client hello fingerprints (JA3 hashes)

The output is a device inventory categorized by type, risk level, and communication patterns. This inventory becomes the foundation for policy generation.

Step 2: Baseline Behavioral Profiles

During the discovery period, NAPSE simultaneously builds behavioral baselines for each device. A baseline captures the normal communication pattern: which IPs the device contacts, on which ports, using which protocols, at what frequency, and with what payload characteristics. These baselines are stored as compact feature vectors that can be evaluated in microseconds during live traffic analysis.

Critical baseline metrics include:

  • Flow cardinality: How many unique destinations does the device contact?
  • Protocol adherence: Does the device use only expected protocols?
  • Temporal patterns: Does the device have predictable communication cycles?
  • Payload entropy: What is the normal entropy distribution of the device’s payloads?
  • DNS behavior: Does the device resolve only expected domains?

Step 3: Policy Generation and Enforcement

Based on discovered baselines, HookProbe automatically generates least-privilege XDP rules. For example, a Hikvision IP camera that communicates only with NVR at 192.168.1.50:554 (RTSP) and firmware server at update.hikvision.com:443 (HTTPS) would receive a policy that permits only those two flows and drops everything else.

These policies are compiled into eBPF bytecode and loaded into the kernel via XDP, ensuring enforcement at wire speed. Policy updates propagate to all edge nodes within seconds through the mesh network, enabling coordinated responses across distributed sites.

Step 4: Continuous Monitoring and Adaptive Response

Once policies are enforced, the system enters continuous monitoring mode. Every packet is evaluated against both the static policy (XDP rules) and the dynamic behavioral baseline (NAPSE profiles). This dual-layer approach catches both known threats (blocked by policy) and novel attacks (detected by behavioral deviation).

When a device deviates from its baseline—for example, an HVAC controller begins making DNS queries to domains associated with command-and-control infrastructure—the following sequence triggers automatically:

  • NAPSE flags the anomalous flow and extracts features
  • Hydra evaluates the features and assigns a threat confidence score
  • If confidence exceeds the configured threshold (default: 0.80), AEGIS executes containment
  • The device is quarantined to a restricted VLAN with only management access
  • A forensic snapshot of the device’s recent traffic is captured for investigation
  • SOC analysts receive an alert with full context: device identity, anomaly details, confidence score, and recommended remediation

Addressing Common IoT Zero Trust Challenges

Challenge: Devices That Cannot Be Patched

Many IoT devices run firmware that is never updated. Legacy building automation systems, medical devices with regulatory certification constraints, and industrial controllers with 10-year lifecycles all fall into this category. Zero Trust compensates by enforcing security at the network layer rather than the device layer. Even if the device itself is vulnerable, strict micro-segmentation and continuous behavioral monitoring prevent exploitation from succeeding. An attacker who compromises an unpatched camera finds themselves in a network segment with no lateral movement options, monitored by AI that will detect and contain any anomalous activity within milliseconds.

Challenge: Encrypted IoT Traffic

An increasing number of IoT devices use TLS for communication, making payload inspection impossible without man-in-the-middle proxying. HookProbe’s approach does not require decryption. NAPSE analyzes encrypted traffic using metadata: TLS version, cipher suites, certificate chains, SNI values, JA3/JA4 fingerprints, packet timing, and flow volume patterns. Research has shown that these metadata features alone achieve over 95% accuracy in detecting malicious activity within encrypted streams.

Challenge: Scale and Performance

Enterprise IoT deployments can involve tens of thousands of devices generating millions of flows per hour. Traditional security appliances cannot scale to this volume without introducing latency or dropping packets. HookProbe solves this by distributing enforcement across edge nodes running eBPF/XDP programs in the kernel fast path. Each edge node—even a Raspberry Pi 5—can process over 1 million packets per second with XDP, and the workload scales linearly by adding more edge nodes. There is no central bottleneck.

Challenge: False Positives in Behavioral Analysis

Behavioral baselines can trigger false positives when devices exhibit legitimate but unusual behavior—firmware updates, configuration changes, seasonal usage patterns. HookProbe mitigates this through multi-model consensus. The Hydra engine requires agreement across its anomaly detector, Bayesian scorer, and threat intelligence correlation before escalating to a blocking action. Borderline cases are flagged as suspicious and presented to analysts for review, while only high-confidence threats trigger automated containment. Over time, analyst feedback refines the models, continuously reducing false positive rates.

Compliance and Regulatory Alignment

Zero Trust for IoT aligns with multiple regulatory frameworks and industry standards:

  • NIST SP 800-207: HookProbe’s architecture directly implements the Policy Engine, Policy Administrator, and Policy Enforcement Point components defined in the NIST ZTA reference architecture.
  • IEC 62443: For industrial IoT environments, micro-segmentation via XDP satisfies the zone and conduit model requirements for industrial network security.
  • HIPAA / HITECH: Medical IoT devices handling PHI benefit from continuous monitoring and automated containment that demonstrates due diligence in protecting patient data.
  • MITRE ATT&CK for ICS: NAPSE detection rules map directly to MITRE ATT&CK techniques, providing audit-ready evidence of threat coverage.
  • NIS2 Directive: European organizations subject to NIS2 can demonstrate the “state of the art” security measures required by the directive through AI-native continuous monitoring.

Real-World Deployment Scenario

Consider a mid-sized hospital network with 2,000 connected medical devices: patient monitors, infusion pumps, imaging systems, and building automation. These devices span dozens of manufacturers, run various embedded operating systems, and cannot accept endpoint agents due to regulatory certification constraints.

A HookProbe deployment in this environment involves placing edge nodes at each network aggregation point—typically 8 to 12 nodes for a facility of this size. During the 72-hour discovery phase, NAPSE identifies all 2,000 devices, classifies them by type, and builds behavioral baselines. The system automatically generates micro-segmentation policies that restrict each device category to its required communication paths.

Within the first week of enforcement, the system detects a compromised patient monitor attempting to contact an external IP address via DNS tunneling—a technique invisible to signature-based detection. The Hydra engine scores the activity at 0.91 confidence, AEGIS quarantines the device, and the SOC team receives a detailed incident report. The entire response takes 8 milliseconds. Without Zero Trust enforcement, this compromised device could have served as a pivot point for accessing the hospital’s electronic health records system.

Getting Started with Edge-Native Zero Trust

Implementing Zero Trust for unmanaged IoT does not require ripping out existing infrastructure. HookProbe edge nodes deploy alongside your current network, operating in passive monitoring mode initially and transitioning to active enforcement as baselines mature. The key steps are:

  • Audit your IoT inventory: Identify all unmanaged devices and their network locations
  • Deploy edge nodes: Place HookProbe sensors at network aggregation points
  • Establish baselines: Allow 48-72 hours of passive observation
  • Review auto-generated policies: Validate least-privilege rules before enforcement
  • Enable enforcement: Transition from monitoring to active XDP-based blocking
  • Iterate: Refine policies based on analyst feedback and evolving device behavior

For detailed deployment guides and configuration references, visit the HookProbe documentation. To understand how edge-native detection compares to traditional centralized approaches, read our analysis on AI-native IDS beyond signature-based detection.

Frequently Asked Questions

Can Zero Trust be applied to devices that do not support authentication?

Yes. Network-level Zero Trust uses behavioral fingerprinting and traffic analysis instead of device-side authentication. HookProbe identifies devices through passive observation of their network behavior and enforces policies at the network layer using eBPF/XDP, requiring zero cooperation from the device itself.

What is the performance overhead of eBPF/XDP enforcement?

Minimal. XDP programs execute in the kernel fast path before packets reach the network stack. On a Raspberry Pi 5, XDP can process over 1 million packets per second. On x86 hardware with a 10GbE NIC, throughput exceeds 10 million packets per second with no measurable latency increase.

How does HookProbe handle IoT devices that change behavior legitimately?

The Hydra verdict engine uses multi-model consensus to distinguish genuine threats from legitimate changes. Firmware updates, configuration changes, and seasonal variations are scored across multiple models. Only when consensus exceeds the confidence threshold does automated containment trigger. Borderline cases are escalated to human analysts, and their decisions feed back into model training.

Does this approach work for industrial OT environments?

Yes. HookProbe supports industrial protocols including Modbus, BACnet, DNP3, and OPC UA. The NAPSE engine performs protocol-aware inspection for these protocols, and XDP enforcement can restrict OT devices to their required communication paths without impacting real-time control operations. The architecture aligns with IEC 62443 zone and conduit requirements.

What happens if an edge node goes offline?

XDP rules are loaded into the kernel and persist independently of the HookProbe userspace process. If the analysis engine goes offline, existing enforcement rules continue operating. When the node comes back online, it synchronizes state with the mesh network and resumes full analysis. During the offline period, traffic that matches existing rules is handled normally; only new threat detection is paused.

Related Articles

Zero Trust for IoT: Securing Unmanaged Edge Devices

Originally published at hookprobe.com. HookProbe is an open-source AI-native IDS that runs on a Raspberry Pi.

GitHub: github.com/hookprobe/hookprobe

Why I Built My Own WebSocket Service Instead of Paying for Pusher

Real-time features look simple from the outside.

A chat message appears instantly. A dashboard updates without refresh. A notification badge increments in the corner. A “someone is typing…” indicator just works.

But once you try to build those features into a product, you run into a very different reality:

  • WebSocket connections need to stay alive reliably
  • Private channels need authentication
  • Presence needs user tracking
  • Fanout needs to work across multiple nodes
  • Webhooks need retries
  • Usage needs to be measured
  • Costs get weird as usage grows

At some point I realized I had two options:

  1. Keep paying for a hosted real-time provider and accept the tradeoffs
  2. Build the service I actually wanted

I picked option 2.

That decision turned into Apinator: a real-time messaging platform and Pusher-style alternative with public, private, and presence channels, multi-tenant isolation, usage metering, and SDKs for Node.js, Python, PHP, Go, and browser clients.

This post is the story of why I built it, what turned out to be harder than expected, and when building your own WebSocket infrastructure is absolutely the wrong idea.

The Original Problem

I didn’t start with the goal of “building a WebSocket company.”

I started with a much more ordinary product need: I wanted reliable real-time features without handing over a core part of the stack to a black box I couldn’t control.

The usual hosted tools are good at getting you started. In many cases, they are the correct choice. You can ship quickly, wire up a client SDK, and move on.

But the deeper I got into real production requirements, the more the friction showed up:

  • I wanted predictable control over the infrastructure
  • I wanted multi-tenant behavior that matched my own product model
  • I wanted to understand exactly how auth, fanout, and presence behaved
  • I wanted better cost characteristics as usage increased
  • I wanted the option to self-host the core infrastructure

None of these problems are obvious in a simple demo. They show up later, when real traffic, retries, and operational edge cases start mattering.

That was the point where “just use a hosted provider” stopped feeling like a complete answer.

The Misleading Part About Real-Time Infrastructure

The misleading thing about WebSocket products is that the happy path is tiny.

If you reduce the problem enough, a WebSocket service is just:

{"event":"message-created","channel":"chat-room","data":"{"text":"hello"}"}

That part is easy.

The hard part is everything around it.

A real platform needs answers to questions like:

  • How do clients authenticate subscriptions to private channels?
  • How do presence channels track members across reconnects and multiple tabs?
  • How do you fan out events across multiple servers?
  • How do you verify webhook authenticity?
  • How do you enforce plan limits without turning the hot path into a bottleneck?
  • How do you expose useful SDKs without making every language feel like a second-class citizen?

This is where a lot of “simple WebSocket server” projects stop being simple.

Why I Didn’t Want a Thin Wrapper

I wasn’t interested in building a toy socket server that worked in development and fell apart under real product constraints.

If I was going to do this, it needed to cover the boring but important parts:

  • public channels
  • private channels with HMAC auth
  • presence channels with member tracking
  • webhook delivery
  • usage accounting
  • rate limiting
  • multi-tenant isolation
  • support for multiple regions

That immediately changed the shape of the system.

Instead of one process doing everything, I split the architecture into a control plane and a data plane.

At a high level:

  • The control plane handles accounts, app configuration and management APIs
  • The data plane handles WebSocket connections, event publishing, channel auth, and real-time fanout
  • Redis sits on the hot path for fanout, caching, counters, and rate limiting
  • PostgreSQL stays in the control plane where consistency matters more than latency

That separation ended up being one of the best decisions in the project.

The Architecture I Ended Up Building

Apinator is built in Go as a multi-tenant WebSocket system with distinct binaries for the control plane, data plane, migrations, and webhook worker.

The core pieces look like this:

  • api: account management, config, and internal APIs
  • realtime: the WebSocket data plane
  • worker: webhook delivery with retries
  • migrate: database migrations

The data plane has no direct PostgreSQL dependency. It resolves tenant configuration through Redis with an internal API fallback.

That matters because the data plane is the part that needs to stay lean. Every extra dependency in the critical path shows up under load.

A few specific decisions were especially important.

1. Redis for fanout, not just caching

I used Redis Pub/Sub for cross-node event fanout, plus ref-counted subscriptions so nodes only stay subscribed to channels that actually have connected clients.

Without something like that, horizontal scaling becomes fake. You can add more nodes, but events don’t reach all connected subscribers reliably.

2. HMAC auth for private and presence channels

Private and presence subscriptions need server-side authorization. That means the browser cannot be trusted to decide who can subscribe to what.

So the flow is:

  1. The client asks to subscribe
  2. Your backend authenticates the user
  3. Your backend signs the channel subscription
  4. The WebSocket service validates the signature

That sounds standard, because it is. But getting the ergonomics right across SDKs matters a lot.

3. Presence is more annoying than it looks

Presence is not “just a list of users online.”

You have reconnects, multiple tabs, transport flapping, disconnect timing, and the question of when someone should count as present. If the same user has three tabs open, are they one member or three?

Those edge cases are where presence systems get messy fast.

4. Webhooks need a delivery model, not a POST request

It is easy to say “send a webhook when X happens.”

It is harder to answer:

  • What if the destination is down?
  • What if it times out?
  • What if it returns 500 three times?
  • What if you need signature verification?

That pushed me toward a transactional outbox pattern and a dedicated worker with retry logic and backoff instead of “fire and hope.”

5. Limits belong in the design early

This is one of the least glamorous parts, which is why it gets skipped.

But if you’re building a multi-tenant platform, usage accounting is not an add-on. It shapes the whole system.

You need to know what you are counting, where you are counting it, and how much consistency you actually need. If you leave that vague, you end up retrofitting it into the hottest code path later.

That is a bad place to discover you need atomic counters.

What Was Harder Than I Expected

A few things were clearly harder than I expected.

Connection lifecycle edge cases

Most bugs in real-time systems are not in the initial connect flow. They are in reconnects, dropped sockets, duplicate subscriptions, stale presence members, race conditions during auth, and weird timing windows when clients come and go quickly.

Keeping the SDKs consistent

It’s one thing to build the backend.

It’s another to make the developer experience feel coherent across Node.js, Python, PHP, Go, and browser clients. If each SDK has different naming, behavior, or auth assumptions, the platform feels unreliable even if the backend is correct.

Avoiding “accidental complexity”

There is always a temptation to keep adding platform features because you are already deep in infrastructure land.

I had to keep pulling the design back to the core question:

What does a developer actually need to publish an event, authenticate a channel, and trust the system in production?

If the answer didn’t support that, it probably didn’t belong in the first version.

What I’d Do Differently

If I were starting from scratch again, I would do a few things earlier:

  • Define operational metrics sooner
  • Write more failure-mode tests before polishing APIs
  • Be even stricter about keeping the hot path small
  • Treat SDK ergonomics as part of the product, not follow-up work

That last point matters more than it sounds.

Infrastructure products win partly on correctness, but they also win on how little cognitive load they add to the developer using them.

When You Should Not Build Your Own WebSocket Service

To be clear: most teams should not build this.

If your need is “I want chat, notifications, or presence working this week,” use a hosted provider and move on.

Building real-time infrastructure is only rational if at least one of these is true:

  • real-time is central to your product
  • you need tighter control over behavior or deployment
  • your cost profile makes third-party pricing painful
  • you want self-hosting as a product or compliance requirement
  • you are willing to own the operational complexity

If none of that applies, don’t romanticize infrastructure work. It is very easy to turn months of engineering time into a more fragile version of something you could have bought.

Why I’m Still Glad I Built It

Even with all of that, I’m glad I built it.

Not because it was easy. It wasn’t.

Not because I think every existing provider is bad. I don’t.

I’m glad I built it because I wanted a real-time platform whose internals I understood, whose tradeoffs I chose deliberately, and whose developer experience matched the way I think real-time features should be integrated into modern apps.

That became Apinator.

Today it supports:

  • public, private, and presence channels
  • server-side event publishing
  • webhook verification
  • multi-tenant apps
  • usage metering and plan enforcement
  • SDKs for Node.js, Python, PHP, Go, and browser clients

It is the service I originally wanted to use.

If You’re Building Real-Time Features

If you are working on chat, live dashboards, collaborative UIs, notifications, or presence, the main lesson I learned is this:

Real-time is not hard because of WebSockets.

It is hard because of everything around WebSockets.

That’s the part the glossy demos skip.

If you want to see what that looks like as a product, you can check out Apinator.

If there’s interest, I can write a follow-up post breaking down the technical architecture in more detail, including channel auth, presence design, multi-node fanout, and webhook delivery.

I Scanned 10 Developer Tools for AI Agent-Readiness. Only One Passed.

Everyone’s building AI agents. Nobody’s building for them.

I’ve been working on agent integrations and kept running into the same problem: when we say “AI agents can use APIs,” how many developer tools are actually set up for an agent to discover and interact with autonomously?

So I ran an agent-readiness audit on 10 well-known developer tools. The scanner checks 32 signals across 6 categories:

  • Discoverability — can agents find you?
  • Comprehension — can agents understand your API?
  • Usability — can agents interact with you?
  • Stability — can agents depend on you?
  • Agent Experience — what happens when an agent shows up?
  • Transactability — can agents do business with you?

Each category gets a tier: Ready, Partial, or Not Ready. To “pass,” a tool needs at least half its categories at Ready.

One tool passed. Nine didn’t.

The Results

Resend — 4/6 Ready ✅

The clear winner, and it wasn’t close. Resend has an MCP endpoint at /.well-known/mcp.json, a public OpenAPI spec with 39 fully documented endpoints, Schema.org structured data on the homepage, and returns proper JSON errors with consistent structure.

This is what agent-readiness actually looks like: an agent can discover the API through protocol-based discovery (MCP), understand the full API surface through machine-readable specs (OpenAPI), and verify what the product does through structured data. No human intervention required at any step.

Stripe — 1/6 Ready (Stability)

The most surprising result on the list. Stripe literally invented the Agentic Commerce Protocol. They have a proper llms.txt file. They are, arguably, the most developer-friendly API on the internet.

But: no OpenAPI spec at standard discoverable paths, no MCP endpoint, no /.well-known/agent.json. Agent Experience scored Red. An agent hitting Stripe’s /api endpoint gets an HTML page, not a machine-readable spec.

The company building the future of agent payments isn’t agent-ready itself.

Vercel — 1/6 Ready (Stability)

Good fundamentals — changelog, status page, proper security headers. But the OpenAPI spec is behind a login wall, and there’s no MCP endpoint. An agent would find the documentation but couldn’t machine-read the API surface without authenticating first.

Postmark — 1/6 Ready (Discoverability)

Has structured data and llms.txt, which is already more than most. But the scanner got rate-limited (429) on half its checks — the pricing page, signup page, and several API paths all returned “Too Many Requests.”

This is actually an interesting finding in itself: aggressive rate limiting without rate-limit headers means agents get blocked with no way to self-throttle. If your rate limiter doesn’t include Retry-After or X-RateLimit-* headers, you’re not just blocking abuse — you’re blocking legitimate agent discovery.

Clerk — 0/6 Ready

Has an impressive 2,395-line llms.txt — more content than most tools’ entire documentation. But no OpenAPI spec at discoverable paths, no MCP, and the Terms of Service appear to prohibit automated access.

All that content investment is invisible to protocol-based agent discovery.

Neon — 0/6 Ready

The llms-full.txt is 32,588 lines — by far the largest in the set. But Comprehension scored Red because there’s no OpenAPI spec at discoverable paths, and no structured data on the homepage.

This is the clearest example of a pattern I kept seeing: heavy investment in LLM-readable content while missing the machine-readable infrastructure that agents actually use for discovery.

Supabase — 0/6 Ready

This one genuinely surprised me. Supabase has an MCP server — I use it daily. But /.well-known/mcp.json returns 404. No structured data, no OpenAPI spec at standard paths, llms.txt exists but was flagged as basic. Discoverability scored Red.

The tools are there, but the front door isn’t wired up for autonomous discovery. An agent using MCP protocol-based discovery would never find Supabase’s MCP server.

Plaid — 0/6 Ready

Documentation is good, sandbox is available, but no MCP, no OpenAPI at standard paths. Pricing is behind a table with no structured data. An agent comparing fintech APIs programmatically wouldn’t be able to include Plaid in its evaluation.

Twilio — 0/6 Ready

Both Discoverability and Agent Experience scored Red. The llms.txt exists but was too large to parse (body truncated). No MCP, no OpenAPI at discoverable paths. For a company that’s been API-first for 15+ years, the agent layer is essentially absent.

SendGrid — 0/6 Ready

Inherits Twilio’s infrastructure (it’s a Twilio product now), so same limitations. The openapi.json path returns an HTML page instead of JSON — which is a particularly frustrating failure mode for an agent expecting structured data.

What the Data Actually Shows

The gap isn’t API quality. Every tool on this list has APIs that developers love. The gap is in the discovery and machine-readability layer — the difference between “a developer can read our docs” and “an agent can programmatically find, evaluate, and start using our API.”

Three specific findings stood out:

Almost nobody has /.well-known/mcp.json

Only Resend. This is the standard path for MCP protocol-based discovery — how an agent using MCP finds your server endpoint. Without it, your MCP server might exist, but agents following the protocol can’t discover it.

llms.txt adoption is strong — but insufficient

8 out of 10 tools had an llms.txt file. That’s encouraging adoption. But llms.txt solves a different problem than agent discovery. It helps LLMs understand what your product does. It doesn’t help an agent using MCP or A2A protocol-based discovery find your API.

An agent browsing /.well-known/mcp.json endpoints won’t read your llms.txt. Different protocols, different discovery mechanisms.

Size of llms.txt doesn’t correlate with readiness

This was the most counterintuitive finding. Neon’s 32,588-line file didn’t help because the structured infrastructure around it was missing. Resend’s much smaller file worked because it had OpenAPI, MCP, and structured data backing it up.

The lesson: llms.txt is valuable when it sits on top of solid machine-readable infrastructure. It’s not valuable as a replacement for that infrastructure.

What This Means for Builders

If you’re building agents that need to autonomously discover and evaluate APIs, you’re going to hit walls everywhere. The infrastructure layer that MCP, A2A, and x402 assume — machine-readable discovery, structured pricing, programmatic auth documentation — barely exists yet.

Build your agents to handle graceful degradation, because most APIs are still built for human developers browsing documentation pages, not autonomous agents making programmatic decisions.

And if you’re building an API: the bar for agent-readiness is lower than you think. Resend passed with straightforward infrastructure — a public OpenAPI spec, an MCP endpoint at the standard path, and structured data on the homepage. No exotic technology. Just the basics, done correctly.

The scanner is free at scan.strale.io if you want to check your own stack. Happy to share the full JSON scan reports for any of these tools — just ask in the comments.

Versioning gameplay scanline contracts in the TD2 SDL port

Versioning gameplay scanline contracts in the TD2 SDL port

This checkpoint moves one of the gameplay renderer shortcuts into a cleaner shape.

Until now, the SDL runtime loaded the live-race scanline overlay through one scene-specific path. That was enough to prove the horizon fix on the promoted gameplay_live_race_mid bundle, but it was not a good long-term surface for more gameplay phases.

So I replaced that hardcoded lookup with a versioned contract:

  • rom_analysis/docs/gameplay_scanline_contracts.jsonc

The runtime now selects scanline overlays from that contract, and the tracked sources behind it currently are:

  • tools/out/lane3_live_race_mid_scanline_full/td2_scanline_step_test.json
  • tools/out/lane3_live_entry_frame03250_scanline_full/td2_scanline_step_test.json

The contract still uses a deliberately narrow field set:

  • main_layers
  • bg1_hscroll/bg1_vscroll
  • bg2_hscroll/bg2_vscroll
  • bg3_hscroll/bg3_vscroll

That is enough to keep the first solved gameplay consumer intact. The live-race bundle still renders with the restored sky / mountain / roadside split, and that stays protected by the new test_scanline_contract.sh smoke.

The more interesting part of this checkpoint is the second gameplay consumer.

I promoted tools/out/lane3_live_entry_frame03250_bundle/design_pack onto the same contract-backed surface and captured a full 224-scanline trace for it. That closes a useful architectural question: later gameplay bundles can now opt into the same scanline path without needing another runtime special case.

But it also closed a stronger negative result.

When I compared the 3250 runtime output with and without the new scanline contract, the result was still:

  • 0 mismatched pixels

That means the second gameplay phase is not blocked on trace plumbing anymore. It is blocked on missing renderer inputs beyond the current field set. In other words, scrolls plus main_layers were enough for the first live-race fix, but they are not enough for the later live-entry phase.

That is exactly the kind of boundary I wanted from this step: less ad hoc code, one versioned path for gameplay scanlines, and a clearer definition of what the next renderer promotion actually has to solve.