Skip to content

Harden generated dependency-lock provenance before Dependabot merge #1229

Description

@seonghobae

Product and supply-chain gap

A dependency PR changed connector/requirements-hashes.txt from websockets==16.1 to websockets==17.0 while retaining the old artifact hash and a stale regeneration comment. Repository-local application checks initially passed, so the queue did not prove that the declared version, generation command, trusted registry artifacts, platform compatibility, and clean hash-locked installation were mutually consistent.

This is a fail-open supply-chain evidence gap: a syntactically green dependency update can be un-installable or can attest a different artifact than it declares.

Current implementation stack

The remediation is intentionally split into bounded evidence layers rather than one monolithic validator.

Layer 1 — repository-controlled declaration receipt: PR #1369

Canonical parent PR #1369 was observed as develop@bc98789521d21271e84789888413c182aa111b4d -> bb8e34988af133bf28b0c1b657be7f757b66b2c8. It validates offline declaration consistency before dependency installation, including exact pins and SHA-256 syntax, generator-command/source/version binding, requirements.in, manual extras syntax, recursive -r / --requirement includes, repository-root containment, cycles/depth/missing include failures, deterministic credential-free receipts, and CI publication of the receipt even when validation fails. It is not shipped until merged to protected develop; refetch its exact head/base, threads, reviews, required statuses, and workflows before acting.

Layer 2 — network-derived PyPI release digest evidence: PR #1370

PR #1370 was observed stacked directly on #1369 (bb8e34988af133bf28b0c1b657be7f757b66b2c8 -> 80454eecb04ae8455a52828f1e5efe6cd9577bcb). It adds a PyPI-specific check that an exact locked project/version has at least one eligible non-yanked release artifact whose published SHA-256 is present in the lock. It deliberately excludes artifact URLs/provider exception text from receipts and does not claim private-index support.

Because #1370 is stacked, it is dependency-blocked while its parent is not integrated. After the parent reaches protected develop, #1370 must be retargeted/revalidated against the then-live protected head and obtain fresh exact-head/base-sensitive evidence.

Live merge-contract correction — 2026-08-17

Repository ruleset 15586698 alone requires zero approving reviews, but the effective default-branch contract is the union of all active applicable rulesets. Repository ruleset 17214772 (Lock default branch) and inherited organization ruleset 18156473 (CWL Central required workflows) each require one approving review, dismiss stale reviews on push, require approval after the last push, and require review-thread resolution. No active ruleset currently requires CODEOWNER review. The effective live merge contract therefore still requires a qualifying independent post-last-push approval in addition to exact-head status checks and required workflows. Issue #1371 remains open because the current collaborator inventory exposes only seonghobae, so the independent human approval route is not presently verifiable from this repository writer's authority. Do not infer future mergeability from this snapshot; refetch every active ruleset and exact-head evidence at decision time.

Remaining required contract

The issue remains open until the full protected-branch evidence chain covers every generated Python requirements set used by backend, connector, CI, and security-review jobs:

  1. Parse each pinned requirement and every associated --hash value, recursively including valid requirements-file includes.
  2. Verify the regeneration declaration names the same direct requirement version/source boundary as the file.
  3. Resolve exact distribution metadata from the configured trusted index without dependency execution and bind eligible artifact SHA-256 digests to recorded lock hashes.
  4. Prove relevant Python/platform artifact compatibility rather than accepting any release artifact generically.
  5. Perform a clean pip install --require-hashes rehearsal for every changed requirements set on supported Python/runtime targets.
  6. Reject stale hashes/comments, missing platform artifacts, unpinned transitive dependencies, include/path escapes, and index/source mismatches with stable reason codes.
  7. Keep network-derived metadata out of committed fixtures unless source, retrieval date, and digest are recorded; keep receipts credential-free and privacy-safe.
  8. Maintain 100% owned production statement/branch coverage and complete public docstrings where repository gates support them.

Merge policy

Dependency-only PRs must not be considered merge-ready merely because application tests do not import the updated package. Offline declaration consistency, exact registry digest provenance, target compatibility, and clean --require-hashes installability are distinct mandatory evidence layers. No layer may substitute pending, skipped, neutral, absent, stale, predecessor-head, model-only, or author-only evidence for another.

Acceptance evidence

  • a fixture reproducing the 16.1-comment / 17.0-version / stale-hash mismatch fails at the appropriate layer;
  • a correctly regenerated 17.0 declaration passes offline validation;
  • current trusted-registry evidence proves an eligible exact 17.0 artifact digest matches a recorded lock hash;
  • supported Python/platform targets prove at least one compatible artifact or fail closed;
  • clean isolated pip install --require-hashes rehearsals pass for every applicable changed requirements set;
  • every active requirements file is covered by the repository contract, including recursively included files;
  • CI publishes concise machine-readable provenance receipts without exposing credentials, arbitrary runner files, artifact URLs, or provider exception strings;
  • the integrated exact protected head satisfies all live CI/security/coverage/container/package/provenance/review/thread/workflow gates together before this issue closes.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    area: authAuthentication, authorization, identity, or tenant isolationarea: ci-cdCI, GitHub Actions, checks, release, or supply chainarea: dependenciesDependency or lockfile maintenancearea: securitySecurity boundary, hardening, or vulnerability preventionmaintenancepriority: mediumNormal-priority or P2 workstatus: blockedBlocked by conflict, dependency, or required prerequisitetype: maintenanceMaintenance, build, dependency, or operational upkeep

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions