scitt-cose
A generic, payload-agnostic IETF SCITT + COSE Receipts substrate for Python:
build/verify COSE_Sign1 Signed Statements, verify Receipts and RFC 9162
inclusion / consistency proofs, with the Merkle + receipt-signing
primitives. A separate module, scitt_cose.cll, verifies a Checkpointed
Local Log (MMR inclusion, consistency and range proofs against a checkpoint);
it is narrower than the rest of the package, see
CLL verification.
It is NOT a transparency service (operating a log — a hosted registration
endpoint — is a separate concern), and it carries NO application profile —
bring your own statement semantics. The only third-party dependencies anywhere
in the package are cbor2 and
cryptography, plus the standard
library. COSE_Sign1 (RFC 9052) is implemented here from scratch — it does not
use python-cwt or any other COSE library.
Name note.
scitt-coseis the finalized package name, claimed on PyPI and GitHub (action-state-group/scitt-cose) in the same pass.
What this does / does not do
Does:
- Verify a SCITT Signed Statement (
COSE_Sign1) signature against a supplied key — EdDSA and ES256 — and report its issuer / subject / content-type / alg. - Verify a COSE Receipt carrying either of two verifiable data structures:
RFC9162_SHA256(vds = 1, the tree algorithm registered by RFC 9942) or CCFccf.v1(vds = 2, Microsoft CCF's Merkle format, used by scitt-ccf-ledger v7+) — the RFC 9162 SHA-256 inclusion proof and the log's signature over the reconstructed root — i.e. "this statement is provably in the log" — without trusting the log operator. The vds value is read from the protected header only and anything other than these two registered structures is rejected, not silently accepted. - Provide the RFC 9162 Merkle primitives (root, inclusion, consistency) and a
build_receiptprimitive. - Verify a Checkpointed Local Log offline (
scitt_cose.cll): that a leaf is under a checkpoint's MMR root, that one checkpoint extends an earlier one, and that a range of leaves is complete, with the checkpoint's own receipt checked byverify_receipt.
Does NOT:
- Operate a Transparency Service. It never registers statements, issues receipts, witnesses, or stores anything. Running a log is a separate concern with its own operational trust obligations.
- Validate any application profile's payload semantics. The statement payload
is treated as opaque bytes. There is no application-profile awareness —
SBOMs, agent actions, or anything else; that neutrality is deliberate, and is
what makes this reusable by anyone in the SCITT ecosystem. The one
exception is honest to name:
scitt_cose.cllknows one log format, the CLL checkpoint record (below). Its leaves are still opaque digests. - Depend on a COSE library for wire values.
COSE_Sign1is implemented from scratch overcbor2+cryptography; code points are pinned to the IANA registries, not to a library's enum.
Why this exists
This is a standalone, profile-opaque, cross-validated generic SCITT/COSE verifier: it verifies anyone's SCITT Signed Statements and COSE Receipts, treats the payload as opaque bytes, and its conformance is checked against independent, external references (the published RFC 6962/9162 Merkle vectors, a third-party COSE library, and a separate Go implementation — see Correctness & cross-implementation evidence).
It is intended to be useful as neutral substrate: the parts that exist today
don't fit that gap cleanly — python-cwt is COSE-only (no SCITT/Receipts), and a
transparency-service emulator is a server, not a verification library you depend
on. So this is the small building block — a second, independent implementation
you can verify against, with no profile baked in. (No primacy is claimed; the
value is neutrality + verifiable conformance, not being "first".)
An agent-action profile is one example consumer that builds its statement/claim semantics on top of this substrate — but nothing profile-specific lives here.
Provenance, neutrality & governance
Three things an adopter should know up front:
- Built by Action State Group. We built this for our own SCITT use and publish it as community substrate under Apache-2.0.
- Neutral by design. No application profile, no vendor coupling,
payload-opaque. The package imports only
cbor2,cryptography, and the standard library — it does not import any Action State code, and a test gate (tests/test_iana_codepoints.py) enforces that this stays true. - Foundation intent. We intend to contribute this project to a neutral open-source foundation so its governance does not rest with any single vendor. Which foundation is deliberately not yet decided; until then it is governed in the open under DCO + Apache-2.0 (see CONTRIBUTING.md).
- Development. This project is built and maintained by Action State Group, with AI-assisted engineering (Claude Code) used as a development tool. Every contribution is human-reviewed and DCO-signed. Correctness does not rest on trusting any author — human or otherwise: conformance is enforced in CI by the published RFC 6962/9162 test vectors, an independent clean-room Go implementation, and cross-checks against a third-party COSE library, none of which can be skipped.
Scope
In scope (library plumbing):
- Build / parse / verify Signed Statements and Transparent Statements.
- Verify Receipts + RFC 9162 inclusion and consistency proofs.
- RFC 9162 SHA-256 Merkle primitives and the receipt-signing primitive
(
build_receipt) — so you can mint receipts as a building block.
Out of scope (documented, deliberately not built):
- Operating a transparency log / service. A hosted registration endpoint, log storage, monitoring, witnessing, gossip — none of that is here. The primitives needed to build one (Merkle tree, receipt signing) are included.
Install
pip install cbor2 cryptography # runtime deps
# from a checkout (package root):
pip install -e .
Quick start
from cryptography.hazmat.primitives.asymmetric import ed25519
from cryptography.hazmat.primitives import serialization
from scitt_cose import (
build_signed_statement, parse_signed_statement,
merkle_root, inclusion_proof, verify_inclusion,
consistency_proof, verify_consistency,
build_receipt, verify_receipt,
attach_receipts, extract_receipts,
)
# --- a key (caller supplies everything) ---
sk = ed25519.Ed25519PrivateKey.generate()
priv = sk.private_bytes(serialization.Encoding.PEM,
serialization.PrivateFormat.PKCS8,
serialization.NoEncryption())
pub = sk.public_key().public_bytes(serialization.Encoding.PEM,
serialization.PublicFormat.SubjectPublicKeyInfo)
# --- Signed Statement (generic; no profile) ---
stmt = build_signed_statement(
b'{"hello":"world"}',
alg="EdDSA", private_key_pem=priv,
issuer="https://issuer.example",
subject="my-artifact",
content_type="application/json",
extra_cwt_claims={"my_claim": "x", 99: 1}, # str- or int-keyed
)
parsed = parse_signed_statement(stmt, public_key_pem=pub)
assert parsed["signature_verified"] is True
assert parsed["issuer"] == "https://issuer.example"
# --- Merkle (RFC 9162 SHA-256; hex in/out) ---
entries = [b"a".hex(), b"b".hex(), b"c".hex(), b"d".hex()]
root = merkle_root(entries)
path = inclusion_proof(entries, 2)
assert verify_inclusion(entries[2], 2, len(entries), path, root)
cproof = consistency_proof(entries, 2, 4)
assert verify_consistency(merkle_root(entries[:2]), root, 2, 4, cproof)
# --- Receipt (primitive) + verify ---
receipt = build_receipt(
leaf_entry_hex=entries[2], leaf_index=2, tree_entries_hex=entries,
alg="EdDSA", log_private_key_pem=priv, # here the "log" key is our key
)
res = verify_receipt(receipt, leaf_entry_hex=entries[2], log_public_key_pem=pub)
assert res.ok and res.root == root
# --- Transparent Statement = Signed Statement + Receipts ---
transparent = attach_receipts(stmt, [receipt])
assert extract_receipts(transparent) == [receipt]
CLI
scitt-cose --statement stmt.cose --statement-pubkey issuer.pem
scitt-cose --receipt receipt.cose --receipt-log-pubkey log.pem --leaf-entry-hex 61
scitt-cose --statement stmt.cose --receipt receipt.cose \
--receipt-log-pubkey log.pem --leaf-entry-hex 61 --json
Public API
| Area | Functions / types |
|---|---|
| COSE_Sign1 | sign_sign1, verify_sign1, Sign1, CoseError |
| Statements | build_signed_statement, parse_signed_statement, attach_receipts, extract_receipts |
| Merkle | leaf_hash, merkle_root, inclusion_proof, verify_inclusion, consistency_proof, verify_consistency |
| Receipts | build_receipt, verify_receipt, ReceiptResult |
CLL (scitt_cose.cll, its own namespace) |
verify_leaf_against_checkpoint, verify_checkpoint_chain, verify_range_against_checkpoint, witness_status_line; the proof types InclusionProof, ConsistencyProof, RangeProof, Checkpoint; the MMR primitives (leaf_hash, interior_hash, root_from_peaks, peaks, verify_inclusion, verify_consistency, verify_range) |
| Status | DRAFT_TRACKING_NOTICE, RFC_SCITT_ARCHITECTURE, RFC_COSE_RECEIPTS, SUBSTRATE_RFCS (DRAFT_* names kept as aliases) |
Failure contract
A verifier's behaviour on hostile and malformed input is part of its API, so it
is spelled out here and enforced by tests (tests/test_hardening.py) and by
continuous differential fuzzing (see below).
parse_signed_statementandverify_receiptnever raise on input. Every outcome — bad signature, malformed CBOR, truncation, a hostile length or tree size — is reported in the returned value (signature_verified/ReceiptResult.ok), never as a leakedcbor2/RecursionError/ other exception. ACoseErroris reserved for the low-level primitiveverify_sign1(a building block), which raises on failure by design.- Identity is authenticated-only.
parse_signed_statementpopulatesissuer/subject/content_type/alg/claimsonly whensignature_verified is True. When the signature did not verify (wrong key, bad signature) or no key was supplied, those top-level fields areNone, and the structurally-decoded values are fenced under an explicitunverifiedsub-dict — so an integrator can never mistake an attacker-chosen issuer for a signed one.verified ⇒ trust the fields; not verified ⇒ they are underunverified`, clearly labelled. - Strict, non-malleable decoding. Both verify paths reject trailing bytes after the COSE_Sign1, indefinite-length / non-deterministic encodings, and duplicate protected-header keys — so one signature cannot be presented in many byte encodings, and the Python and Go verifiers agree on accept and reject.
- Bounded cost. Messages are size-capped; tree sizes and inclusion-proof
lengths are bounded and length-checked before any hashing or allocation, and
no decoded integer is ever coerced to
bytesbefore validation. A tiny hostile receipt cannot trigger a multi-gigabyte allocation or an unbounded loop on either runtime.
See docs/hardening-review.md for the review, the
finding-by-finding resolutions, and the consciously-accepted items.
Algorithms
sign_sign1 / statements support "EdDSA" (code point −8) and "ES256"
(−7). For ES256, COSE carries the signature as raw r || s (64 bytes), not
DER; the conversion happens at the cryptography boundary. ML-DSA code points
(RFC 9964) are recognized in the status notice but signing is not
implemented here.
ES256 signatures are accepted in their canonical form as verified by
cryptography; s-value malleability (high-s) is not rejected — see the
Security Considerations in docs/hardening-review.md
for why that is a documented, accepted property rather than a bug.
Why CWT Claims at label 15 (not 13)
Signed-Statement CWT Claims are placed in the protected header at label 15,
the "CWT Claims" header parameter registered by RFC 9597 §2. Label 13 is
a different parameter (kcwt, RFC 9528) and is sometimes mistakenly used for the
claims map; this library always reads and writes the claims at 15.
Receipt vdp encoding (honest caveat)
The Receipt's verifiable-data-proof shape is RFC 9942 (COSE Receipts; unchanged from draft-ietf-cose-merkle-tree-proofs-18, which this library was first built against):
- protected
1= alg, protected395= vds (1=RFC9162_SHA256); - unprotected
396= vdp map with key-1→ array of inclusion-proof bstrs; - each inclusion-proof bstr =
cbor([tree_size, leaf_index, [audit_path bstrs]]); - payload = the Merkle root (detached by default).
verify_receipt reads vds from the protected header only (it is
security-relevant and must be integrity-protected), reconstructs the root from
the proof, and verifies the COSE_Sign1 over that root with the log key. This
exact CBOR shape is validated by round-trip in this library's own tests and
against the code points RFC 9942 registers (vds 395, vdp 396, RFC9162_SHA256 = 1).
CLL verification (scitt_cose.cll)
A Checkpointed Local Log appends records locally, commits to them with a
Merkle Mountain Range (MMR), and registers a signed checkpoint of that
MMR with a Transparency Service. scitt_cose.cll is the verifier for it: a
third party holding a record digest, a proof and a checkpoint can check,
offline,
- that the leaf is under the checkpoint's MMR root (inclusion);
- that a later checkpoint extends an earlier one, with no rollback (consistency);
- that a run of leaves is complete, with none left out (range);
- and that the checkpoint was registered, through the checkpoint's own COSE
Receipt and the unchanged
verify_receipt.
Every result reports "witnessed up to size S at time T", never a bare boolean, and shows the lag when it is known.
What it is not, honestly:
- It is not RFC 9162. An MMR is a different tree construction, which is
why the module keeps its own namespace and is not exported at the top
level: its
verify_inclusionwould otherwise collide with the RFC 9162 one. - It knows one format.
Checkpoint.digest()is a byte-identical port of the checkpoint record that checkpointed-local-log andcapsule-emitproduce. It is a port, not an import, so this package still depends only oncbor2andcryptography. The records under the leaves stay opaque: the module sees only their digests. - It does not check the checkpoint's own signature. The producer signs checkpoints with a scheme it chooses, which a neutral verifier cannot check generically. The receipt is what this module verifies.
It is checked against the vectors in test-vectors/mmr/
(KAT39, proof and range vectors) and in tests/test_cll.py.
Standards status / honesty
The SCITT Architecture is now RFC 9943 (published June 2026). This library implements RFC 9943 as its normative SCITT base.
COSE Receipts is RFC 9942
(formerly draft-ietf-cose-merkle-tree-proofs-18). This library implements its
Receipt encoding and the RFC9162_SHA256 verifiable data structure.
No unassigned RFC number is claimed anywhere (enforced by a test that scans shipped source + docs).
Published RFCs whose mechanisms this library implements / relies on (titles verified against the RFC Editor / IANA registries):
- RFC 9052 — CBOR Object Signing and Encryption (COSE): Structures and Process (COSE_Sign1, Sig_structure).
- RFC 9053 — COSE: Initial Algorithms (EdDSA −8, ES256 −7).
- RFC 9162 — Certificate Transparency Version 2 (SHA-256 Merkle tree; inclusion and consistency proofs; reuses the RFC 6962 tree hash).
- RFC 9597 — CBOR Web Token (CWT) Claims in COSE Headers — the CWT Claims
header parameter at label 15 (IANA COSE Header Parameters registry). Label
13 is
kcwtand 14 iskccs, both from RFC 9528 (EDHOC) — not the CWT Claims map; using 13 for claims is the python-cwt bug this library avoids. - RFC 9964 — ML-DSA for JOSE and COSE (code points recognized; ML-DSA signing not implemented here).
Independence
scitt_cose/ imports only cbor2, cryptography, and the standard library.
It does not import cwt / python-cwt, pycose, or any consuming
product/profile package. Verify:
grep -rnE 'import (cwt|pycose)\b' scitt_cose/ # → nothing
Two tests keep this true: the COSE-library import guard and the
no-downstream-code neutrality gate (both in tests/test_iana_codepoints.py).
Correctness & cross-implementation evidence
For a community verifier, "trust me, it's conformant" is worthless. The correctness story rests on agreement with things outside this library, not on self-consistency:
- Cross-language agreement (in CI). An independent Go verifier
(the
scitt-cose-go-verifydirectory, built onveraison/go-cose+fxamacker/cbor, with a clean-room Merkle fold) verifies the statements and receipts this library emits, agrees on the reconstructed Merkle root, and rejects tampered inputs. CI runs it withSCITT_REQUIRE_GO=1, so the cross-check can never silently skip. (tests/test_crosslang_go.py) - A second, receipt-only cross-language check: Rust.
rust/scitt-cose(oncoset+ed25519-dalek/p256, with its own clean-room RFC 9162 Merkle fold inrust/scitt-cose/src/merkle.rs) independently verifies receipts this library emits, including theiat/gradeprotected-header labels and the two booleans (witness_time_established,grade_cryptographically_bound) derived from them. Receipt-only by design — it never reads a Signed Statement. CI runs it withSCITT_REQUIRE_RUST=1. (tests/test_crosslang_rust.py) - The standard's own test vectors. The Merkle code is checked against the
published RFC 6962 / RFC 9162 reference vectors (8-leaf root
5dc9da79…, the canonical inclusion/consistency proofs) — external values, not ours. (tests/test_rfc9162_vectors.py) - A third-party COSE library.
pycose(independent of us, and notpython-cwt) both verifies our statements and emits statements we verify — so the round-trip isn't self-referential. (tests/test_thirdparty_cose.py) - The COSE standard's own reference-signed vector. We verify the canonical
COSE_Sign1 the COSE WG published (RFC 9052 §C.2.1, ES256, from the
cose-wg/Examplescorpus) — anchoring the signature layer to the spec's reference output, just as the RFC 6962 vectors anchor the Merkle layer. (tests/test_cose_wg_vectors.py) - A real Transparency-Service verifier. A downstream Transparency
Service's own verifier — written independently of this package, on a
different COSE stack (
python-cwt, vs this package's from-scratchcbor2/cryptography) — cross-verifies the same Signed Statements and the same TS-issued Receipts and agrees on the reconstructed Merkle root, in both directions. This exercises the real register→issue→verify shape; the integration test lives in the consuming repo (so this package stays standalone). This is not the hosted verify endpoint: that endpoint runs this package unchanged (a convenience deployment, deliberately the same library), so it is not an independent oracle — the python-cwt verifier is. - IANA values, not library enums. Every wire code point is asserted against
its registry/RFC number (CWT Claims 15, not python-cwt's
13). (tests/test_iana_codepoints.py) - Spec-driven negative suite. The MUST-reject conditions — alg confusion,
critical-header (
crit) handling,vdsdowngrade, wrong-leaf/wrong-log receipts, Merkle edge cases, malformed CBOR — each have a test. (tests/test_negative_conformance.py)
Evaluated and not used: the SCITT API emulator. The
scitt-community/scitt-api-emulatorwas considered as an ecosystem oracle and rejected: it is archived/unmaintained (final "pre-archive" tag, Nov 2024) and emits the obsolete pre-standard receipt format (draft-birkholz-scitt-receipts— string labelsservice_id/tree_alg, not a COSE_Sign1 receipt, not thevds=395 /vdp=396 RFC 9162 structure this library verifies); its statements usepycose, already covered above. Pinning a non-conformant, drift-prone implementation would be a misleading oracle, so the COSE WG spec vector is used in its place.
Cross-implementation validation
At IETF 126 (Vienna, Jul 2026), receipt verification was cross-validated:
microsoft/scitt-ccf-ledger PR #424
pins the published pyscitt test inputs as vectors-ietf126; ccf.v1 + RFC 9162
SHA-256 receipts were verified under one dispatch path against this library's
verify_receipt().
Hosted verification — a standalone SCITT-only verifier
hosted_profiles.hosted is a stateless, read-only wrapper over the same
verify functions, so you can offer verification without anyone installing
anything — and without the submitter having to trust the operator with their
data (nothing stored, nothing logged, payload-opaque; the receipt path needs
only the leaf digest, never the payload). tests/test_hosted_parity.py
asserts the hosted verdict equals the local verdict on a fixture set,
including the ASGI path.
Not part of the published scitt-cose package. hosted_profiles/ (the
hosted HTTP wrapper plus its application-profile renderers) is excluded from
the built wheel — the neutral, pip install-able package is verifier APIs
only. hosted_profiles.hosted only runs from a full repo checkout (see the
Dockerfile, or clone + run below).
This is a SCITT-only verifier, and it is NOT a Transparency Service. It verifies statements and receipts; it never registers, issues receipts, or witnesses. Running a Transparency Service is a separate offering with its own operational trust obligations — deliberately out of scope here.
Run it standalone from a repo checkout (no other service involved):
# Under a production ASGI server (pip install ".[serve]" from the checkout):
uvicorn hosted_profiles.hosted:make_asgi_app --factory --host 0.0.0.0 --port 8080
# Or containerized (Dockerfile ships in the repo):
docker build -t scitt-verifier . && docker run -p 8080:8080 scitt-verifier
GET / -> capabilities (what it does / does not do)
POST /verify -> {valid, statement, receipt, reasons} # JSON body, see below
GET / is content-negotiated: browsers (Accept: text/html) get a static
landing page that renders the verifier-vs-Transparency-Service boundary table
on the page itself — not buried in docs — while API clients get the same data
as JSON (including a boundary field). Both are generated from the same
constants (hosted_profiles.hosted.BOUNDARY_TABLE), so page and API can't
drift; tests/test_hosted_page.py pins the table's presence on both.
It can also ride along inside an existing ASGI app via
app.mount("/scitt-verify", hosted_profiles.hosted.make_asgi_app()) — same
logic, shared deployment, still standalone code. The full design, submitter-safety
constraints, and proposed deployment shape are in
docs/hosted-verifier-design.md. A hosted
instance is live at https://verify.agentactioncapsule.org — this package unchanged
(the parity-tested wrappers, deployed); its landing page renders the
verifier-vs-Transparency-Service boundary table and states the privacy posture.
You don't need it: the verifier runs anywhere.
Bundle & capsule permalinks — offline, not just hosted
GET /v/<capsule_id> and GET /bundle are the recipient-side viewers behind
capsule bundle's permalinks. The record never leaves the browser in
either mode — it rides in the URL fragment (the part after #), which
HTTP never transmits, so the server serving the viewer's HTML/JS never sees
the bytes being verified. Integrity, Sequence and (bundle-only) Range membership/
Cross-check are checkable with zero network: download the self-contained
copy from GET /bundle/offline-shell and it still verifies opened straight
from file://. Authenticity (the COSE signature) isn't evaluated by this
browser page yet — that stage renders an honest skip, never a fabricated
pass — but is checkable with zero network too, via the CLI's
permalink --check or scitt-cose installed locally. Witness needs a
network by definition — it's a claim about a log someone else keeps — and
when the witness is unreachable the viewer renders that stage skipped, not
failed. Full trust model, including exactly what a server does learn (a
viewed capsule_id, and — until you've downloaded and diffed it — trust in
served JS): docs/verification-trust-model.md.
Drop a file instead of opening a link. GET / and GET /bundle both
accept a dropped (or chosen) file: an Evidence Bundle (.json), or a
self-contained report page (.html) whose embedded bundle
(window.__BUNDLE__ = …;</script>) is read out of it. The file is read with
the browser's FileReader and checked on the page; it is never uploaded. A
file dropped on / is handed to /bundle in sessionStorage (same origin,
that tab only), never sent to the server. Files over 16 MiB are refused.
Test vectors (cross-implementation, stable)
test-vectors/ is a frozen, append-only vector set for
other SCITT/COSE implementations to check themselves against: four happy-path
vectors (EdDSA, ES256, a real CCF ccf.v1 receipt, a multi-proof receipt) and
four negative vectors (tampered inclusion path, unsupported vds, bad statement
signature, zero-size proof), each with committed bytes, TEST-ONLY
keys, and an expected.json documenting every protected-header field a
verifier needs. Verify from a clean checkout:
git clone https://github.com/action-state-group/scitt-cose
cd scitt-cose && pip install -e . && python -m scitt_cose.vectors
or from the published package (the runner ships in scitt-cose ≥ 0.1.0):
pip install "scitt-cose>=0.1.0", download test-vectors/, then
python -m scitt_cose.vectors path/to/test-vectors (add --json for a
machine-readable report). The Go clean-room implementation runs the same
manifest (go test ./... in scitt-cose-go-verify/); the Rust clean-room
implementation runs it too (cargo test --test vectors in
rust/scitt-cose/). The append-only promise is enforced, not just stated:
test-vectors/SHA256SUMS pins every published byte and CI fails on any
mutation. A mismatch against your implementation is exactly the report we
want — please open an issue. Details and the stability promise:
test-vectors/README.md.
A second, receipt-only vector set,
test-vectors/receipt-v1/, exercises the iat
and private-use grade (-65537) protected-header labels — including a
real captured receipt from a live TRACE-registry witness alongside synthetic
EdDSA/ES256 vectors and two post-signature tamper vectors. Same append-only
promise, own SHA256SUMS. Details:
test-vectors/receipt-v1/README.md.
More vector sets in this repository
| Set | What it pins | Checked by |
|---|---|---|
test-vectors/mmr/ |
MMR known answers (KAT39), inclusion and consistency proofs, and range proofs | scitt_cose.cll (tests/test_cll.py) and the browser range check |
test-vectors/capsule-id/ |
the browser port of the Agent Action Capsule id recompute, against that library's Python reference | the hosted viewers only (hosted_profiles/); not the package |
test-vectors/tamper-states/ |
four bundle states (offline pass, digest mismatch, chain gap, witness downgrade) for the bundle viewer's checks | the hosted viewers only (hosted_profiles/); not the package |
The last two exist for the hosted viewers, which render one application profile. The package itself never reads them.
What else is in this repository
The published package is scitt_cose/ alone. Everything else is here for
cross-checking, hosting or history, and stays out of the wheel:
| Path | What it is |
|---|---|
scitt-cose-go-verify/ |
the independent Go verifier CI cross-checks against (above) |
rust/scitt-cose/ |
the independent, receipt-only Rust verifier (above) |
hosted_profiles/ |
the hosted HTTP verifier and its viewers (above). Unlike the package, it renders application profiles: aac.py for Agent Action Capsules and machine_mandate.py, plus published-witnesses.json |
viewer/ |
the source of the hosted viewers' bundled browser checks (aac-crypto.js, witness-check.js), built from vendored copies of the agent-action-capsule and CLL TypeScript libraries |
demo/ |
a synthetic, worked example: a fictional bank's three-capsule refund chain registered on a live Transparency Service. It shows one application profile on top of this substrate; nothing in it is part of the package |
interop/ccf/ |
the IETF 126 cross-service check: one statement with receipts from two independent Transparency Services (an RFC 9162 log and a CCF node), both verified by verify_receipt |
interop/vcp/ |
an envelope probe: a VeritasChain VCP event payload wrapped in a Signed Statement verifies through parse_signed_statement as opaque bytes |
scripts/ |
one-time vector generators (each says what it pins), the Python-vs-Go differential fuzzer, and smoke_verify.py, which checks a running verifier |
docs/ |
the hardening review, the hosted-verifier design, the verification trust model and the launch checklist |
INTEROP.md |
a pointer: the interop registry moved to agent-action-capsule |
Tests
python3 -m pytest -q # unit + conformance suite (package root)
SCITT_REQUIRE_GO=1 python3 -m pytest -q # also forces the Go cross-check
python3 -m ruff check .
License & contributing
Apache-2.0 — see LICENSE and NOTICE. Contributions are
accepted under the Developer Certificate of Origin (sign your commits with
git commit -s); scope rules and the standards-honesty gates are in
CONTRIBUTING.md. Releases are cut through a reviewed version-bump pull
request; see RELEASING.md.
Metadata
Release files for scitt-cose 0.4.2
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| scitt_cose-0.4.2.tar.gz | 158.3 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| scitt_cose-0.4.2-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 217.3 kB
Release files / scitt_cose-0.4.2.tar.gz
| Download URL | scitt_cose-0.4.2.tar.gz |
|---|---|
| Size | 158.3 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
5dc284e44739c07b3bc90ee3fe1186ef9fe9bfe90141a7528b4d3f64c5b6d073
|
|
BLAKE2b-256 checksum How to use checksums |
6d41038314873ba4b5cd8fbf5b191593aa5092dddd45b0bb689103d9d0269b5c
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Oct 14, 2026.
Transparency logRelease files / scitt_cose-0.4.2-py3-none-any.whl
| Download URL | scitt_cose-0.4.2-py3-none-any.whl |
|---|---|
| Size | 59.1 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
b75d70a67ef2d232a3b9136c2bdd9915354b4f1b949214b563d885f487cb6797
|
|
BLAKE2b-256 checksum How to use checksums |
189b04aba238ecbec736db357990a091c6e9a95d1c543102926167848e83a8dd
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Oct 14, 2026.
Transparency log