Metadata-Version: 2.4
Name: agent-harness-aibom
Version: 0.1.15
Summary: AIBOM generator for AI agent harnesses (Hermes, OpenClaw) and their model/skill/MCP/hook surface
Author: Practical DevSecOps
License: MIT
Project-URL: Homepage, https://github.com/Aj7Ay/agent-harness-aibom
Project-URL: Repository, https://github.com/Aj7Ay/agent-harness-aibom
Project-URL: Changelog, https://github.com/Aj7Ay/agent-harness-aibom/releases
Requires-Python: >=3.10
Description-Content-Type: text/markdown
License-File: LICENSE
Requires-Dist: PyYAML>=6.0
Provides-Extra: dev
Requires-Dist: pytest>=8.0; extra == "dev"
Requires-Dist: cyclonedx-python-lib[json-validation]>=8.0; extra == "dev"
Dynamic: license-file

# agent-harness-aibom

[![CI](https://github.com/Aj7Ay/agent-harness-aibom/actions/workflows/ci.yml/badge.svg)](https://github.com/Aj7Ay/agent-harness-aibom/actions/workflows/ci.yml)
[![PyPI](https://img.shields.io/pypi/v/agent-harness-aibom.svg)](https://pypi.org/project/agent-harness-aibom/)
[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](LICENSE)

An AIBOM (AI Bill of Materials) generator for AI agent harnesses —
currently Hermes and [OpenClaw](https://docs.openclaw.ai) — that emits standard CycloneDX 1.6
JSON extended with harness-specific fields (skill fingerprints, MCP server
TLS/auth posture, hook approval state, model provenance). See
[`SPEC.md`](SPEC.md) for the full data model and its rationale.

This is the "ground truth" layer for a broader exercise: scan a real
harness with this tool, scan the same harness with a general-purpose
scanner (e.g. Cisco AI BOM), and diff what each one saw.

## Install

```bash
pip install agent-harness-aibom
```

or, with [uv](https://docs.astral.sh/uv/):

```bash
uv venv && source .venv/bin/activate && uv pip install agent-harness-aibom
# or, to match plain `pip install` above and skip the venv:
uv pip install --system agent-harness-aibom
```

For development, from a checkout:

```bash
uv sync --extra dev       # or: pip install -e ".[dev]"
```

## Usage

```bash
# Auto-detect and scan whatever's installed under $HOME
harness-aibom scan --runtime auto -o aibom.json

# Scan a specific runtime explicitly
harness-aibom scan --runtime hermes -o hermes-aibom.json
harness-aibom scan --runtime openclaw -o openclaw-aibom.json

# Check a document's shape
harness-aibom validate aibom.json

# Compare two scans -- e.g. before/after a suspected skill compromise
harness-aibom diff before.json after.json

# Render a document as a single, offline, static HTML file
harness-aibom report aibom.json -o report.html
```

`scan` runs entirely against the local filesystem and local subprocesses/
HTTP calls (`hermes`/`openclaw` CLIs, Ollama's `/api/tags`). To scan a
remote lab VM, install the package there (or SSH in and run it) — there's
no built-in remote transport yet.

Missing pieces are never fatal: if `hermes` isn't on `PATH`, or Ollama
isn't reachable, the scan still completes and prints a `warning[...]` line
to stderr explaining what it skipped, so students can see exactly what
partial information looks like.

## Example output

[`examples/hermes-aibom.example.json`](examples/hermes-aibom.example.json)
and [`examples/openclaw-aibom.example.json`](examples/openclaw-aibom.example.json)
were generated by running `scan` against the test fixtures in
`tests/fixtures/` (a synthetic `config.yaml`/`openclaw.json`, no live
`hermes`/`openclaw`/`ollama` on this machine) — a realistic example of
graceful degradation when the runtime binary isn't present.
[`examples/hermes-aibom.example.html`](examples/hermes-aibom.example.html)
and [`examples/openclaw-aibom.example.html`](examples/openclaw-aibom.example.html)
are the `report` rendering of those same two documents.

## Project layout

```
src/harness_aibom/
├── model.py          # Component / HarnessDocument -- the in-memory data model
├── cyclonedx.py       # model.py -> CycloneDX 1.6 JSON
├── fingerprint.py      # sha256 helpers
├── validate.py         # structural checks on a harness-aibom document
├── diff.py             # before/after comparison
├── cli.py               # `harness-aibom` entrypoint
└── collectors/
    ├── base.py          # Collector ABC
    ├── ollama.py         # shared: model discovery via Ollama's HTTP API
    ├── mcp.py             # shared: MCP server extraction from a config dict
    ├── secrets.py          # shared: secrets-surface discovery (paths/perms only)
    ├── hermes.py            # Hermes collector
    └── openclaw.py          # OpenClaw collector
```

## CI and publishing

- `.github/workflows/ci.yml` runs the test suite and a CLI smoke test on
  every push and pull request, on Python 3.10, 3.11, and 3.12.
- `.github/workflows/publish.yml` builds and publishes the package to PyPI
  when you publish a GitHub Release. It uses PyPI Trusted Publishing, so no
  password lives in this repo. Trusted publishing is already configured for
  this project on PyPI.

To ship a new version: bump `version` in `pyproject.toml`, commit, then
publish a new GitHub Release with a matching tag (e.g. `v0.1.1`). The
release triggers `publish.yml`, which builds and uploads it automatically.

## Testing

```bash
pytest -q
```

Collector tests run entirely against fixtures under `tests/fixtures/`
(`hermes_home/`, `openclaw_home/`) with injected fake `run`/`fetch`
functions — no real `hermes`/`openclaw`/`ollama` needed to run the suite.

## Roadmap

v0.1 is live on PyPI — the spec plus two working collectors. Natural next
steps, roughly in order:

1. Harden hook parsing against a live Hermes box (see `SPEC.md` §5).
2. Point this at the actual CAASP lab VMs and fix whatever the real output
   shapes get wrong.
3. Scan the same harness with Cisco AI BOM and diff the two documents —
   the gap-analysis exercise this package exists to support.
4. cosign signing/provenance for the emitted AIBOM.
