Skip to content

Joern Gateway

RORO edited this page Jul 2, 2026 · 2 revisions

Joern Gateway

A standalone Joern server in server mode plus a Python WebSocket gateway, in Docker. The gateway turns Joern's async protocol into one simple HTTP call that the agent drives with joernctl.

Joern gateway architecture

How it works

  • Joern server (joern --server) speaks the scala-repl-pp protocol: POST /query returns a UUID, the finished UUID is pushed over the /connect WebSocket, and you fetch it from GET /result/:uuid.
  • gateway.py holds the WebSocket open, correlates UUIDs, and exposes POST /query that returns {"success","stdout","uuid"}.
  • joernctl is a stdlib-only host client. Only the gateway port 127.0.0.1:8099 is exposed. Joern's 8080 stays inside the container.

Commands

cd joern-gateway
docker compose up -d --build     # first build pulls the JDK and Joern
./joernctl health
./joernctl import /work/target [name]
./joernctl query '<cpgql>'       # use - to read from stdin
./joernctl script ./query.sc     # send a file as one query
./joernctl --json query '...'    # raw gateway JSON
docker compose down

Configuration

Set on the compose environment block:

  • JOERN_QUERY_TIMEOUT (default 300): per-query timeout in seconds.
  • JOERN_USER / JOERN_PASS: enable basic auth on Joern (set both).
  • JAVA_OPTS: JVM flags, for example -Xmx6G for large CPGs.

Build arg JOERN_VERSION pins a Joern release (default latest).

Notes

  • First build is large (a JDK plus the Joern CLI).
  • One session holds one CPG. A new importCode replaces it. Heavy queries queue.
  • The gateway runs whatever CPGQL you send, which is code execution inside the container. Keep the port on loopback and only analyze code you are authorized to.

Clone this wiki locally