aicheck inventory
The hosted scanner checks one host, once. aicheck inventory is the
continuous version: a local, multi-host inventory of exposed self-hosted AI
services: Ollama, n8n, vLLM, Langfuse and the rest of the tier-1 list. It runs
on your machine. Nothing leaves it except read-only GET probes to
hosts you listed yourself. No account, no phone-home, results stay on your disk.
Three states, not one verdict
Every probed product lands in exactly one of three channels:
- findings: no authentication, graded CRITICAL/HIGH/MEDIUM.
- observations: auth present, product confidently fingerprinted. Reported as INFO, never graded, never fails CI. A bare 401 on a well-known port is never reported.
- unknown: probes unanswered. The report says so
(
coverage.partial); a partial sweep's clean result is not proof of clean.
Drift
Each finding gets a stable id (a hash of check, host, scheme, port, path), so
run-to-run the tool reports new, fixed,
changed and still-open, not a wall of duplicates.
A host that didn't answer this run is excluded from every drift bucket: a dead
host never looks remediated. --fail-on-new exits 1 when something new
appeared, so a cron job or pipeline can gate on it.
Webhooks
Optionally POST the drift summary to your endpoint: a SIEM, a
ticket queue, an internal hook. With --webhook-secret the exact body is
HMAC-signed (X-Aicheck-Signature: sha256=<hex>) so the receiver can
verify it. Webhooks go where you point them; never to unauth.dev.
Frozen report schema v1
The JSON in <state-dir>/runs/<run_id>.json is schema v1:
additive-only. New fields may appear; renames, removals or type
changes bump schema_version. Build dashboards and parsers against it.
Any breaking change bumps the schema version first.
Quickstart
pip install aicheck-scan
targets.yaml:
targets:
- host: 10.0.1.5
owner: ml-platform
env: production
- host: ollama.dev.internal
owner: data-science
env: development
# - host: 10.0.2.0/24 # CIDRs expand (max 256 by default)
aicheck inventory --targets targets.yaml --state-dir ./state --allow-private --i-own-these-targets
--allow-private is required for RFC1918/internal sweeps and always
requires --i-own-these-targets. Targets also load from CSV or
flow-log-ish JSONL. Docker:
docker run --rm --network host -v "$PWD/targets.yaml:/targets.yaml:ro" -v "$PWD/state:/state" ghcr.io/unauthdev/aicheck-scan inventory --targets /targets.yaml --state-dir /state --allow-private --i-own-these-targets
Or start passive: --flow-logs turns VPC flow logs (AWS text/.gz
or JSONL) into an attributed target list with zero probing;
--verify sweeps what it finds:
aicheck inventory --flow-logs vpc-flow.log.gz --state-dir ./state --verify --allow-private --i-own-these-targets
Run it on a schedule (cron, systemd timer) and the drift report is the inventory. Source and install notes: unauthdev/aicheck-scan.
Two more doors
Class B data plane (customer estates only): with
--deep --deep-packs data-plane --i-own-these-targets it also
checks whether gRPC data planes accept connections (Milvus :19530, Qdrant
:6334, Weaviate :50051), zero bytes sent, only reported when the product is
already fingerprinted. Reachable, never "data accessible". Default traffic
stays GET-only; the hosted scanner and the Action never run it.
Workflow templates: aicheck template file.json
statically scans n8n, Dify, and Flowise template files for embedded secrets,
exfil-shaped flows, and dangerous nodes. No probing, files only.
What it is not
Not a CSPM. It doesn't read your cloud accounts. Not cloud enumeration. It probes the hosts you list, nothing else. Not runtime prompt-injection or agent AppSec. It checks whether services are exposed without auth, not what models do with prompts. It complements those tools; it doesn't replace them.
Single host or CI gate instead? aicheck scan <host>, or the
GitHub Action.
One-off check, no install: the hosted scanner.