Commit de4792aac7
de4792aac7adb09234c2a2247b7dc1216ff95b07
parent: cf5fb77d29
Verified · cmc
cmc <hello@cleberg.net> · 2026-08-07 02:13 UTC
Align install docs, expand threat model, add CI
- README install matches the site (direct-from-git one-liner); clone moved
under Development
- Threat model states that a seal proves the package is unchanged, not that
the collection faithfully represented the system at collection time
- Add ruff + pytest CI; drop a stale noqa directive
Layout: unified · split
.github/workflows/ci.yml
added
+26
| @@ -0,0 +1,26 @@ |
| 1 | name: CI |
| 2 | |
| 3 | on: |
| 4 | push: |
| 5 | pull_request: |
| 6 | |
| 7 | jobs: |
| 8 | test: |
| 9 | runs-on: ubuntu-latest |
| 10 | strategy: |
| 11 | matrix: |
| 12 | python-version: ["3.10", "3.12"] |
| 13 | steps: |
| 14 | - uses: actions/checkout@v5 |
| 15 | - name: Set up Python ${{ matrix.python-version }} |
| 16 | uses: actions/setup-python@v6 |
| 17 | with: |
| 18 | python-version: ${{ matrix.python-version }} |
| 19 | - name: Install |
| 20 | run: | |
| 21 | python -m pip install --upgrade pip |
| 22 | pip install -e ".[dev]" |
| 23 | - name: Ruff |
| 24 | run: ruff check . |
| 25 | - name: Tests |
| 26 | run: pytest -q |
README.md
+16 −5
| @@ -27,12 +27,15 @@ timestamping needs `asn1crypto` (`evidence-seal[timestamp]`). |
| 27 | 27 | ## Install |
| 28 | 28 | |
| 29 | 29 | ```bash |
| 30 | | git clone https://github.com/audit-labs/evidence-seal |
| 31 | | cd evidence-seal |
| 32 | | python -m venv .venv && source .venv/bin/activate |
| 33 | | pip install -e ".[sign,timestamp]" # or drop the extras for the zero-dependency core |
| 30 | # Core is pure standard library; extras add signing + timestamping. |
| 31 | pip install "evidence-seal[sign,timestamp] @ git+https://github.com/audit-labs/evidence-seal" |
| 32 | |
| 33 | # Or, for the zero-dependency core, drop the extras: |
| 34 | pip install "evidence-seal @ git+https://github.com/audit-labs/evidence-seal" |
| 34 | 35 | ``` |
| 35 | 36 | |
| 37 | To hack on it from a clone instead, see [Development](#development). |
| 38 | |
| 36 | 39 | ## Usage |
| 37 | 40 | |
| 38 | 41 | ```bash |
| @@ -160,7 +163,15 @@ untimestamped* manifest can be regenerated by anyone with the files, and its |
| 160 | 163 | guarantee, **sign** the manifest (retain the public key out of band) and |
| 161 | 164 | **timestamp** it with a trusted TSA. |
| 162 | 165 | |
| 163 | | Two limits to be honest about: |
| 166 | **What a seal does not prove.** A seal proves the *package* is unchanged since it |
| 167 | was sealed — nothing more. It says nothing about whether the collection faithfully |
| 168 | represented the system at collection time: whether the right scope was captured, |
| 169 | whether a query was complete, or whether the evidence was gathered from the |
| 170 | production system at all. That is the question an auditor actually asks, and it is |
| 171 | answered by collection controls and re-performance, not by this tool. Seal the |
| 172 | evidence; don't mistake an intact seal for a trustworthy collection. |
| 173 | |
| 174 | Further limits to be honest about: |
| 164 | 175 | |
| 165 | 176 | - **`timestamp verify` checks the binding; `--tsa-cert` adds signature |
| 166 | 177 | verification but not chain-of-trust.** Without a cert, verification proves the |
scripts/_local_tsa.py
+1 −1
| @@ -17,7 +17,7 @@ _REPO = _HERE.parent.parent |
| 17 | 17 | sys.path.insert(0, str(_REPO / "tests")) |
| 18 | 18 | sys.path.insert(0, str(_REPO)) |
| 19 | 19 | |
| 20 | | from test_timestamp import issue_signed_token # noqa: E402 |
| 20 | from test_timestamp import issue_signed_token |
| 21 | 21 | |
| 22 | 22 | |
| 23 | 23 | def main() -> None: |