Metadata-Version: 2.4
Name: signrun
Version: 0.1.0
Summary: Signed integrity records for scientific Python pipelines (DSSE + in-toto).
Author-email: Blake Corman <zzirblake@gmail.com>
License: Apache-2.0
Project-URL: Homepage, https://corman.io/signrun
Project-URL: Repository, https://github.com/zzirblake/signrun
Project-URL: Documentation, https://corman.io/signrun/docs
Project-URL: Issues, https://github.com/zzirblake/signrun/issues
Keywords: provenance,reproducibility,dsse,in-toto,attestation,ed25519,scientific-computing
Classifier: Development Status :: 3 - Alpha
Classifier: Intended Audience :: Science/Research
Classifier: Intended Audience :: Developers
Classifier: License :: OSI Approved :: Apache Software License
Classifier: Operating System :: MacOS
Classifier: Operating System :: POSIX :: Linux
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Classifier: Topic :: Scientific/Engineering
Classifier: Topic :: Security :: Cryptography
Classifier: Topic :: Software Development :: Quality Assurance
Requires-Python: >=3.10
Description-Content-Type: text/markdown
License-File: LICENSE
Requires-Dist: cryptography>=48.0.0
Requires-Dist: PyYAML>=6.0
Provides-Extra: dev
Requires-Dist: pytest>=8.0; extra == "dev"
Requires-Dist: pytest-cov>=5.0; extra == "dev"
Requires-Dist: ruff>=0.5; extra == "dev"
Dynamic: license-file

# signrun

[![PyPI](https://img.shields.io/pypi/v/signrun.svg)](https://pypi.org/project/signrun/)
[![Python versions](https://img.shields.io/pypi/pyversions/signrun.svg)](https://pypi.org/project/signrun/)
[![CI](https://github.com/zzirblake/signrun/actions/workflows/ci.yml/badge.svg)](https://github.com/zzirblake/signrun/actions/workflows/ci.yml)
[![License: Apache-2.0](https://img.shields.io/badge/license-Apache--2.0-blue.svg)](LICENSE)

Signed integrity records for scientific Python pipelines.

`signrun` wraps a Python entrypoint, captures content-addressed identity for declared inputs, code, declared outputs, and runtime environment, and emits a DSSE-enveloped in-toto Statement signed with Ed25519. A third party with the signer's externally-published fingerprint can verify byte-equivalence and confirm the signature matches the expected key in a single command.

**Status:** v0.1.0, alpha. The spec is stable; the implementation is under active development.

## Quickstart

```bash
pip install signrun

# Generate a keypair (prints your fingerprint -- publish it; see docs/trust-anchor.md)
signrun init

# Declare what your run reads and writes
cat > signrun.yaml <<EOF
inputs:
  - data/input.csv
outputs:
  - results/output.json
EOF

# Wrap your script (signrun uses sys.executable; no `python` prefix)
signrun wrap pipeline.py -- --seed 42

# Verify with the signer's externally-supplied trust anchor
signrun verify --fingerprint sha256:<your-fingerprint> manifest.json
```

See [`docs/quickstart.md`](docs/quickstart.md) for the full 60-second onboarding.

## What v0.1 delivers

- DSSE envelope (`secure-systems-lab/dsse`) wrapping an in-toto Statement v1 with `predicateType: https://corman.io/signrun/Provenance/v0.1`.
- Content-addressed SHA256 over declared inputs, declared outputs (subject), the entrypoint script, and project-local imported modules (paths relative to `cwd` for cross-machine portability).
- Ed25519 signature over the DSSE PAE (pre-authentication encoding); `keyid` is informational and never trusted.
- Three verification states: `signature invalid` (exit 3), `signature valid, signer untrusted` (exit 1), `trusted signer verified` (exit 0). Trusted failed-run records exit 7.
- TOCTOU defense: post-execution input stability re-hash detects changes that persist until the re-hash and refuses to sign by default. A mutate-read-restore attack (modify-during-run, restore-before-rehash) is an inherent wrapper limitation; see [`docs/threat-model.md`](docs/threat-model.md).
- Cross-machine reproducibility: `installed_packages_sha256` (resolved snapshot) distinguishes platform drift from artifact drift; `dependency_spec_sha256` and `lockfile` capture declared intent.

## What v0.1 does NOT deliver

- **Author identity binding.** The signature only proves possession of the embedded key. For trusted verification, the verifier must supply the signer's fingerprint out-of-band (via the signer's published GitHub README, tagged release commit, personal website). What this proves is *continuity with a published key*, not real-world identity. Channel compromise defeats attribution. v0.3 plans Sigstore-keyless attestation. See [`docs/trust-anchor.md`](docs/trust-anchor.md).
- **Subprocess / multiprocessing / C-extension / external-network capture.** Out of scope, surfaced explicitly in `capture_coverage`. See [`docs/coverage-limits.md`](docs/coverage-limits.md).
- **Symlinks / HPC shared-storage layouts.** v0.1 attests only regular files physically within the verification workspace; symlinked external data requires materializing the file into the workspace or waiting for v0.2.
- **Regulatory compliance.** NIH DMS, NSF Public Access, EU AI Act Article 10 are policy-level requirements; signrun is a useful primitive but neither sufficient nor mandated.

## Documentation

- [`docs/quickstart.md`](docs/quickstart.md) -- install → init → wrap → verify in 60 seconds.
- [`docs/threat-model.md`](docs/threat-model.md) -- what signrun proves, what it doesn't, and the exit-code precedence table.
- [`docs/trust-anchor.md`](docs/trust-anchor.md) -- how to publish your fingerprint and what each publication channel does and does not protect.
- [`docs/coverage-limits.md`](docs/coverage-limits.md) -- explicit list of what v0.1 captures and what it does NOT.
- [`docs/schema.md`](docs/schema.md) -- manifest schema reference for tools that consume signrun output.

## License

Apache-2.0. See [`LICENSE`](LICENSE).
