audit-labs/evidence-seal
Tamper-evident seals and chain of custody for audit evidence.
clone: git clone https://gitbay.org/audit-labs/evidence-seal.git
de4792aac7adb09234c2a2247b7dc1216ff95b07
verified · cmc
author: Christian Cleberg <hello@cleberg.net> · 2026-08-07T02:13:39Z
.github/workflows/ci.yml | 26 ++++++++++++++++++++++++++ README.md | 21 ++++++++++++++++----- scripts/_local_tsa.py | 2 +- 3 files changed, 43 insertions(+), 6 deletions(-) new file mode 100644 @@ -0,0 +1,26 @@ +name: CI + +on: + push: + pull_request: + +jobs: + test: + runs-on: ubuntu-latest + strategy: + matrix: + python-version: ["3.10", "3.12"] + steps: + - uses: actions/checkout@v5 + - name: Set up Python ${{ matrix.python-version }} + uses: actions/setup-python@v6 + with: + python-version: ${{ matrix.python-version }} + - name: Install + run: | + python -m pip install --upgrade pip + pip install -e ".[dev]" + - name: Ruff + run: ruff check . + - name: Tests + run: pytest -q @@ -27,12 +27,15 @@ timestamping needs `asn1crypto` (`evidence-seal[timestamp]`). ## Install ```bash -git clone https://github.com/audit-labs/evidence-seal -cd evidence-seal -python -m venv .venv && source .venv/bin/activate -pip install -e ".[sign,timestamp]" # or drop the extras for the zero-dependency core +# Core is pure standard library; extras add signing + timestamping. +pip install "evidence-seal[sign,timestamp] @ git+https://github.com/audit-labs/evidence-seal" + +# Or, for the zero-dependency core, drop the extras: +pip install "evidence-seal @ git+https://github.com/audit-labs/evidence-seal" ``` +To hack on it from a clone instead, see [Development](#development). + ## Usage ```bash @@ -160,7 +163,15 @@ untimestamped* manifest can be regenerated by anyone with the files, and its guarantee, **sign** the manifest (retain the public key out of band) and **timestamp** it with a trusted TSA. -Two limits to be honest about: +**What a seal does not prove.** A seal proves the *package* is unchanged since it +was sealed — nothing more. It says nothing about whether the collection faithfully +represented the system at collection time: whether the right scope was captured, +whether a query was complete, or whether the evidence was gathered from the +production system at all. That is the question an auditor actually asks, and it is +answered by collection controls and re-performance, not by this tool. Seal the +evidence; don't mistake an intact seal for a trustworthy collection. + +Further limits to be honest about: - **`timestamp verify` checks the binding; `--tsa-cert` adds signature verification but not chain-of-trust.** Without a cert, verification proves the @@ -17,7 +17,7 @@ _REPO = _HERE.parent.parent sys.path.insert(0, str(_REPO / "tests")) sys.path.insert(0, str(_REPO)) -from test_timestamp import issue_signed_token # noqa: E402 +from test_timestamp import issue_signed_token def main() -> None: