Data Flow
Network Traffic Flow
Agent Mode
In agent mode, Synapse operates as a kernel-level firewall with no HTTP proxying.
- XDP filtering — Packets are evaluated at the earliest point the kernel offers, before routing. Known-bad addresses from threat intelligence and access rules are dropped there, without a context switch into user space.
- Firewall backend — Synapse auto-selects the best available backend: XDP > nftables > iptables > userland. Rules from the Gen0Sec API (allow/block lists) are enforced here.
- TCP fingerprinting — JA4T and JA4L fingerprints are captured from SYN packets for OS identification and latency measurement.
- Clean traffic reaches the application directly — no proxying overhead.
Proxy Mode
In proxy mode, Synapse adds full reverse proxy capabilities on top of agent features.
- XDP filtering — Same kernel-level packet filtering as agent mode.
- TLS termination — Terminates with your certificates, or passes the connection through by SNI. JA4 (ClientHello) and JA4S (ServerHello) fingerprints are captured during the handshake.
- WAF engine — Wirefilter-compatible expression language evaluates requests against security rules. GeoIP and ASN data enrich rule evaluation.
- CAPTCHA — Suspicious requests can be challenged with hCaptcha, reCAPTCHA, or Turnstile.
- Content scanning — Bodies selected by a
content_scanningWAF rule are scanned via ClamAV. - Reverse proxy — Clean requests are forwarded to upstream servers with weighted load balancing.
- JA4H fingerprinting — HTTP request headers are fingerprinted at the application layer.
Threat Intelligence Flow
Synapse continuously syncs threat data from the Gen0Sec API.
| Data Source | Update Method | Used By |
|---|---|---|
| Gen0Sec Threat API | Periodic API polling | Access rules, IP reputation |
| Threat MMDB | File-based, hot-reloadable | GeoIP, ASN, threat scoring |
| GeoIP MMDB | File-based, hot-reloadable | Country/city/ASN lookups |
| Access Rules | API sync + SIGHUP reload | Firewall allow/block lists |
| Cerebellum Verdicts | Real-time push | Threat classification updates |
Fingerprinting Pipeline
JA4+ fingerprints are captured at different layers and included in every access log entry.
| Layer | Fingerprints | Capture Point |
|---|---|---|
| TCP | JA4T, JA4TS, JA4L, JA4LS | SYN/SYN-ACK packets |
| TLS | JA4, JA4S, JA4X | TLS handshake |
| HTTP | JA4H | Request headers |
| SSH | JA4SSH | SSH session traffic |
| DHCP | JA4D, JA4D6 | DHCP messages |
| Scan | JA4TScan | Active TCP probes |
Fingerprints flow into:
- Access logs — Every request includes all available fingerprints
- Event queue — Batched for downstream analysis
- Cerebellum — ML correlation across all sensors
Where decisions are made, and where they are enforced
The single most useful thing to understand about the data flow is that the packet path only ever compares things it can read from a packet header. Everything richer is resolved somewhere else, before the packet arrives.
| Condition | Resolved | By |
|---|---|---|
| ASN, country in access rules | Ahead of time, into IP ranges | Cerebellum, at config generation |
| ML verdict, IDS context, threat score, workload identity | On the host, at decision time | Amygdala |
| Address, port, protocol, TCP flags, fingerprint, rate | On the packet path | Hillock in the kernel |
So "block this ASN" never becomes an ASN lookup per packet — it becomes a set of address blocks generated upstream. And "block when the classifier says C2 and the IDS already alerted" is evaluated on the host, which then installs a plain address block.
Two consequences worth planning around:
- Enforcement cost is flat. An elaborate policy costs the same per packet as a simple one, because the kernel is comparing the same primitives either way.
- Pre-resolved conditions are as fresh as the last config generation, not as fresh as the packet. A network that announces a new prefix is covered at the next regeneration. Where that matters, match on it live through Amygdala instead.
Event & Log Processing
Synapse uses a unified event queue for all telemetry.
Every layer that reaches a verdict — access rules, the smart firewall, the IDS, the WAF, threat intelligence, CAPTCHA, rate limiting — emits the same structured event. One stream, whichever layer decided, which is what makes "why was this client blocked" a single question rather than a correlation exercise.
See Security Event Export for what each sink is for.
Event Types
| Event | Description | Interval |
|---|---|---|
| Access log | Per-request log with fingerprints, GeoIP, threat data | Real-time |
| TCP fingerprint stats | Aggregated SYN fingerprint statistics | Configurable (default 60s) |
| Fingerprint events | Individual fingerprint observations | Configurable (default 30s) |
| BPF stats | eBPF program statistics and dropped IPs | Configurable (default 60s) |
| Threat intel updates | Access rule and threat feed sync results | On sync |
Log Output
Access logs include full request context with all fingerprints:
{
"timestamp": "2025-10-29T12:34:56.789Z",
"client_ip": "192.168.1.100",
"geo": { "country": "US", "city": "San Francisco", "asn": 13335 },
"http": {
"method": "GET",
"path": "/api/data",
"status": 200,
"ja4h": "ge11cr15enus_a1b2c3d4e5f6_123456789abc_def012345678"
},
"tls": {
"ja4": "t13d1516h2_8daaf6152771_b186095e22b6",
"ja4s": "t1302h2_1301_a56c5b993250",
"ja4x": "aae71e8db6d7_b186095e22b6_c1a4f9e7d8b3"
},
"tcp": {
"ja4t": "65535_2-4-8-1-3_1460_7",
"ja4l": "12500_64"
}
}
Full Platform Data Flow
When deployed as a full stack (Cerebrum + Synapse + Jailer + Cerebellum), data flows across all components.
- Cerebrum captures wire-speed metadata (JA4+ fingerprints, IDS alerts) and sends it to Cerebellum
- Synapse sends access logs, fingerprint events, and threat data to Cerebellum
- Cerebellum runs ML inference across all sensor data, correlates cross-site patterns, and pushes updated threat verdicts back to Cerebrum and Synapse in milliseconds
- Jailer enforces per-process sandboxing — file, network and exec control — through BPF LSM hooks, independently of the traffic path
Service Discovery
Upstreams are declared in a file, upstreams.yaml, and hot-reloaded when it changes —
a rewrite is picked up without a restart and without dropping connections.
| Source | A file on the host, watched for changes |
| Reload | Automatic on write; no restart, no dropped connections |
| Backends | One per route, or several with weights |
| Health | Probed on an interval; failed backends leave rotation and return when they recover |
File discovery is the only provider implemented. On Kubernetes, use the Ingress and Gateway API controller instead — it discovers backends from Ingress and Gateway resources, which is the idiomatic path there.