Skip to main content

ProvBind

PyPI Python CI CodeQL License: MIT

Bind AI and research artifacts to the exact source bytes that produced them.

ProvBind is a small, local-first provenance verifier for AI agents, research pipelines, coding agents, and automated reports. It creates a closed JSON manifest that binds an artifact to one or more source files using SHA-256 digests and an independently recomputable binding_id.

pip install provbind

Version 0.2.0 is prepared as the current source release for 2026-08-08. PyPI may briefly continue to show 0.1.0 until the tagged Trusted Publishing workflow completes.

If an agent says “this output was based on these sources,” ProvBind turns that claim into something another process can verify later.

ProvBind proves byte identity and binding. It does not prove that a source is true, that an agent reasoned correctly, that a person authored a file, or that a timestamp is externally trusted.

30-second demo

Create one source and one derived artifact:

printf 'source bytes\n' > source.txt
printf 'derived output\n' > report.md

Seal the exact bytes and verify them:

provbind seal report.md --source source.txt -o provbind.json
provbind verify provbind.json

Expected result:

PASS artifact:report.md — artifact bytes match
PASS local_file:source.txt — source bytes match
VERIFIED

Now change the artifact:

printf '\ntampered\n' >> report.md
provbind verify provbind.json

ProvBind fails closed with NOT VERIFIED and exit code 2.

Use it after Codex or another agent

The agent produces the artifact; ProvBind independently binds the result to the inputs that actually exist afterward:

Codex / another agent
        │
        │ produces artifact
        ▼
  exact artifact bytes ─────┐
                            │
  exact source bytes ───────┼──> ProvBind manifest
                            │
                            ▼
                      independent verify

A complete Codex example is in examples/codex, including:

  • a constrained prompt;
  • a credential-free checked-in provenance fixture;
  • a workflow using the official openai/codex-action@v1 interface;
  • a CI-enforced intentional tamper failure.

The core verifier has no model-vendor dependency. The same seal and verify flow works for outputs produced by people, scripts, Codex, or other agents.

Why

Agent workflows increasingly read files, Git repositories, documents, and research inputs before producing code or reports. A normal output file does not preserve enough evidence to answer basic questions later:

  • Was this the exact source file the agent used?
  • Did a GitHub source come from a fixed commit, or from a branch that later moved?
  • Did the source change after the output was produced?
  • Did someone edit the provenance record itself?
  • Can CI fail closed when the evidence shape is unknown?

ProvBind turns those questions into deterministic checks.

Exact GitHub sources

GitHub sources must use an exact 40-hex commit SHA. Branches, tags, and abbreviated SHAs are rejected.

provbind seal report.md \
  --github-source openai/openai-python@0123456789abcdef0123456789abcdef01234567:README.md \
  -o provbind.json

For private repositories, set GITHUB_TOKEN in the environment.

In v0.2, a v2 GitHub source records and verifies both portable byte identity and Git-native repository membership:

  • exact commit SHA;
  • root tree SHA;
  • path resolved through tree objects;
  • final Git blob SHA and regular-file mode;
  • Git blob SHA-1 recomputed from the returned blob bytes;
  • SHA-256 and byte size over those same bytes.

The release-gate fixture in examples/github-v2 exercises this path against the real public GitHub API using the immutable v0.1.0 release commit, and CI requires the independently observed blob identity to match before verification succeeds.

This is intentional:

main              -> rejected
v1.2.3            -> rejected
abc1234           -> rejected
40-hex commit SHA -> accepted

A provenance record should bind immutable source identity, not a mutable name.

Commands

provbind seal

Create a new manifest. In v0.2, v2 is the default; use --schema v1 only when you explicitly need the frozen legacy output shape.

provbind seal ARTIFACT \
  --source LOCAL_SOURCE \
  --github-source OWNER/REPO@COMMIT:PATH \
  --root . \
  -o provbind.json

provbind seal ARTIFACT --source LOCAL_SOURCE --schema v1 -o provbind-v1.json

Both --source and --github-source are repeatable. At least one source is required.

provbind verify

Recompute artifact and source evidence and compare it with the sealed claims. Verification is schema-driven, so existing v1 manifests remain supported while v2 GitHub sources use the stronger Git object chain.

provbind verify provbind.json --root .
provbind verify provbind.json --root . --json

Exit codes:

  • 0: verified
  • 2: invalid manifest, unavailable evidence, repository-membership mismatch, or byte mismatch

provbind inspect

Inspect a manifest without fetching or re-reading its sources.

provbind inspect provbind.json

For v2 GitHub sources, inspection includes the sealed tree SHA, blob SHA, and Git file mode.

provbind diff

Compare two valid manifests.

provbind diff old.json new.json

The diff reports artifact changes and source additions, removals, or changes.

Manifest model

ProvBind supports two closed schema versions:

  • provbind-manifest-v1 — frozen v0.1 byte-binding contract;
  • provbind-manifest-v2 — v0.2 contract with Git-native identity for GitHub sources.

A v1 manifest looks like this:

{
  "schema_version": "provbind-manifest-v1",
  "binding_id": "...",
  "created_at": "2026-08-08T01:00:00Z",
  "artifact": {
    "path": "report.md",
    "sha256": "...",
    "size": 15
  },
  "sources": [
    {
      "kind": "local_file",
      "path": "source.txt",
      "sha256": "...",
      "size": 13
    }
  ],
  "producer": "provbind/0.1.0"
}

