How it works
Traffic enters the proxy listener (plain or TLS). The first matching route wins. IP filtering and rate limiting run before forwarding. Fingerprints are derived from the client→proxy side of the connection; the proxy then injects trusted headers so backends do not rely on spoofable client fields.
With or without the eBPF agent
Section titled “With or without the eBPF agent”You can run only the proxy or the proxy plus the eBPF agent — they are different operational setups (Compose files and images are not interchangeable). Details: Containers.
- Proxy alone (typical “plain” image / single service): TLS and HTTP/2 are terminated in-process; JA4 and HTTP/2 (Akamai) headers are produced here when enabled. There is no TCP SYN capture — no
x-tcp-p0ffrom the kernel path. - Proxy + agent: a sidecar loads XDP, pins maps, and records SYNs; the proxy reads those maps and adds
x-tcp-p0f. Needs Linux (e.g. kernel ≥ 5.11), bpffs, and the extra privileges described in eBPF TCP setup.
JA4 and Akamai always come from the proxy process; only the SYN fingerprint depends on the agent.
Fingerprint timing
Section titled “Fingerprint timing”- TLS (JA4): Computed from the ClientHello; in typical use, once per TLS session and reused for requests on that session.
- TLS (JA4-S v1): Same ClientHello source, but ephemeral extensions (e.g.
session_ticket,padding) are stripped before hashing, producing a stable fingerprint that does not change across reconnects caused by those extensions. Emitted asx-tls-ja4-sv1andx-tls-ja4-sv1r. - HTTP/2 (Akamai): From HTTP/2 SETTINGS / control frames on that connection.
- TCP SYN: From the initial SYN when eBPF is enabled; applies to the TCP connection, not each HTTP request on keep-alive.
Trust boundary
Section titled “Trust boundary”The proxy overrides client-supplied X-Forwarded-* values. Treat x-tls-*, x-http2-*, and x-tcp-* headers as produced by the proxy, not the client.