Metadata-Version: 2.4
Name: checkii-verify
Version: 0.1.0
Summary: Offline verifier for Checkii signed evidence: report bundles, sealed exports, release receipts and their transparency-log entries
Author: Checkii
License-Expression: Apache-2.0
Project-URL: Homepage, https://checkii.ai/verify
Project-URL: Source, https://pypi.org/project/checkii-verify/#files
Project-URL: Documentation, https://checkii.ai/sample/VERIFY.md
Keywords: security,verification,ed25519,transparency-log,sigstore,rekor,evidence
Classifier: Development Status :: 4 - Beta
Classifier: Environment :: Console
Classifier: Intended Audience :: Developers
Classifier: Intended Audience :: Information Technology
Classifier: Operating System :: OS Independent
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3 :: Only
Classifier: Topic :: Security
Classifier: Topic :: Security :: Cryptography
Requires-Python: >=3.11
Description-Content-Type: text/markdown
License-File: LICENSE
License-File: NOTICE
Requires-Dist: cryptography<51,>=43
Dynamic: license-file

# checkii-verify

Offline verifier for Checkii signed evidence. Apache-2.0. Python 3.11 or later.

It checks, without an account and without a network connection, that the exact
bytes in front of you were signed by a key you trust independently of the file
under test:

- a **report bundle** (`signature.json` beside `report.md` and `snapshot.json`,
  statement `aegis.report-signature.v1`);
- a **sealed export**: the release receipt `checkii-ci assess --receipt` writes
  (`checkii.release-receipt-seal.v1`), a Cyber Resilience Act readiness pack
  (`checkii.audit.cra-pack-seal.v1`) or a time-to-verified-fix export
  (`checkii.remediation.verified-fix-seal.v1`);
- for either, the **transparency-log entry** recorded for the statement when it
  travels with the evidence (`transparency.json` in a bundle, `transparency` in
  an export): the entry names the statement's digest, is signed over the same
  bytes by the key's published log-signing companion, its leaf hash is the entry
  identifier, the inclusion proof reaches the checkpoint root, and the checkpoint
  is signed by the pinned log key.

The same checks run in the browser at https://checkii.ai/verify. Governed-OSINT
transcripts (DSSE envelopes) are verified by that page only; this release does
not cover them.

## Install

```sh
python -m pip install "checkii-verify==0.1.0"
checkii-verify version
```

For an install that resolves nothing, take `requirements.txt` from the sdist
(it pins the one runtime dependency, `cryptography`, with every PyPI digest):

```sh
python -m pip install --require-hashes -r requirements.txt
python -m pip install --no-deps "checkii-verify==0.1.0"
```

## Establish trust first

The key identifier and public key must come from a reviewed source outside the
file being checked: the published key registry at
https://checkii.ai/.well-known/checkii-signing-keys.json read over a channel you
trust, or a value your supplier gave you directly. Reading the key out of the
bundle proves nothing. When a transparency entry is present you also need the
key's log-signing companion: the registry entry with purpose
`transparency-signature` whose `signs_for` is the key id.

## Commands

```sh
checkii-verify bundle <directory> --trusted-key-id <id> --trusted-public-key <base64> \
    [--trusted-log-signing-public-key <base64 SubjectPublicKeyInfo DER>]
checkii-verify seal   <file.json>  --trusted-key-id <id> --trusted-public-key <base64> \
    [--trusted-log-signing-public-key <base64 SubjectPublicKeyInfo DER>]
checkii-verify version
```

`bundle` reads `signature.json`, `report.md`, `snapshot.json` and, when present,
`transparency.json` from the directory. `seal` reads one exported JSON file:
the whole export (`{"receipt": …, "seal": …, "transparency": …}`), in which
case the document's digest is recomputed and compared, or the seal object alone,
in which case the signed digest is printed for you to compare.

| Exit | Meaning |
|---|---|
| 0 | `VALID`: these exact bytes were signed by the supplied trusted key |
| 1 | `INVALID`: malformed input, untrusted key, failed signature, changed bytes, or an entry that does not verify |
| 2 | usage error |

The check is deliberately exact. A text editor that converted line endings, a
mail client that appended a newline or a re-saved file makes a bundle INVALID;
ask the issuer for the original export.

## What a valid result means

That these bytes were issued unchanged by the holder of that key, and, with a
transparency entry, that the issuance was recorded in the public log at that
time. It is not scan evidence, not a statement that a target is secure and not a
compliance claim. A receipt says what ran and what was reported; findings carry
their own validation status.

## Tests

```sh
python -m pip install --require-hashes -r requirements.txt pytest
python -m pytest tests/ -q
```

The tests cover the published sample bundle and its tamper matrix, a real
capture from the public Rekor log for the Merkle and checkpoint arithmetic, and
a synthetic log with a real ECDSA key for the whole flow and its negatives.
