asf-tooling commented on issue #250:
URL: 
https://github.com/apache/tooling-trusted-releases/issues/250#issuecomment-4410407217

   <!-- gofannon-issue-triage-bot v2 -->
   
   **Automated triage** — analyzed at `main@2da7807a`
   
   **Type:** `discussion`  •  **Classification:** `no_action`  •  
**Confidence:** `medium`
   **Application domain(s):** `automated_checks`, `announcement_publishing`
   
   ### Summary
   Issue #250 requests implementing basic attestations (proof of concept) for 
ATR releases in a standardized format. The discussion converged on SLSA v1.2 as 
the target framework (@dave2wave noted SLSA v1.2 'has enough defined that we 
can design more than a proof'), with GitHub's attestation tooling as a 
practical reference. While ATR already has internal 'attestable' metadata 
tracking (file hashes, provenance, check results in atr/attestable.py and 
atr/models/attestable.py), it does NOT yet produce standardized SLSA/in-toto 
format attestations consumable by external tools. No concrete implementation 
spec has been agreed upon beyond the general direction.
   
   ### Where this lives in the code today
   
   #### `atr/models/attestable.py` — `AttestableV2` (lines 70-74)
   _extension point_
   Current internal attestable metadata model - tracks file hashes, paths with 
classifications, and provenance. This data would serve as input to produce 
SLSA-format attestations.
   
   ```python
   class AttestableV2(schema.Strict):
       version: Literal[2] = 2
       hashes: dict[str, HashEntryV2] = schema.factory(dict)
       paths: dict[str, PathEntryV2] = schema.factory(dict)
       policy: dict[str, Any] = schema.factory(dict)
   ```
   
   #### `atr/models/attestable.py` — `ProvenanceV2` (lines 59-61)
   _extension point_
   Internal provenance tracking with a generator enum. This would need to be 
mapped to SLSA provenance predicates in a standardized attestation format.
   
   ```python
   class ProvenanceV2(schema.Strict):
       generator: GeneratorV2
       metadata: dict[str, Any] = schema.factory(dict)
   ```
   
   #### `atr/attestable.py` — `github_tp_payload_read` (lines 206-227)
   _extension point_
   GitHub Trusted Publisher OIDC payload reading - this already captures 
provenance from GitHub Actions which would feed into SLSA provenance 
attestations.
   
   ```python
   async def github_tp_payload_read(
       project_key: safe.ProjectKey, version_key: safe.VersionKey, 
revision_number: safe.RevisionNumber
   ) -> github.TrustedPublisherPayload | None:
       payload_path = github_tp_payload_path(project_key, version_key, 
revision_number)
       if not await aiofiles.os.path.isfile(payload_path):
           return None
       try:
           async with aiofiles.open(payload_path, encoding="utf-8") as f:
               data = json.loads(await f.read())
           if not isinstance(data, dict):
               log.warning(f"TP payload was not a JSON object in 
{payload_path}")
               return None
           # Remove exp and nbf if they're stored - as of 2026-03-18 they're 
validated and then removed before storage
           # but we might have older data
           if "exp" in data:
               del data["exp"]
           if "nbf" in data:
               del data["nbf"]
           return github.TrustedPublisherPayload.model_validate(data)
       except (OSError, json.JSONDecodeError) as e:
           log.warning(f"Failed to read TP payload from {payload_path}: {e}")
           return None
   ```
   
   #### `atr/models/attestable.py` — `AttestableChecksV2` (lines 94-96)
   _extension point_
   Records check results per file - these check outcomes would be attestable 
claims in a standardized format.
   
   ```python
   class AttestableChecksV2(schema.Strict):
       version: Literal[2] = 2
       checks: dict[str, dict[str, str]] = schema.factory(dict)
   ```
   
   #### `atr/storage/writers/announce.py` — `CommitteeMember.release` (lines 
103-115)
   _extension point_
   The release publication workflow - a natural point where finalized 
