What it detects
Offline AI bill of materials for a code repository. It answers "what AI is in this repo?" for reviews, audits, vendor questionnaires and AI-governance inventories (for example, the AI asset inventory that ISO/IEC 42001 and the NIST AI RMF expect), and it can fail CI when a new, undeclared AI component appears ("shadow AI").
Single Python file, standard library only, no network calls. It reads files; it never imports, executes or loads anything it finds.
Rules
| Code | Severity | Meaning |
|---|---|---|
| AB01 | high | Model file in a pickle-based format (.pkl, .pt, .ckpt, .joblib): loading it can run arbitrary code |
| AB02 | low | AI dependency not pinned to an exact version |
| AB03 | low | Floating model alias (gpt-4o, *-latest, *-preview, *-exp): behaviour can change under you |
| AB04 | medium | Plaintext http:// to a remote AI provider |
| AB05 | medium | AI SDK imported in code but not declared in any dependency manifest |
Usage
python3 aibom.py path/to/repo # human-readable inventory + notes
python3 aibom.py . --json -o aibom.json # machine-readable; also a baseline
python3 aibom.py . --cyclonedx --hash -o bom.cdx.json # CycloneDX 1.6 (ML-BOM components, services)
python3 aibom.py . --baseline aibom.json --fail-on new # CI: fail when new AI components appear
python3 aibom.py . --fail-on high # CI: fail on pickle model filesAfter pip install of the kit, the same options work as agentsec aibom …. Every tool also accepts --help and almost every tool accepts --json.
Example output
examples/sample_app is a fake multi-language app (Python, TypeScript, a notebook, YAML, an MCP config, placeholder model files) with fake values only.
$ python3 aibom.py examples/sample_app --baseline examples/baseline.json
AI-BOM for .../examples/sample_app
AI SDKs / frameworks (11)
- @ai-sdk/openai (Vercel AI SDK provider, 1.0.5, declared)
web/chat.ts:2, web/package.json:6
...
- litellm (LiteLLM, import only) [NEW]
app.py:6
...
MCP servers (2)
- docs-search (remote, https://mcp.docs.example/sse) [NEW]
- github (stdio, npx -y @modelcontextprotocol/server-github)
Governance notes (11)
HIGH AB01 models/intent_classifier.pkl model file uses a pickle-based format (pickle); ...
MEDIUM AB04 app.py:14 plaintext http:// endpoint for OpenAI (api.openai.com)
MEDIUM AB05 app.py:6 AI SDK 'litellm' is imported but not declared in any dependency manifest
...
2 component(s) new since baseline: mcp-server:docs-search, sdk:litellm
SARIF and CI
agentsec aibom path/to/input --json > aibom.json
# aibom does not yet emit SARIF; use --json and keep --fail-on for CI.
# GitHub Actions (composite action ships with the repo)
- uses: dunkleschitz/agentsec@v0
with:
tools: aibom
paths: path/to/input
fail-on: high
--sarif is not available on this tool yet (resultguard and toolpoison are reserved as good first issues). Use --json and a --fail-on exit gate instead.
OWASP mapping
Heuristic mapping of what this tool helps a reviewer look for. Not an official OWASP endorsement, and not complete coverage of any item. Sources: OWASP Top 10 for LLM Applications 2025 and OWASP Top 10 for Agentic Applications 2026.
- LLM03 Supply Chain — OWASP LLM Top 10 (2025)
- ASI04 Agentic Supply Chain Vulnerabilities — OWASP Agentic Top 10 (2026)
Known limits
Heuristic scanner, not a security boundary. A clean result does not mean something is safe. All example secrets in this repository are fake.
Full source, tests, and fixtures: tools/aibom/ in the repository. Install the kit with pip install git+https://github.com/dunkleschitz/agentsec.git.