Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 13 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 2 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -38,4 +38,6 @@ thiserror = "2.0"
url = "2"

[dev-dependencies]
base64 = "0.23"
p256 = { version = "0.14", features = ["ecdsa"] }
tempfile = "3"
32 changes: 31 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,7 @@ This CLI builds on the four AI Catalog library crates, released separately from

```
ai-catalog validate [--json] <path|->
ai-catalog verify [--json] [--did-document <DID=PATH>]... [--offline] [--strict] <path|->
ai-catalog format <path|->
ai-catalog oci pack <path|->
ai-catalog oci unpack <path|->
Expand Down Expand Up @@ -133,7 +134,8 @@ Use `-` as `<path>` to read from stdin. Every command accepts `--help`.
### `validate`

Validates a catalog document against the AI Catalog specification and reports
the conformance level (Minimal / Discoverable / Trusted).
its structural conformance level (Minimal or Discoverable). The Trusted level
requires verifying signatures and artifacts; use [`verify`](#verify) for that.

```sh
ai-catalog validate catalog.json # text report
Expand All @@ -149,6 +151,34 @@ than the message. `code` is `null` when the input could not be parsed.

---

### `verify`

Validates a catalog and verifies the signatures and artifacts of its root entries, using
`ai_catalog_validate::verify`.

```sh
ai-catalog verify catalog.json
ai-catalog verify --json catalog.json
ai-catalog verify --offline --did-document did:web:example.com=did.json catalog.json
```

For each trust manifest it reports the `did-web-v1` signature (signer, protected header,
`assertionMethod` key in the signer's root `did:web` document, validity period, and the
detached ES256 JWS) and the release binding of its `subject` to the entry. For each entry it
reports whether the publisher endorsed it and, once a manifest is accepted, whether the
artifact matches `digest`. The catalog's conformance level is Trusted only when an entry has a
verified publisher endorsement and none fails.

DID documents and artifacts are fetched over HTTPS only, without redirects, with size and time
limits, and refusing private, loopback, and link-local addresses. `--did-document DID=PATH`
supplies a DID document locally, and `--offline` never fetches.

Each check is `verified`, `failed`, or `unverifiable` (it could not run, for example a fetch
skipped with `--offline`). Exits with `1` when the catalog is invalid or any check fails; with
`--strict`, also when a check is unverifiable.

---

### `format`

Pretty-prints a catalog document to stdout without modifying the source file.
Expand Down
21 changes: 21 additions & 0 deletions src/cli.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,27 @@ pub enum Command {
#[arg(long)]
json: bool,
},
/// Verify the trust manifests of a catalog's entries
///
/// Checks each manifest's release binding, its did-web-v1 signature against the
/// signer's did:web document, and its validity period, and checks inline data
/// against the entry digest. Exits 1 if any check fails.
Verify {
/// Catalog file, or '-' for stdin
path: String,
/// Print the report as JSON
#[arg(long)]
json: bool,
/// Use this DID document instead of fetching it, as DID=PATH (repeatable)
#[arg(long = "did-document", value_name = "DID=PATH")]
did_documents: Vec<String>,
/// Never fetch DID documents; manifests without a supplied document are inconclusive
#[arg(long)]
offline: bool,
/// Also exit 1 when a signed manifest could not be fully verified
#[arg(long)]
strict: bool,
},
/// Pretty-print a catalog
Format {
/// Catalog file, or '-' for stdin
Expand Down
Loading
Loading