Metadata-Version: 2.4
Name: abom-cli
Version: 0.1.14
Summary: ABOM — the Agent Bill of Materials. Scan, sign, and verify what your AI agents are made of.
Project-URL: Homepage, https://abom.ai
Project-URL: Repository, https://github.com/josephassiga/abom-dev
Project-URL: Specification, https://github.com/josephassiga/abom-dev/tree/main/spec
Author: ABOM Contributors
License-Expression: Apache-2.0
Keywords: agent,ai,ai-security,cyclonedx,llm,ml-bom,provenance,sbom,supply-chain
Classifier: Development Status :: 3 - Alpha
Classifier: Intended Audience :: Developers
Classifier: License :: OSI Approved :: Apache Software License
Classifier: Programming Language :: Python :: 3 :: Only
Classifier: Topic :: Security
Classifier: Topic :: Software Development :: Quality Assurance
Requires-Python: >=3.10
Requires-Dist: cryptography>=42.0
Requires-Dist: tomli>=2.0; python_version < '3.11'
Requires-Dist: typer>=0.12
Provides-Extra: dev
Requires-Dist: build>=1.2; extra == 'dev'
Requires-Dist: click<8.2; extra == 'dev'
Requires-Dist: httpx>=0.27; extra == 'dev'
Requires-Dist: jsonschema>=4.21; extra == 'dev'
Requires-Dist: pytest-cov>=5.0; extra == 'dev'
Requires-Dist: pytest>=8.3; extra == 'dev'
Requires-Dist: ruff>=0.7; extra == 'dev'
Requires-Dist: twine>=5.0; extra == 'dev'
Provides-Extra: mcp
Requires-Dist: httpx>=0.27; extra == 'mcp'
Description-Content-Type: text/markdown

# abom-cli

The reference implementation of [ABOM](../spec/) — the Agent Bill of Materials.
Scan a repo, emit a **signed** Composition Manifest, **verify** it, and **enforce**
it at the tool boundary — inline or through the MCP broker.

```bash
pip install abom-cli        # (until published: pip install -e .)
abom scan .                 # → abom.json (signed with ed25519)
abom verify abom.json       # check signature
abom verify abom.json --policy policy.json   # + enforce a policy (exit 1 on violations)
abom gate abom.json --tool wire_transfer     # ALLOW/DENY one action (deny-by-default)
abom broker abom.json --upstream https://mcp.internal/rpc  # mediate an agent's tool calls
```

## Commands

| Command | What it does |
|---|---|
| `abom scan [PATH]` | Detect agent components (models, prompts, tools, MCP servers, frameworks, vector stores, guardrails) and emit a signed Composition Manifest. `-o -` writes to stdout. |
| `abom verify [FILE]` | Verify the ed25519 signature; with `--policy`, enforce model allowlist / residency / egress / approval rules. Non-zero exit on findings (CI-friendly). `--trusted-key` pins the authorized signer. |
| `abom gate FILE --tool T` | Decide ALLOW/DENY for one action against the signed manifest, deny-by-default, notarized. `--trusted-key` refuses a manifest it can't authenticate. Exit 1 = DENY. |
| `abom broker FILE --upstream URL` | Run the MCP broker: mediate every `tools/call` against the signed manifest before forwarding to an upstream MCP server. Denied calls return a notarized JSON-RPC error and never reach upstream. `--log` for a durable decision log. |
| `abom keygen` | Show (or create) the local ed25519 signing key (`~/.abom/signing_key.pem`, override with `ABOM_KEY`). |
| `abom version` | Print the tool and spec versions. |

All commands accept **`-v`** (info) / **`-vv`** (debug) / **`-q`** (errors only) / **`--json-logs`** (NDJSON for CI) — logs go to stderr, so the ABOM on stdout stays clean.

### Example

```
$ abom scan .
  ABOM · my-agent @ 1.2.0
  models                  3  gpt-4o-mini, claude-3-5-sonnet, OpenAI (SDK)
  frameworks              2  LangChain, LangGraph
  MCP servers             2  filesystem, github
  tools                   1  lookup_customer
  prompts                 1  prompts/system.txt
  signed: ed25519 · key 5846eabc738b3542
  → wrote abom.json
```

## How detection works

`abom scan` is a static scanner (pure stdlib + `cryptography`):
- **Dependencies** (`requirements*.txt`, `pyproject.toml`, `package.json`) → frameworks, model SDKs, vector stores, guardrails.
- **Source** → concrete model names (`gpt-4o`, `claude-*`, …) and `@tool`-decorated functions.
- **Prompt files** (`*.prompt`, `prompts/*.txt|md`) → hashed.
- **MCP configs** (`mcp.json`, `claude_desktop_config.json`, …) → MCP servers.

Each component records `detected_from` so the manifest is auditable. The output
validates against [`spec/abom-0.1.schema.json`](../spec/abom-0.1.schema.json).

## Signing

`abom scan` signs with **ed25519** (`cryptography`). The key lives at
`~/.abom/signing_key.pem` (override with `ABOM_KEY`); the public key + a short
`key_id` are embedded so `abom verify` is self-contained. Pin the trusted signer
with `--trusted-key <key_id>` on `verify` / `gate` / `broker`: a manifest
re-signed by any other key is then refused, so "signed" authenticates *who* — not
just integrity. `LocalSigner` is dev/CI; a `KMSSigner` seam keeps the private key
in a KMS/HSM for production.

## Dev

```bash
make install          # pip install -e ".[dev]"
make test             # pytest (audit chain, scanner, signing)
make scan && make verify
make build            # wheel + sdist + twine check
python demo/demo.py   # generate → verify → tamper-evidence walkthrough
```

## The MCP broker

`abom broker` moves enforcement **out of the agent's process**. The agent points
its MCP client at the broker instead of the MCP server; the broker checks every
`tools/call` against the signed manifest and only forwards allowed ones. A denied
call is answered with a notarized JSON-RPC error and never reaches the upstream
server — deny-by-default becomes *structural* for brokered tools rather than
cooperative. It does **not** stop out-of-band calls (raw HTTP / subprocess) the
agent makes without transiting the broker; pair it with network egress
containment for that.

The optional `[mcp]` extra (`pip install 'abom-cli[mcp]'`) pulls in `httpx` for
the broker's upstream transport and for `abom scan --mcp`.
