abom-cli 0.1.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (38) hide show
  1. abom_cli-0.1.0/.env.example +26 -0
  2. abom_cli-0.1.0/.gitignore +14 -0
  3. abom_cli-0.1.0/Dockerfile +15 -0
  4. abom_cli-0.1.0/MVP_SPEC.md +157 -0
  5. abom_cli-0.1.0/Makefile +32 -0
  6. abom_cli-0.1.0/PKG-INFO +108 -0
  7. abom_cli-0.1.0/README.md +69 -0
  8. abom_cli-0.1.0/charts/abom/Chart.yaml +9 -0
  9. abom_cli-0.1.0/charts/abom/values.yaml +36 -0
  10. abom_cli-0.1.0/demo/README.md +69 -0
  11. abom_cli-0.1.0/demo/demo.py +197 -0
  12. abom_cli-0.1.0/demo/sample_repo/tests.py +40 -0
  13. abom_cli-0.1.0/demo/sample_repo/validator.py +5 -0
  14. abom_cli-0.1.0/docker-compose.yml +53 -0
  15. abom_cli-0.1.0/pyproject.toml +61 -0
  16. abom_cli-0.1.0/scripts/init_db.py +18 -0
  17. abom_cli-0.1.0/src/abom/__init__.py +3 -0
  18. abom_cli-0.1.0/src/abom/agents.py +58 -0
  19. abom_cli-0.1.0/src/abom/api.py +177 -0
  20. abom_cli-0.1.0/src/abom/audit.py +122 -0
  21. abom_cli-0.1.0/src/abom/bom.py +147 -0
  22. abom_cli-0.1.0/src/abom/cli.py +130 -0
  23. abom_cli-0.1.0/src/abom/config.py +37 -0
  24. abom_cli-0.1.0/src/abom/db.py +127 -0
  25. abom_cli-0.1.0/src/abom/execution.py +73 -0
  26. abom_cli-0.1.0/src/abom/models_router.py +84 -0
  27. abom_cli-0.1.0/src/abom/orchestration.py +237 -0
  28. abom_cli-0.1.0/src/abom/policy.py +46 -0
  29. abom_cli-0.1.0/src/abom/scan.py +207 -0
  30. abom_cli-0.1.0/src/abom/schemas.py +79 -0
  31. abom_cli-0.1.0/src/abom/sign.py +91 -0
  32. abom_cli-0.1.0/tests/fixtures/sample-agent/agent.py +16 -0
  33. abom_cli-0.1.0/tests/fixtures/sample-agent/mcp.json +6 -0
  34. abom_cli-0.1.0/tests/fixtures/sample-agent/prompts/system.txt +2 -0
  35. abom_cli-0.1.0/tests/fixtures/sample-agent/requirements.txt +7 -0
  36. abom_cli-0.1.0/tests/test_audit_chain.py +73 -0
  37. abom_cli-0.1.0/tests/test_scan.py +67 -0
  38. abom_cli-0.1.0/tests/test_sign.py +32 -0