attestations could be generated and published alongside the release artifacts.
   
   ```python
       async def release(  # noqa: C901
           self,
           project_key: safe.ProjectKey,
           version_key: safe.VersionKey,
           preview_revision_number: safe.RevisionNumber,
           email_to: str,
           body: str,
           download_path_suffix: safe.RelPath | None,
           fullname: str,
           subject_template_hash: str | None = None,
           email_cc: list[str] | None = None,
           email_bcc: list[str] | None = None,
       ) -> None:
   ```
   
   #### `atr/tasks/checks/signature.py` — `check` (lines 38-50)
   _currently does this_
   Existing signature verification check - its results (valid signature, signer 
identity) would be claims in a SLSA attestation.
   
   ```python
   async def check(args: checks.FunctionArguments) -> results.Results | None:
       """Check a signature file."""
       recorder = await args.recorder(CHECK_VERSION)
       if not (primary_abs_path := await recorder.abs_path()):
           return None
   
       if not (primary_rel_path := args.primary_rel_path):
           await recorder.exception("Primary relative path is required", 
{"primary_rel_path": primary_rel_path})
           return None
   
       artifact_rel_path = str(primary_rel_path).removesuffix(".asc")
       if not (artifact_abs_path := await recorder.abs_path(artifact_rel_path)):
           return None
   ```
   
   ### Where new code would go
   - `atr/slsa.py` — new file
     New module to generate SLSA v1.2 attestations (in-toto format statements) 
from ATR's internal attestable data, check results, and provenance information.
   - `atr/models/slsa.py` — new file
     Pydantic models for SLSA v1.2 attestation predicates (provenance, 
verification summary) following the in-toto statement specification.
   - `atr/tasks/attestation.py` — new file
     Task to generate attestations at appropriate lifecycle points (post-vote, 
pre-release) using the internal metadata and check results.
   
   ### Proposed approach
   The implementation would involve: (1) Creating Pydantic models for SLSA v1.2 
in-toto attestation statements (subjects with digests, predicates for 
provenance), following the spec at slsa.dev/spec/v1.2/attestation-model. (2) 
Building a module that transforms ATR's internal attestable data (AttestableV2 
paths/hashes, check results, GitHub TP payloads) into SLSA-format attestations. 
(3) Integrating attestation generation into the release lifecycle — likely at 
the point where a release transitions to preview or is published. (4) Exposing 
generated attestations in the UI so users can review them, and making them 
downloadable alongside release artifacts.
   
   However, since the discussion is still collecting references and no concrete 
implementation decisions have been documented (e.g., which specific SLSA 
predicate types to emit first, whether to use Sigstore bundles or standalone 
statements, how to sign the attestations), this issue remains in the design 
phase. The team should decide: what predicates to emit (provenance? 
verification summary?), what signing mechanism (ASF project keys? Sigstore?), 
and what the minimal viable attestation looks like before coding begins.
   
   ### Open questions
   - Which SLSA predicate types should be implemented first - provenance (build 
origin), verification summary (checks passed), or both?
   - Should attestations be signed with ASF project OpenPGP keys, 
Sigstore/Fulcio certificates, or both?
   - Should attestations follow the in-toto bundle format (as used by 
GitHub/PyPI) or be standalone JSON statements?
   - At what lifecycle point should attestations be generated - at each 
revision commit, at vote start, at release publication, or all of the above?
   - How should the OIDC issuer policy enforcement (Piotr's request documented 
by @sbp) interact with the basic attestation PoC?
   - Is there an existing Python library for producing SLSA/in-toto 
attestations that should be used (e.g., in-toto-python, sigstore-python)?
   
   _The agent reviewed this issue and is not proposing patches in this run. 
Review the existing-code citations and open questions above before deciding 
next steps._
   
   ### Files examined
   - `atr/models/attestable.py`
   - `atr/attestable.py`
   - `atr/tasks/checks/__init__.py`
   - `atr/hashes.py`
   - `atr/tasks/checks/signature.py`
   - `atr/storage/writers/announce.py`
   - `atr/tasks/checks/hashing.py`
   - `atr/detection.py`
   
   ---
   *Draft from a triage agent. A human reviewer should validate before merging 
any change. The agent did not run tests or verify diffs apply.*


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to