Skip to content

nuclide-research/herald

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

8 Commits
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

herald

Declarative HTTP auth-probe tool for AI/LLM infrastructure.

release license go NuClide

FeaturesInstallationUsageSchemaPlatformsRestraint


herald reads platform YAML configs, sweeps a list of IPs, and outputs NDJSON findings. It is the HTTP application-layer auth probe in the NuClide chain: after aimap answers "what service is this?" and scanner answers "what version?", herald answers "is this open?"

Population-scale surveys of AI/LLM infrastructure (Open WebUI, Dify, Flowise, Langfuse, LiteLLM, AnythingLLM, LibreChat, LobeChat, RAGFlow, OpenHands, Phoenix) follow a repeating pattern:

shodan download -> extract IP:port list -> hit 2-3 endpoints per host
-> parse JSON field -> classify open / closed -> structured output

Every survey used to ship a one-off probe script. herald collapses that work to a YAML config: one file per platform, declaring the endpoints, the JSON field paths to inspect, the values that constitute an "open" finding, and any extra fields to extract.

Features

  • Declarative YAML probes. New platform is a new file, no code changes
  • 11 platforms shipped: Open WebUI, Dify, Flowise, Langfuse, LiteLLM, AnythingLLM, LibreChat, LobeChat, RAGFlow, OpenHands, Phoenix
  • 4 match types: dot-path field equals value, field exists, top-level array non-empty, body substring
  • 3 extract types: dot-path field, array count, indexed-array field
  • Go concurrency, 1,140 Langfuse hosts in under 60 seconds at 50 workers
  • NDJSON output. Pipe to visorlog ingest, jq, wc -l, or anywhere else
  • Single static binary, standard library plus gopkg.in/yaml.v3
  • Reads metadata only. Does not authenticate, register accounts, or invoke LLM completions

Installation

go install -v github.com/nuclide-research/herald@latest

Or build from source:

git clone https://github.com/nuclide-research/herald
cd herald
go build -o herald .

Requires Go 1.21 or later.

Usage

# List available platforms
herald -list

# Sweep
cat ip-port.txt | herald -platform dify

# With explicit options
cat ip-port.txt | herald \
  -platform open-webui \
  -workers 50 \
  -timeout 7 \
  -platforms ./platforms

Input format: one IP:PORT:SCHEME per line.

124.220.32.195:80:http
206.206.192.179:3000:http
85.214.93.104:4000:http

Output format: NDJSON, one finding per line.

{"platform":"langfuse","ip":"206.206.192.179","port":3000,"scheme":"http","probe_id":"signup_open","finding":"SIGNUP_OPEN","severity":"medium","ts":"2026-06-06T08:33:37Z"}
{"platform":"langfuse","ip":"206.206.192.179","port":3000,"scheme":"http","probe_id":"health_open","finding":"HEALTH_OPEN","severity":"info","fields":{"version":"3.132.0"},"ts":"2026-06-06T08:33:37Z"}

Platform config schema

Example (platforms/dify.yaml):

name: dify
description: "Dify LLM app development platform"
default_ports: [80, 443, 3000, 8080]
probes:
  - id: signup_open
    endpoint: /console/api/system-features
    match:
      field: is_allow_register
      value: true
    finding: SIGNUP_OPEN
    severity: high
    extract:
      - field: sso_enforced_for_signin
        as: sso
      - field: "license.status"
        as: license

Match types:

  • field plus value: dot-path field equals expected value
  • field plus exists: true: field exists at path
  • array_nonempty: true: top-level array (or data array) has elements
  • body_contains: raw substring match against response body

Extract types:

  • field plus as: extract dot-path field value
  • array_count: count elements in top-level array
  • array_field plus index plus as: extract a field from a specific array element

Supported platforms

Platform Probes Validated against
dify 3 1,600-host Cat-DF survey (2026-06-06)
open-webui 4 5,097-host Cat-OW survey (2026-06-06)
flowise 1 841-host Cat-FW survey (2026-06-06)
langfuse 2 1,140-host Cat-LF survey (2026-06-06)
litellm 2 2,209-host Cat-05 survey (2026-06-06)
anythingllm 1 232-host survey (2026-06-06, all closed)
librechat shipped LibreChat OSS survey
lobechat shipped LobeChat OSS survey
ragflow shipped RAGFlow OSS survey
openhands shipped OpenHands OSS survey
phoenix shipped Arize Phoenix survey

Tool family

Tool Role
aimap TCP/TLS fingerprinting plus service deep enumeration, "what is this?"
scanner Liveness plus banner plus version, "is this alive, what version?"
herald HTTP application-layer auth probe, "is this open?"

The three are complementary. herald fills the gap between "this is Dify" (aimap) and "this Dify has auth disabled" (formerly manual, now declarative YAML).

Design references

  • Security with Go (Packt, 2018): channel-semaphore concurrency pattern, custom TLS transport, url.Parse path injection
  • Powerful Command-Line Applications in Go (Pragmatic, 2021): HTTP client architecture, NDJSON output, sentinel errors
  • Hacking APIs (No Starch, 2022): the public-system-info endpoint discovery pattern that motivates Dify's /console/api/system-features probe

Restraint

herald reads metadata. It does not authenticate, register accounts, or invoke LLM completions. The probes hit endpoints that are intentionally public (config endpoints, sign-in pages, version disclosures) and classify the host based on what the operator's configuration reveals.

Where a finding requires the next step (for example, confirming that is_allow_register: true actually allows registration), that step is performed manually with explicit operator or CERT coordination. Never automated at population scale.

Our other projects

  • aimap, AI/ML infrastructure fingerprint scanner
  • scanner, full-handshake banner stage between passive discovery and deep enumeration
  • glance, schema-only sensitivity analyzer for sealed corpora
  • VisorLog, finding ledger and ingest pipeline
  • BARE, semantic exploit-module ranking over scanner findings

License

MIT. Part of the NuClide toolchain. Contact: nuclide-research.com

Releases

No releases published

Packages

 
 
 

Contributors

Languages