@@ -0,0 +1,26 @@
1
+ # Copy to .env and adjust. All keys are prefixed ABOM_ (see src/abom/config.py).
2
+
3
+ ABOM_DATABASE_URL=postgresql+asyncpg://abom:abom@localhost:5432/abom
4
+ ABOM_TEMPORAL_HOST=localhost:7233
5
+ ABOM_TEMPORAL_NAMESPACE=default
6
+ ABOM_TASK_QUEUE=abom-cli
7
+
8
+ ABOM_S3_ENDPOINT=http://localhost:9000
9
+ ABOM_S3_ACCESS_KEY=minioadmin
10
+ ABOM_S3_SECRET_KEY=minioadmin
11
+ ABOM_S3_BUCKET=abom-artifacts
12
+
13
+ # Local, OpenAI-compatible model server (vLLM). Set MODEL_USE_MOCK=false to use it.
14
+ ABOM_MODEL_BASE_URL=http://localhost:8001/v1
15
+ ABOM_MODEL_NAME=local/qwen2.5-coder
16
+ ABOM_MODEL_USE_MOCK=true
17
+
18
+ # Auth: leave JWKS empty for dev mode (static token grants all roles).
19
+ ABOM_OIDC_JWKS_URL=
20
+ ABOM_OIDC_AUDIENCE=abom
21
+ ABOM_DEV_STATIC_TOKEN=dev-token
22
+
23
+ # Execution
24
+ ABOM_SANDBOX_IMAGE=python:3.12-slim
25
+ ABOM_WORKSPACE_ROOT=/tmp/abom-workspaces
26
+ ABOM_GATE_TIMEOUT_SECONDS=600
@@ -0,0 +1,14 @@
1
+ __pycache__/
2
+ *.pyc
3
+ .env
4
+ cli/demo/out/
5
+ .DS_Store
6
+
7
+ # build artifacts
8
+ dist/
9
+ build/
10
+ *.egg-info/
11
+ .abom/
12
+
13
+ # abom scan output
14
+ abom.json
@@ -0,0 +1,15 @@
1
+ FROM python:3.12-slim
2
+
3
+ WORKDIR /app
4
+ ENV PYTHONUNBUFFERED=1 PYTHONPATH=/app/src
5
+
6
+ COPY pyproject.toml ./
7
+ RUN pip install --no-cache-dir -e "." || pip install --no-cache-dir \
8
+ fastapi "uvicorn[standard]" pydantic pydantic-settings "sqlalchemy[asyncio]" \
9
+ asyncpg alembic temporalio httpx boto3 "python-jose[cryptography]" typer
10
+
11
+ COPY src ./src
12
+ COPY scripts ./scripts
13
+
14
+ EXPOSE 8000
15
+ CMD ["uvicorn", "abom.api:app", "--host", "0.0.0.0", "--port", "8000"]
@@ -0,0 +1,157 @@
1
+ # ABOM — Step-1 MVP Specification
2
+
3
+ *Build target for the lighthouse design partner. Detailed enough to scaffold from. Companion to the project docs (kept private) §7 and the project docs (kept private).*
4
+
5
+ ---
6
+
7
+ ## 1. Goal
8
+
9
+ For **one real agent run, entirely inside the customer's boundary**, produce a
10
+ signed **Agent Bill of Materials** and verify it:
11
+
12
+ 1. **Generate** — a signed **Composition Manifest** (what the agent is made of) and
13
+ a hash-chained **Action Provenance** chain (what it did).
14
+ 2. **Verify** — run **abom-verify** against policy and catch a real violation a raw
15
+ log would let ship silently (unapproved/shadow model, confidential-data egress,
16
+ missing approval, composition drift).
17
+ 3. **Prove** — show the provenance is tamper-evident: scrubbing a record breaks the
18
+ chain at the exact `seq`.
19
+
20
+ Guiding constraint: *nothing leaves the boundary*. The ABOM format extends
21
+ **CycloneDX ML-BOM**.
22
+
23
+ ---
24
+
25
+ ## 2. The workload
26
+
27
+ An agent run (the MVP exercises a developer/document agent) whose actions —
28
+ model calls, tool/egress calls, data access, gate results, approvals — are
29
+ captured as Action Provenance and bound to a signed Composition Manifest.
30
+
31
+ ### Out of scope for MVP
32
+ Full runtime auto-capture (eBPF/framework taps) · real ed25519/cosign signing
33
+ (MVP uses an HMAC stand-in) · the persistent Notary registry · OPA/Rego (MVP uses
34
+ a JSON policy) · web console · multi-tenancy · SIEM export · air-gap bundle.
35
+
36
+ ---
37
+
38
+ ## 3. The ABOM artifacts (the core)
39
+
40
+ **Composition Manifest** — signed; `composition_sha256` is the join key.
41
+ ```json
42
+ { "abom":"0.1","extends":"CycloneDX ML-BOM","type":"CompositionManifest",
43
+ "agent":{"name":"…","version":"…","risk_class":"high (Annex III)"},
44
+ "components":[ {"type":"model","name":"…","weights_sha256":"…","egress":false},
45
+ {"type":"tool","name":"http_fetch","allowed_endpoints":["…"]},
46
+ {"type":"prompt","sha256":"…"},
47
+ {"type":"dataSource","classification":"confidential"},
48
+ {"type":"policy","engine":"OPA","sha256":"…"} ],
49
+ "controls":{"egress":"deny-by-default","hitl":"required-for-consequential","residency":"EU"},
50
+ "composition_sha256":"…","signature":{"alg":"…","value":"…"} }
51
+ ```
52
+
53
+ **Action Provenance Record** — hash-chained (reuses the audit chain).
54
+ ```json
55
+ { "type":"ActionProvenance","run_id":"agent@ver","seq":1,
56
+ "data":{ "composition_sha256":"…","decision":"…",
57
+ "inputs":[…],"model_calls":[{"model":"…","tokens":…}],
58
+ "tools_invoked":[{"name":"…","endpoint":"…"}],
59
+ "data_touched":[{"classification":"confidential","egress":false}],
60
+ "policy_decisions":[{"rule":"approval_required","result":"required"}],
61
+ "approval":{"by":"…","decision":"approved"} },
62
+ "prev_hash":"…","hash":"…" }
63
+ ```
64
+
65
+ Implemented in [src/abom/bom.py](src/abom/bom.py) (`build_composition`,
66
+ `append_action`, `sign`/`verify_signature`) over the tamper-evident chain in
67
+ [src/abom/audit.py](src/abom/audit.py).
68
+
69
+ ---
70
+
71
+ ## 4. abom-verify — policy checks
72
+
73
+ `bom.verify_abom(composition, chain, policy)` → `{ok, findings[], actions}`. Rules:
74
+
75
+ | Rule | Catches |
76
+ |---|---|
77
+ | `signature` | composition signature invalid |
78
+ | `chain_integrity` | provenance mutated / scrubbed / reordered |
79
+ | `composition_match` | an action references a different composition |
80
+ | `model_allowlist` | a model not on the approved list was used |
81
+ | `composition_drift` | a runtime model not in the signed manifest (shadow model) |
82
+ | `residency` | confidential/restricted data egressed |
83
+ | `egress_allowlist` | egress to an unapproved endpoint |
84
+ | `approval_coverage` | a consequential action without approval |
85
+
86
+ Phase-2 swaps the JSON policy for OPA/Rego behind the same interface.
87
+
88
+ ---
89
+
90
+ ## 5. Tech stack & substrate
91
+
92
+ Where ABOMs are captured: the agent runs through the control-plane substrate so
93
+ every action is observable. (Capture completeness is the product's hardest
94
+ property — see the project docs (kept private) §3.2.)
95
+
96
+ | Concern | Choice |
97
+ |---|---|
98
+ | Language | Python 3.12 |
99
+ | API | FastAPI + Pydantic v2 |
100
+ | Orchestration | Temporal (`temporalio`) |
101
+ | DB / ORM | PostgreSQL 16 + SQLAlchemy 2.0 (async) |
102
+ | Object store | MinIO (S3) |
103
+ | Model serving | vLLM (OpenAI-compatible); `MockModelClient` for laptops |
104
+ | Policy | JSON (MVP) → OPA/Rego |
105
+ | Signing | HMAC stand-in (MVP) → ed25519 / cosign |
106
+ | Deploy | Helm stub (`charts/abom`), any Kubernetes |
107
+
108
+ ---
109
+
110
+ ## 6. API surface (MVP)
111
+
112
+ Bearer token; `roles` claim drives RBAC (`developer`, `operator`, `auditor`).
113
+
114
+ | Method | Path | Role | Purpose |
115
+ |---|---|---|---|
116
+ | GET | `/healthz` `/readyz` | — | liveness / readiness |
117
+ | POST | `/v1/runs` | developer | start an instrumented agent run |
118
+ | GET | `/v1/runs/{id}/abom` | auditor | the run's Composition Manifest + Action Provenance |
119
+ | GET | `/v1/abom/verify?run_id=` | auditor | run abom-verify → findings |
120
+ | GET | `/v1/abom/chain/verify?run_id=` | auditor | recompute the provenance hash chain |
121
+ | POST | `/v1/runs/{id}/approve` | operator | approve a consequential action |
122
+
123
+ ---
124
+
125
+ ## 7. Definition of done
126
+
127
+ 1. A run completes against a **local** model only — zero external egress, verifiable.
128
+ 2. The run emits a **signed Composition Manifest** and a **hash-chained Action Provenance** chain.
129
+ 3. **abom-verify** returns **clean** for a compliant run and **≥3 findings** for a violating run (shadow model + confidential egress + missing approval).
130
+ 4. Tampering with any provenance record makes `verify_abom` report a `chain_integrity` finding at the broken `seq`.
131
+ 5. RBAC enforced: `auditor` cannot start runs; `developer` cannot approve.
132
+ 6. `make demo` runs the generate → verify → tamper scenario with no infrastructure.
133
+
134
+ The demo ([demo/demo.py](demo/demo.py)) already satisfies criteria 2–4 and 6.
135
+
136
+ ---
137
+
138
+ ## 8. Milestones (≈6 weeks, one engineer)
139
+
140
+ | Wk | Deliverable |
141
+ |---|---|
142
+ | 1 | ABOM v0 schema + `bom.py` (composition, provenance, verify) + tamper test ✓ |
143
+ | 2 | Control API: runs, `/v1/runs/{id}/abom`, `/v1/abom/verify`, RBAC |
144
+ | 3 | Capture hooks in the model router + tool gateway (real model/tool/data events) |
145
+ | 4 | Real ed25519/cosign signing; persist to a minimal Notary (append-only table) |
146
+ | 5 | CycloneDX + SIEM export; second decidable verify rule hardened |
147
+ | 6 | docker-compose end-to-end; Helm stub; design-partner demo |
148
+
149
+ ---
150
+
151
+ ## 9. Risk specific to the MVP
152
+
153
+ **Capture completeness.** A provenance chain is only trustworthy if *every* action
154
+ is recorded. The MVP supplies actions explicitly; the product earns completeness
155
+ by generating from inside the runtime (control-plane taps + framework hooks + an
156
+ eBPF egress backstop). Keep the `abom-gen` capture interface stable so those
157
+ sources can be added without changing the artifacts.
@@ -0,0 +1,32 @@
1
+ .PHONY: install test scan verify demo build up down migrate lint
2
+
3
+ install:
4
+ pip install -e ".[dev]"
5
+
6
+ test:
7
+ PYTHONPATH=src pytest -q
8
+
9
+ scan:
10
+ PYTHONPATH=src python -m abom.cli scan . -o abom.json
11
+
12
+ verify:
13
+ PYTHONPATH=src python -m abom.cli verify abom.json
14
+
15
+ build:
16
+ rm -rf dist && python -m build && twine check dist/*
17
+
18
+ up:
19
+ docker compose up -d --build
20
+
21
+ down:
22
+ docker compose down -v
23
+
24
+ migrate:
25
+ PYTHONPATH=src python scripts/init_db.py
26
+ @echo "(MVP) tables created via metadata. For prod, switch to Alembic migrations."
27
+
28
+ demo:
29
+ python3 demo/demo.py
30
+
31
+ lint:
32
+ ruff check src tests
@@ -0,0 +1,108 @@
1
+ Metadata-Version: 2.4
2
+ Name: abom-cli
3
+ Version: 0.1.0
4
+ Summary: ABOM — the Agent Bill of Materials. Scan, sign, and verify what your AI agents are made of.
5
+ Project-URL: Homepage, https://abom.ai
6
+ Project-URL: Repository, https://github.com/josephassiga/abom
7
+ Project-URL: Specification, https://github.com/josephassiga/abom/tree/main/spec
8
+ Author: ABOM Contributors
9
+ License-Expression: Apache-2.0
10
+ Keywords: agent,ai,ai-security,cyclonedx,llm,ml-bom,provenance,sbom,supply-chain
11
+ Classifier: Development Status :: 3 - Alpha
12
+ Classifier: Intended Audience :: Developers
13
+ Classifier: License :: OSI Approved :: Apache Software License
14
+ Classifier: Programming Language :: Python :: 3 :: Only
15
+ Classifier: Topic :: Security
16
+ Classifier: Topic :: Software Development :: Quality Assurance
17
+ Requires-Python: >=3.11
18
+ Requires-Dist: cryptography>=42.0
19
+ Requires-Dist: typer>=0.12
20
+ Provides-Extra: dev
21
+ Requires-Dist: build>=1.2; extra == 'dev'
22
+ Requires-Dist: jsonschema>=4.21; extra == 'dev'
23
+ Requires-Dist: pytest>=8.3; extra == 'dev'
24
+ Requires-Dist: ruff>=0.7; extra == 'dev'
25
+ Requires-Dist: twine>=5.0; extra == 'dev'
26
+ Provides-Extra: server
27
+ Requires-Dist: alembic>=1.13; extra == 'server'
28
+ Requires-Dist: asyncpg>=0.30; extra == 'server'
29
+ Requires-Dist: boto3>=1.35; extra == 'server'
30
+ Requires-Dist: fastapi>=0.115; extra == 'server'
31
+ Requires-Dist: httpx>=0.27; extra == 'server'
32
+ Requires-Dist: pydantic-settings>=2.6; extra == 'server'
33
+ Requires-Dist: pydantic>=2.9; extra == 'server'
34
+ Requires-Dist: python-jose[cryptography]>=3.3; extra == 'server'
35
+ Requires-Dist: sqlalchemy[asyncio]>=2.0; extra == 'server'
36
+ Requires-Dist: temporalio>=1.8; extra == 'server'
37
+ Requires-Dist: uvicorn[standard]>=0.32; extra == 'server'
38
+ Description-Content-Type: text/markdown
39
+
40
+ # abom-cli
41
+
42
+ The reference implementation of [ABOM](../spec/) — the Agent Bill of Materials.
43
+ Scan a repo, emit a **signed** Composition Manifest, and **verify** it.
44
+
45
+ ```bash
46
+ pip install abom-cli # (until published: pip install -e .)
47
+ abom scan . # → abom.json (signed with ed25519)
48
+ abom verify abom.json # check signature
49
+ abom verify abom.json --policy policy.json # + enforce a policy (exit 1 on violations)
50
+ ```
51
+
52
+ ## Commands
53
+
54
+ | Command | What it does |
55
+ |---|---|
56
+ | `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. |
57
+ | `abom verify [FILE]` | Verify the ed25519 signature; with `--policy`, enforce model allowlist / residency / egress / approval rules. Non-zero exit on findings (CI-friendly). |
58
+ | `abom keygen` | Show (or create) the local ed25519 signing key (`~/.abom/signing_key.pem`, override with `ABOM_KEY`). |
59
+ | `abom version` | Print the tool and spec versions. |
60
+
61
+ ### Example
62
+
63
+ ```
64
+ $ abom scan .
65
+ ABOM · my-agent @ 1.2.0
66
+ models 3 gpt-4o-mini, claude-3-5-sonnet, OpenAI (SDK)
67
+ frameworks 2 LangChain, LangGraph
68
+ MCP servers 2 filesystem, github
69
+ tools 1 lookup_customer
70
+ prompts 1 prompts/system.txt
71
+ signed: ed25519 · key 5846eabc738b3542
72
+ → wrote abom.json
73
+ ```
74
+
75
+ ## How detection works
76
+
77
+ `abom scan` is a static scanner (pure stdlib + `cryptography`):
78
+ - **Dependencies** (`requirements*.txt`, `pyproject.toml`, `package.json`) → frameworks, model SDKs, vector stores, guardrails.
79
+ - **Source** → concrete model names (`gpt-4o`, `claude-*`, …) and `@tool`-decorated functions.
80
+ - **Prompt files** (`*.prompt`, `prompts/*.txt|md`) → hashed.
81
+ - **MCP configs** (`mcp.json`, `claude_desktop_config.json`, …) → MCP servers.
82
+
83
+ Each component records `detected_from` so the manifest is auditable. The output
84
+ validates against [`spec/abom-0.1.schema.json`](../spec/abom-0.1.schema.json).
85
+
86
+ ## Signing
87
+
88
+ `abom scan` signs with **ed25519** (`cryptography`). The key lives at
89
+ `~/.abom/signing_key.pem` (override with `ABOM_KEY`); the public key + a short
90
+ `key_id` are embedded so `abom verify` is self-contained. A Notary / key registry
91
+ pins trusted key ids in production.
92
+
93
+ ## Dev
94
+
95
+ ```bash
96
+ make install # pip install -e ".[dev]"
97
+ make test # pytest (audit chain, scanner, signing)
98
+ make scan && make verify
99
+ make build # wheel + sdist + twine check
100
+ python demo/demo.py # generate → verify → tamper-evidence walkthrough
101
+ ```
102
+
103
+ ## What else is in this package
104
+
105
+ `src/abom/` also contains a **prototype control-plane** (`api.py`, `db.py`,
106
+ `orchestration.py`, the Notary) behind the optional `[server]` extra — the
107
+ beginnings of the commercial layer. It is **not** required for `scan`/`verify`
108
+ and is not part of the v0.1 spec. See [MVP_SPEC.md](MVP_SPEC.md).
@@ -0,0 +1,69 @@
1
+ # abom-cli
2
+
3
+ The reference implementation of [ABOM](../spec/) — the Agent Bill of Materials.
4
+ Scan a repo, emit a **signed** Composition Manifest, and **verify** it.
5
+
6
+ ```bash
7
+ pip install abom-cli # (until published: pip install -e .)
8
+ abom scan . # → abom.json (signed with ed25519)
9
+ abom verify abom.json # check signature
10
+ abom verify abom.json --policy policy.json # + enforce a policy (exit 1 on violations)
11
+ ```
12
+
13
+ ## Commands
14
+
15
+ | Command | What it does |
16
+ |---|---|
17
+ | `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. |
18
+ | `abom verify [FILE]` | Verify the ed25519 signature; with `--policy`, enforce model allowlist / residency / egress / approval rules. Non-zero exit on findings (CI-friendly). |
19
+ | `abom keygen` | Show (or create) the local ed25519 signing key (`~/.abom/signing_key.pem`, override with `ABOM_KEY`). |
20
+ | `abom version` | Print the tool and spec versions. |
21
+
22
+ ### Example
23
+
24
+ ```
25
+ $ abom scan .
26
+ ABOM · my-agent @ 1.2.0
27
+ models 3 gpt-4o-mini, claude-3-5-sonnet, OpenAI (SDK)
28
+ frameworks 2 LangChain, LangGraph
29
+ MCP servers 2 filesystem, github
30
+ tools 1 lookup_customer
31
+ prompts 1 prompts/system.txt
32
+ signed: ed25519 · key 5846eabc738b3542
33
+ → wrote abom.json
34
+ ```
35
+
36
+ ## How detection works
37
+
38
+ `abom scan` is a static scanner (pure stdlib + `cryptography`):
39
+ - **Dependencies** (`requirements*.txt`, `pyproject.toml`, `package.json`) → frameworks, model SDKs, vector stores, guardrails.
40
+ - **Source** → concrete model names (`gpt-4o`, `claude-*`, …) and `@tool`-decorated functions.
41
+ - **Prompt files** (`*.prompt`, `prompts/*.txt|md`) → hashed.
42
+ - **MCP configs** (`mcp.json`, `claude_desktop_config.json`, …) → MCP servers.
43
+
44
+ Each component records `detected_from` so the manifest is auditable. The output
45
+ validates against [`spec/abom-0.1.schema.json`](../spec/abom-0.1.schema.json).
46
+
47
+ ## Signing
48
+
49
+ `abom scan` signs with **ed25519** (`cryptography`). The key lives at
50
+ `~/.abom/signing_key.pem` (override with `ABOM_KEY`); the public key + a short
51
+ `key_id` are embedded so `abom verify` is self-contained. A Notary / key registry
52
+ pins trusted key ids in production.
53
+
54
+ ## Dev
55
+
56
+ ```bash
57
+ make install # pip install -e ".[dev]"
58
+ make test # pytest (audit chain, scanner, signing)
59
+ make scan && make verify
60
+ make build # wheel + sdist + twine check
61
+ python demo/demo.py # generate → verify → tamper-evidence walkthrough
62
+ ```
63
+
64
+ ## What else is in this package
65
+
66
+ `src/abom/` also contains a **prototype control-plane** (`api.py`, `db.py`,
67
+ `orchestration.py`, the Notary) behind the optional `[server]` extra — the
68
+ beginnings of the commercial layer. It is **not** required for `scan`/`verify`
69
+ and is not part of the v0.1 spec. See [MVP_SPEC.md](MVP_SPEC.md).
@@ -0,0 +1,9 @@
1
+ apiVersion: v2
2
+ name: abom
3
+ description: ABOM — production control plane for agentic AI (MVP Helm stub)
4
+ type: application
5
+ version: 0.1.0
6
+ appVersion: "0.1.0"
7
+ # MVP stub. Real chart adds: Operator CRDs, Temporal subchart, vLLM/KServe
8
+ # serving, NetworkPolicies (zero egress), Vault integration, OTel collector,
9
+ # and an offline/air-gap values overlay.
@@ -0,0 +1,36 @@
1
+ # MVP stub values. The production chart enforces sovereignty defaults
2
+ # (egressPolicy: deny-all, airgap mode, signed images only).
3
+
4
+ image:
5
+ repository: ghcr.io/abom/abom
6
+ tag: "0.1.0"
7
+ pullPolicy: IfNotPresent
8
+
9
+ api:
10
+ replicas: 2
11
+ port: 8000
12
+
13
+ worker:
14
+ replicas: 2
15
+
16
+ postgres:
17
+ # In prod, use CloudNativePG / customer-managed Postgres.
18
+ url: "postgresql+asyncpg://abom:abom@abom-postgres:5432/abom"
19
+
20
+ temporal:
21
+ host: "abom-temporal:7233"
22
+ namespace: default
23
+
24
+ modelServing:
25
+ # vLLM on customer GPUs (KServe in prod).
26
+ baseUrl: "http://abom-vllm:8000/v1"
27
+ model: "local/qwen2.5-coder"
28
+
29
+ sovereignty:
30
+ airgap: false # true => no managed control channel, offline updates only
31
+ egressPolicy: deny-all # NetworkPolicy posture; egress only via gated gateway
32
+ requireSignedImages: true
33
+
34
+ audit:
35
+ retentionDays: 3650
36
+ wormCopy: false # Phase-2: WORM object copy + periodic anchoring
@@ -0,0 +1,69 @@
1
+ # ABOM demo — generate · verify · prove tamper-evidence
2
+
3
+ This is the demonstration that matters for ABOM: it generates an **Agent Bill of
4
+ Materials** for an agent run and shows **abom-verify** catching real policy
5
+ violations a raw log would let ship silently — then proves the record can't be
6
+ quietly scrubbed.
7
+
8
+ ## Run it
9
+
10
+ ```bash
11
+ cd cli
12
+ python3 demo/demo.py # or: make demo
13
+ ```
14
+
15
+ No infrastructure required — no Temporal, Postgres, GPU. The model is a
16
+ deterministic mock; the **test gate is a real subprocess**, and the **signing,
17
+ hash-chaining, and policy verification are real** ([../src/abom/bom.py](../src/abom/bom.py),
18
+ [../src/abom/audit.py](../src/abom/audit.py)).
19
+
20
+ ## What it does
21
+
22
+ It emits one signed **Composition Manifest** (what the agent is made of) and runs
23
+ an agent two ways, each producing a hash-chained **Action Provenance** chain
24
+ (what the agent did), then runs **abom-verify**:
25
+
26
+ | Run | What happens | abom-verify |
27
+ |---|---|---|
28
+ | **Compliant** | approved model, no bad egress, consequential action approved | **CLEAN** — 0 findings |
29
+ | **Violating** | shadow (unapproved) model, confidential data egressed to an unapproved endpoint, consequential action with no approval | **BLOCKED** — 5 findings |
30
+
31
+ The five findings on the violating run: `model_allowlist`, `composition_drift`,
32
+ `approval_coverage`, `residency`, `egress_allowlist`.
33
+
34
+ Then it tampers — edits the provenance record to **erase the egress** — and shows
35
+ the hash chain breaks (`chain_integrity` finding), so the evidence can't be
36
+ silently scrubbed.
37
+
38
+ ## Expected output
39
+
40
+ ```
41
+ abom-verify [compliant]: CLEAN ✓ over 2 actions
42
+ abom-verify [violating]: BLOCKED ✗ (5 findings) over 2 actions
43
+ • [high] model_allowlist (seq 0): unapproved model used: external/gpt-4o
44
+ • [high] composition_drift (seq 0): runtime model not in signed manifest: external/gpt-4o
45
+ • [high] approval_coverage (seq 0): consequential action without approval
46
+ • [high] residency (seq 1): confidential data egressed
47
+ • [medium] egress_allowlist (seq 1): egress to unapproved endpoint: telemetry.vendor.example
48
+ scrubbing the record → chain integrity: BROKEN (detected)
49
+ ✓ DEMO ASSERTIONS PASSED
50
+ ```
51
+
52
+ ## Artifacts (written to `demo/out/`)
53
+
54
+ - `composition.json` — the signed Composition Manifest.
55
+ - `provenance_compliant.json` / `provenance_violating.json` — the hash-chained Action Provenance chains.
56
+ - `verify.json` — the machine-checkable abom-verify results.
57
+
58
+ ## What this proves — and what it doesn't
59
+
60
+ It proves the four ABOM mechanics: **composition** is captured and signed,
61
+ **provenance** is recorded and tamper-evident, **verify** catches policy
62
+ violations that would otherwise ship silently, and scrubbing the evidence is
63
+ **detected**.
64
+
65
+ It does **not** prove capture *completeness* — here the actions are supplied by
66
+ the demo. The real product earns completeness by generating from inside the agent
67
+ runtime / control plane (see the project docs (kept private) §3.2),
68
+ which is the next thing to build and the metric to put in front of a design
69
+ partner.