The Problem During a penetration test or network audit you often encounter an open HTTP port and need to know which LLM back‑end is listening (Ollama, vLLM, LiteLLM, etc.). Manually probing each vendor’s API is slow and error‑prone, especially when dozens of services share similar endpoints.
What This Does julius ships as a single Go binary that sends a curated set of HTTP probes (YAML files under probes/ and pkg/scanner/testdata/fixtures/) and matches the responses against signature rules in pkg/rules/. The core CLI lives in cmd/julius/main.go, which delegates to the runner package (pkg/runner/runner.go). The runner loads the probe definitions, builds a TLS configuration if needed, and orchestrates concurrent scanning via the scanner (pkg/scanner/scanner.go). Results are formatted by the output package (pkg/output/output.go) into table, JSON or JSONL.
How It Is Wired
- Entry point –
cmd/julius/main.goparses CLI arguments and invokesrunner.Run. - Runner –
pkg/runner/runner.go(functionsRun,loadProbes,buildTLSConfig) reads probe YAML files (file I/O, 8 functions total) and creates aScannerviapkg/scanner.NewScanner. - Scanner –
pkg/scanner/scanner.goprovidesNewScanner,ScanAll, andScan.NewScanneris the most widely used constructor (called from 38 places). It configures concurrency, timeout (WithTimeout– 37 callers), and delegates each target tomatchProbe/matchProbeAny. - Probe matching –
pkg/probe/probe.goparses a probe definition, expands base paths (expand.go), and returns aDoRequestthat performs the HTTP call (doHTTPRequest). The request/response handling touches the filesystem (reading embedded probe assets). - Rule evaluation – Each response is fed to the rule set in
pkg/rules/. Functions likeMatch(called from 11 places) execute the signature logic defined inrule_*files. - Output – After all scans complete,
pkg/output.NewTableWriteror the JSON writers serialize theResultstructs (pkg/types/result.go) and write to stdout.
The call graph shows a hub at NewScanner and Run; changes to those functions propagate to dozens of callers, so they carry the largest blast radius. No circular dependencies were detected, and the internal graph consists of 317 call edges across 32 Go files.
How To Use It
# Install the latest version
go install github.com/moses-y/julius/cmd/julius@latest
# Scan a single endpoint
julius probe https://target.example.com
# Scan a list of targets (one per line)
cat hosts.txt | julius probe -f -
# Choose JSON output
julius probe https://target.example.com -o json
The binary compiles with the Makefile (make build produces julius). No external configuration files are required; probe definitions are bundled under probes/ and can be extended by adding new YAML files following the existing schema.
Real‑World Use A security engineer adds julius to a nightly discovery job that reads CIDR ranges, runs julius probe against each host, and stores the JSONL output in a SIEM. The Specificity score from the rule engine helps prioritize follow‑up testing (e.g., a 100‑score Ollama service vs. a generic OpenAI‑compatible endpoint).
Code Health & Issues
- Medium – Dependency‑vulnerability gate missing –
.github/workflows/*.ymlcontain no step that scans Go modules for known CVEs. Adddependency-review-actionorosv-scannerto the CI pipeline. - Low – Workflow timeout not set –
ci.ymldefines four jobs withouttimeout-minutes; long‑running or stuck jobs can overlap on the default six‑hour limit. Add a reasonable timeout (e.g.,timeout-minutes: 30).
Measured findings – the test suite contains two high‑cognitive‑load issues: deep nesting (max depth 8) and an oversized file (pkg/scanner/scanner_test.go, 1,204 lines). Refactor into smaller, focused test files. A medium‑severity duplication exists across four rule files; extract the repeated 6‑line block into a shared helper.
The Bottom Line julius provides a focused, Go‑native fingerprinting tool that reliably identifies dozens of LLM services with minimal external dependencies. The codebase is well‑tested but suffers from a few large, deeply nested test files and a lack of automated dependency‑vulnerability checks. It is suitable for security teams that need a fast, offline scanner and are comfortable maintaining Go binaries.