Shadowlight
╔═╗╦ ╦╔═╗╔╦╗╔═╗╦ ╦╦ ╦╔═╗╦ ╦╔╦╗
╚═╗╠═╣╠═╣ ║║║ ║║║║║ ║║ ╦╠═╣ ║
╚═╝╩ ╩╩ ╩═╩╝╚═╝╚╩╝╩═╝╩╚═╝╩ ╩ ╩
───────────────────────────────
shadow AI exposure scanner · v1.0.0 · authorized use only
by Arman Manteghi · github.com/Arman-Manteghi
A command-line scanner that finds AI infrastructure on your network that anyone can use without a password.
Ollama, vector databases, model servers, AI web interfaces and MLOps tools are usually installed for a quick test and ship without authentication. Once one of them is reachable from outside the machine, it exposes your models, your embeddings and your GPUs. Shadowlight scans the addresses you give it, recognises 23 services, checks read-only whether each one answers without credentials, and tells you what to fix.
- Pure terminal tool: one
pip install, one command, no dependencies. - Read-only: it never writes, deletes or modifies anything on a target.
- Public internet addresses are refused unless you confirm you are authorised.
- Recognises services by what they answer, not only by their port, so it also finds them on non-default ports.
- Matches the detected version against known vulnerabilities and raises the risk when it is outdated.
Install
Requires Python 3.10 or newer (this release is built for Python 3.10, 3.11, 3.12, 3.13, 3.14).
pip install shadowlight
Then run shadowlight. Upgrade with pip install --upgrade shadowlight, remove it with pip uninstall shadowlight.
To keep it isolated from your other packages, and have the command on your PATH automatically, use pipx instead: pipx install shadowlight. If the command is not found after a plain pip install, run python -m shadowlight.
The same build is also attached to every release here, if you prefer to install straight from GitHub:
pip install https://github.com/Arman-Manteghi/shadowlight/releases/download/v1.0.0/shadowlight-1.0.0-py3-none-any.whl
or download shadowlight-1.0.0-py3-none-any.whl from the Releases page and run pip install shadowlight-1.0.0-py3-none-any.whl.
If you see has no build for Python x.y, your Python is newer or older than the versions this release was built for.
Use
Run it with no arguments and it asks what to scan:
shadowlight
Or give it targets directly:
shadowlight 192.168.1.0/24
shadowlight 10.0.0.5-40 -p ollama,qdrant
shadowlight 10.0.0.0/24 -p llm,vector -o report.html
shadowlight --list
| Option | What it does |
|---|---|
targets |
IP, hostname, CIDR, range (10.0.0.5-40) or a file with one target per line |
-p, --ports |
numbers, ranges, service names or groups: llm, vector, ui, mlops, all |
-o FILE |
save the report as .html, .json, .csv or plain text |
--json |
print JSON instead of the table |
--baseline FILE |
compare with an earlier JSON report and show what is new or fixed |
--fail-on RULE |
exit with status 2 on exposed (default), low, medium, high, critical, new or never |
--rate N |
at most N new connection attempts per second |
--list |
show every supported service |
What it detects
| Service | Group | Default port |
|---|---|---|
| Ollama | Model server | 11434 |
| ChromaDB | Vector database | 8000 |
| Weaviate | Vector database | 8080 |
| Qdrant | Vector database | 6333 |
| Milvus | Vector database | 19530 |
| vLLM | Model server | 8000 |
| llama.cpp server | Model server | 8080 |
| LocalAI | Model server | 8080 |
| LiteLLM Proxy | Model server | 4000 |
| Text Generation Inference | Model server | 8080 |
| Text Embeddings Inference | Model server | 8080 |
| NVIDIA Triton | Model server | 8000 |
| KoboldCpp | Model server | 5001 |
| Open WebUI | AI interface | 8080, 3000 |
| ComfyUI | AI interface | 8188 |
| Stable Diffusion WebUI | AI interface | 7860 |
| Gradio app | AI interface | 7860 |
| Flowise | AI interface | 3000 |
| Langflow | AI interface | 7860 |
| Ray Dashboard | MLOps | 8265 |
| MLflow | MLOps | 5000 |
| TorchServe Management | MLOps | 8081 |
| OpenAI-compatible API | Model server | 1234, 1337, 9997 |
Any other server that speaks the OpenAI API is caught by a generic signature.
In CI and scheduled scans
Exit status is 0 when the rule passes and 2 when it trips, so it can gate a pipeline:
shadowlight 10.0.0.0/24 --json -o today.json --baseline last.json --fail-on new
Responsible use
Only scan systems you own or have written permission to test. Shadowlight only sends read-only requests, but scanning other people's systems can still be illegal. Public addresses are refused unless you pass --authorized.
Verify your download
SHA256SUMS.txt lists the checksum of the wheel. In PowerShell:
Get-FileHash .\shadowlight-1.0.0-py3-none-any.whl -Algorithm SHA256
On Linux or macOS use sha256sum shadowlight-1.0.0-py3-none-any.whl.
Author
Shadowlight is built and maintained by Arman Manteghi.
License
Free to use for authorised security testing, personal or internal business use. Redistribution, modification, reverse engineering and use against systems you are not authorised to test are not permitted. Read LICENSE.txt before using it.
Copyright (c) 2026 Arman Manteghi. All rights reserved.
Metadata
Release files for shadowlight 1.0.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| shadowlight-1.0.0-py3-none-any.whl | Python 3 | none | any | Details |
Release files / shadowlight-1.0.0-py3-none-any.whl
| Download URL | shadowlight-1.0.0-py3-none-any.whl |
|---|---|
| Size | 1.2 MB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
e2e92c2b49a39243ba83a394c73a95b20122bfbecd7140fcc7c543cf6cc25bb0
|
|
BLAKE2b-256 checksum How to use checksums |
f28efb8cd7a44e7c137154dd11387b1a6d074f994cf3b1e8ac669eb19a779faf
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.11.4
|