A runnable signer and verifier for the AI Catalog Level 3 "Trusted Catalog" trust layer, including the in-flight hardening from PR #47 / ADR-0009 (signed subject-binding, identity anchoring, algorithm allowlist, freshness, SSRF-safe fetch).
It ships a substitution-attack vector suite that demonstrates, with running code, that the attack ADR-0009 describes succeeds without subject-binding and is closed by it. The spec references this threat model in prose; this repository is a concrete, reproducible demonstration of it.
Contributed by TomeVault, which publishes quality and
consistency attestations for AI instruction files. The crypto here mirrors what
TomeVault runs in production: detached EdDSA JWS over RFC 8785 JCS, keys resolved
by kid from a published .well-known/jwks.json. TomeVault serves its own
catalog signed this way, subject-bound to the served bytes, at
tomevault.io/.well-known/ai-catalog.json.
| Spec element | Module | Notes |
|---|---|---|
| Detached JWS over JCS (RFC 7515 + 8785) | jws.py, jcs.py |
empty-payload compact serialization header..signature |
| Algorithm allowlist (RFC 8725 / PR #47 F4) | jws.py |
rejects none and all HMAC; permits EdDSA/ES*/PS*/RS256 |
| Subject-binding (PR #47 / ADR-0009) | manifest.py |
signed subject {url, mediaType, digest} closes substitution |
| Identity anchoring (PR #47 F3) | manifest.py |
identity domain MUST align with the entry urn:air: publisher |
| Freshness (PR #47 F5) | manifest.py |
required issuedAt, optional expiresAt |
| SSRF-safe fetch (PR #47 F7) | fetch.py |
https-only, blocks loopback/link-local/private/metadata |
Key resolution (HTTPS JWKS by kid) |
keys.py |
OKP/Ed25519 JWK Set export and lookup |
| Level 3 catalog assembly | catalog.py |
specVersion + host + entry trustManifest |
| Scan attestation type | attestations.py |
io.tomevault.consistency-scan, evidence not verdict |
The spec deliberately does not bless a scanner or define a quality verdict, and
leaves attestations[].type open. Following the reverse-DNS namespacing the
metadata rules already mandate, this library carries a content-addressed scan
attestation (io.tomevault.consistency-scan).
It asserts only that a content-addressed scan report is published at a URI. It
never asserts the artifact is safe or compliant. A consumer dereferences the
report, recomputes the digest, and decides. The cross-model consistency signal
is carried as a prediction of divergence risk, never a verified medal.
pip install -e .
python make_vectors.py
pytestThis signs a conformant Level 3 entry, runs eight scenarios (happy path, drift,
substitution with and without subject-binding, alg:none, identity mismatch,
expiry, JWKS resolution), asserts each verdict, and writes canonical artifacts to
vectors/. It exits non-zero if any scenario does not match its expected verdict.
The substitution scenarios are the point: scenario 3 shows a validly-signed
pre-PR-#47 manifest accepting a swapped malicious artifact; scenario 4 shows the
same swap rejected once subject is signed.
The test suite (pytest, 67 tests) is adversarial: hostile and malformed inputs,
SSRF bypass attempts (redirects, DNS rebinding, private and metadata addresses),
did:web resolution edge cases, and structural conformance against the spec's
CDDL shapes.
make_vectors.py uses a fixed-seed TEST key so the vectors are reproducible. It
is not a TomeVault production key and must not be used to sign anything real.
TomeVault's production public key is published at
https://tomevault.io/.well-known/jwks.json.