A v2 github_file source additionally seals git_tree_sha, git_blob_sha, and git_mode alongside the exact commit/path and SHA-256/size.

binding_id is the SHA-256 of ProvBind's canonical JSON encoding of:

schema_version + artifact claim + ordered source claims

created_at is intentionally excluded from binding_id, so the same artifact/source claim has the same binding identity even if the manifest is regenerated at a different time.

The schemas are published at schemas/provbind-manifest-v1.schema.json and schemas/provbind-manifest-v2.schema.json. Runtime validation is implemented without third-party dependencies and is stricter than simply parsing JSON.

Fail-closed design

ProvBind intentionally accepts a small closed evidence model:

  • local_file
  • github_file

Unknown top-level fields are rejected. Unknown fields inside artifact/source objects are rejected. Unknown source kinds are rejected. Duplicate source identities are rejected. Parent-directory traversal in local paths is rejected. GitHub mutable refs are rejected. In v2, symlink/submodule/tree final objects are also rejected until they have an explicit reviewed contract.

New source types should be introduced through a new reviewed schema/version rather than silently accepted by old verifiers.

GitHub Actions

The v0.2.0 composite Action is addressed by its release tag:

- uses: yunying24/provbind@v0.2.0
  with:
    manifest: provbind.json
    root: .

The existing v0.1.0 tag remains available for workflows intentionally pinned to the v0.1 implementation.

The action installs ProvBind from the checked-out action source and runs verification. A failing binding fails the workflow.

You can also install the CLI directly in any CI system:

- run: pip install provbind
- run: provbind verify provbind.json --root .

Threat model

ProvBind is designed to detect:

  • source bytes changing after a manifest was created;
  • artifact bytes changing after a manifest was created;
  • provenance claim edits that are not accompanied by a recomputed binding;
  • use of mutable GitHub refs in a byte-binding claim;
  • malformed or unexpectedly widened manifest shapes;
  • in v2, mismatch between exact commit/tree/path/blob membership and the sealed GitHub claim.

ProvBind does not currently defend against an attacker who can replace the artifact, every source, and the manifest together. That requires an external trust anchor such as a signed release, transparency log, trusted CI attestation, or another independent publication channel. Those are roadmap items, not current claims.

Design principles

  1. Exact bytes over labels. A source name is not evidence of source identity.
  2. Immutable refs over mutable refs. GitHub bindings use exact commit SHAs.
  3. Closed schemas over permissive parsing. Unknown evidence shapes fail closed.
  4. Separate verification from correctness. Matching bytes do not make content true.
  5. Local-first verification. Local-file verification requires no service or account.
  6. Small trusted core. ProvBind has zero runtime Python dependencies.

Use cases

  • bind an AI-generated research memo to its input corpus;
  • bind a coding-agent patch/report to exact repository files;
  • preserve source identity for automated market or technical reports;
  • fail CI when evidence or generated outputs drift;
  • attach a portable provenance manifest to releases or audit artifacts.

Examples

provbind verify examples/basic/provbind.json --root examples/basic
provbind verify examples/codex/provbind.json --root examples/codex

Project status

ProvBind is alpha. Version 0.2.0 is prepared as the current source release after completing the v2 Git identity gate: 72 compatibility/adversarial tests, package smoke testing, the Codex positive/tamper contract, a real public exact-commit GitHub v2 fixture, and CodeQL. PyPI may briefly lag at 0.1.0 until release publication completes.

See ROADMAP.md for planned work, including signed attestations, HTTP content-addressed sources, reusable policy profiles, and integrations for coding/research agents.

Contributing

Issues, test cases, source adapters, security review, and integration examples are welcome. See CONTRIBUTING.md.

Security

Please report security-sensitive findings privately as described in SECURITY.md.

License

MIT. See LICENSE.

Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

provbind-0.2.0.tar.gz (27.5 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

provbind-0.2.0-py3-none-any.whl (19.2 kB view details)

Uploaded Python 3

File details

Details for the file provbind-0.2.0.tar.gz.

File metadata

  • Download URL: provbind-0.2.0.tar.gz
  • Upload date:
  • Size: 27.5 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/7.0.0 CPython/3.13.14

File hashes

Hashes for provbind-0.2.0.tar.gz
Algorithm Hash digest
SHA256 d8162f44412ccbf188ee48ca4a78f4f64d408a5e8cbb08eb2d6548d28dab06e1
MD5 f3269a343f81f5e7128973591606db82
BLAKE2b-256 40616f2e4662f89197a2a7e3f3c1926c163ff25c497141fa4dc2fc73932a8975

See more details on using hashes here.

Provenance

The following attestation bundles were made for provbind-0.2.0.tar.gz:

Publisher: publish.yml on yunying24/provbind

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file provbind-0.2.0-py3-none-any.whl.

File metadata

  • Download URL: provbind-0.2.0-py3-none-any.whl
  • Upload date:
  • Size: 19.2 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/7.0.0 CPython/3.13.14

File hashes

Hashes for provbind-0.2.0-py3-none-any.whl
Algorithm Hash digest
SHA256 261c4af62dfaa84fb81896bd890504e83141c5966d753c1ab4105de5bb1e2901
MD5 dc95914fd7a6be79a34b10993b315707
BLAKE2b-256 d3318a9176fd467569d01f972f0a094dac525b40f4e2fd6d51d1f20fbd70f269

See more details on using hashes here.

Provenance

The following attestation bundles were made for provbind-0.2.0-py3-none-any.whl:

Publisher: publish.yml on yunying24/provbind

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page